diff --git a/application/api/answer/routes.py b/application/api/answer/routes.py index 62fb6b931..6f0315152 100644 --- a/application/api/answer/routes.py +++ b/application/api/answer/routes.py @@ -184,6 +184,13 @@ def complete_stream( response_full = "" source_log_docs = [] answer = retriever.gen() + sources = retriever.search() + for source in sources: + if("text" in source): + source["text"] = source["text"][:100].strip()+"..." + if(len(sources) > 0): + data = json.dumps({"type":"source","source":sources}) + yield f"data: {data}\n\n" for line in answer: if "answer" in line: response_full += str(line["answer"]) @@ -221,7 +228,6 @@ def complete_stream( "timestamp": datetime.datetime.now(datetime.timezone.utc), } ) - data = json.dumps({"type": "end"}) yield f"data: {data}\n\n" except Exception as e: diff --git a/frontend/src/conversation/SharedConversation.tsx b/frontend/src/conversation/SharedConversation.tsx index 139c82462..c4cb17fb6 100644 --- a/frontend/src/conversation/SharedConversation.tsx +++ b/frontend/src/conversation/SharedConversation.tsx @@ -26,7 +26,6 @@ import { selectQueries, } from './sharedConversationSlice'; import { useSelector } from 'react-redux'; -const apiHost = import.meta.env.VITE_API_HOST || 'https://docsapi.arc53.com'; export const SharedConversation = () => { const navigate = useNavigate(); @@ -39,6 +38,7 @@ export const SharedConversation = () => { const status = useSelector(selectStatus); const inputRef = useRef(null); + const sharedConversationRef = useRef(null); const { t } = useTranslation(); const dispatch = useDispatch(); @@ -60,38 +60,6 @@ export const SharedConversation = () => { } }, []); - function formatISODate(isoDateStr: string) { - const date = new Date(isoDateStr); - - const monthNames = [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'June', - 'July', - 'Aug', - 'Sept', - 'Oct', - 'Nov', - 'Dec', - ]; - - const month = monthNames[date.getMonth()]; - const day = date.getDate(); - const year = date.getFullYear(); - - let hours = date.getHours(); - const minutes = date.getMinutes(); - const ampm = hours >= 12 ? 'PM' : 'AM'; - - hours = hours % 12; - hours = hours ? hours : 12; - const minutesStr = minutes < 10 ? '0' + minutes : minutes; - const formattedDate = `Published ${month} ${day}, ${year} at ${hours}:${minutesStr} ${ampm}`; - return formattedDate; - } useEffect(() => { if (queries.length) { queries[queries.length - 1].error && setLastQueryReturnedErr(true); @@ -100,10 +68,17 @@ export const SharedConversation = () => { }, [queries[queries.length - 1]]); const scrollIntoView = () => { - endMessageRef?.current?.scrollIntoView({ - behavior: 'smooth', - block: 'start', - }); + if (!sharedConversationRef?.current || eventInterrupt) return; + + if (status === 'idle' || !queries[queries.length - 1].response) { + sharedConversationRef.current.scrollTo({ + behavior: 'smooth', + top: sharedConversationRef.current.scrollHeight, + }); + } else { + sharedConversationRef.current.scrollTop = + sharedConversationRef.current.scrollHeight; + } }; const fetchQueries = () => { @@ -202,7 +177,12 @@ export const SharedConversation = () => { return (
-
+

diff --git a/frontend/src/conversation/conversationSlice.ts b/frontend/src/conversation/conversationSlice.ts index 10070a97f..bf3753119 100644 --- a/frontend/src/conversation/conversationSlice.ts +++ b/frontend/src/conversation/conversationSlice.ts @@ -6,7 +6,6 @@ import store from '../store'; import { handleFetchAnswer, handleFetchAnswerSteaming, - handleSearch, } from './conversationHandlers'; import { Answer, ConversationState, Query, Status } from './conversationModels'; @@ -48,47 +47,19 @@ export const fetchAnswer = createAsyncThunk( .catch((error) => { console.error('Failed to fetch conversations: ', error); }); - - handleSearch( - //search for sources post streaming - question, - state.preference.selectedDocs!, - state.conversation.conversationId, - state.conversation.queries, - state.preference.chunks, - state.preference.token_limit, - ).then((sources) => { - //dispatch streaming sources - dispatch( - updateStreamingSource({ - index: state.conversation.queries.length - 1, - query: { sources: sources ?? [] }, - }), - ); - }); } else if (data.type === 'id') { dispatch( updateConversationId({ query: { conversationId: data.id }, }), ); - handleSearch( - //search for sources post streaming - question, - state.preference.selectedDocs!, - state.conversation.conversationId, - state.conversation.queries, - state.preference.chunks, - state.preference.token_limit, - ).then((sources) => { - //dispatch streaming sources - dispatch( - updateStreamingSource({ - index: state.conversation.queries.length - 1, - query: { sources: sources ?? [] }, - }), - ); - }); + } else if (data.type === 'source') { + dispatch( + updateStreamingSource({ + index: state.conversation.queries.length - 1, + query: { sources: data.source ?? [] }, + }), + ); } else if (data.type === 'error') { // set status to 'failed' dispatch(conversationSlice.actions.setStatus('failed')); diff --git a/frontend/src/conversation/sharedConversationSlice.ts b/frontend/src/conversation/sharedConversationSlice.ts index f605c6bf3..c95f44e8f 100644 --- a/frontend/src/conversation/sharedConversationSlice.ts +++ b/frontend/src/conversation/sharedConversationSlice.ts @@ -6,7 +6,6 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; import { handleFetchSharedAnswer, handleFetchSharedAnswerStreaming, - handleSearchViaApiKey, } from './conversationHandlers'; const API_STREAMING = import.meta.env.VITE_API_STREAMING === 'true'; @@ -45,22 +44,13 @@ export const fetchSharedAnswer = createAsyncThunk( // set status to 'idle' dispatch(sharedConversationSlice.actions.setStatus('idle')); dispatch(saveToLocalStorage()); - - state.sharedConversation.apiKey && - handleSearchViaApiKey( - question, - state.sharedConversation.apiKey, - state.sharedConversation.queries, - ).then((sources) => { - //dispatch streaming sources - sources && - dispatch( - updateStreamingSource({ - index: state.sharedConversation.queries.length - 1, - query: { sources: sources ?? [] }, - }), - ); - }); + } else if (data.type === 'source') { + dispatch( + updateStreamingSource({ + index: state.sharedConversation.queries.length - 1, + query: { sources: data.source ?? [] }, + }), + ); } else if (data.type === 'error') { // set status to 'failed' dispatch(sharedConversationSlice.actions.setStatus('failed')); @@ -247,7 +237,8 @@ export const { updateStreamingSource, } = sharedConversationSlice.actions; -export const selectStatus = (state: RootState) => state.conversation.status; +export const selectStatus = (state: RootState) => + state.sharedConversation.status; export const selectClientAPIKey = (state: RootState) => state.sharedConversation.apiKey; export const selectQueries = (state: RootState) =>