Skip to content

Commit 559329b

Browse files
committed
big rag frontend update to v3
1 parent 0b1ec8e commit 559329b

File tree

13 files changed

+176
-163
lines changed

13 files changed

+176
-163
lines changed

src/client/components/ChatV2/ChatV2.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { useEffect, useRef, useState } from 'react'
55
import { useTranslation } from 'react-i18next'
66
import { useParams, useSearchParams } from 'react-router-dom'
77
import { DEFAULT_ASSISTANT_INSTRUCTIONS, DEFAULT_MODEL, DEFAULT_MODEL_TEMPERATURE, FREE_MODEL, inProduction, validModels } from '../../../config'
8-
import type { FileSearchCompletedData } from '../../../shared/types'
98
import { getLanguageValue } from '../../../shared/utils'
109
import useCourse from '../../hooks/useCourse'
1110
import useInfoTexts from '../../hooks/useInfoTexts'
@@ -34,6 +33,7 @@ import { ArrowDownward, MenuBookTwoTone, Tune } from '@mui/icons-material'
3433
import { useChatScroll } from '../../hooks/useChatScroll'
3534
import { TestUseInfoV2 } from './TestUseInfo'
3635
import Footer from '../Footer'
36+
import { ToolCallResultEvent } from '../../../shared/chat'
3737

3838
function useLocalStorageStateWithURLDefault(key: string, defaultValue: string, urlKey: string) {
3939
const [value, setValue] = useLocalStorageState(key, defaultValue)
@@ -91,11 +91,11 @@ export const ChatV2 = () => {
9191
const [tokenUsageWarning, setTokenUsageWarning] = useState<string>('')
9292
const [tokenUsageAlertOpen, setTokenUsageAlertOpen] = useState<boolean>(false)
9393
const [allowedModels, setAllowedModels] = useState<string[]>([])
94-
const [showFileSearchResults, setShowFileSearchResults] = useState<boolean>(false)
94+
const [showToolResults, setShowToolResults] = useState<boolean>(false)
9595
const [chatLeftSidePanelOpen, setChatLeftSidePanelOpen] = useState<boolean>(false)
9696
// RAG states
9797
const [ragIndexId, setRagIndexId] = useState<number | undefined>()
98-
const [activeFileSearchResult, setActiveFileSearchResult] = useState<FileSearchCompletedData | undefined>()
98+
const [activeToolResult, setActiveToolResult] = useState<ToolCallResultEvent | undefined>()
9999
const ragIndex = ragIndices?.find((index) => index.id === ragIndexId)
100100

101101
// Analytics
@@ -137,6 +137,7 @@ export const ChatV2 = () => {
137137
refetchStatus()
138138
}
139139
chatScroll.autoScroll()
140+
console.log(message)
140141
},
141142
onText: () => {
142143
chatScroll.autoScroll()
@@ -145,14 +146,14 @@ export const ChatV2 = () => {
145146
handleCompletionStreamError(error, fileName)
146147
enqueueSnackbar(t('chat:errorInstructions'), { variant: 'error' })
147148
},
148-
onFileSearchComplete: (fileSearch) => {
149-
setActiveFileSearchResult(fileSearch)
149+
/* @todo fix this: onFileSearchComplete: (fileSearch) => {
150+
setActiveToolResult(fileSearch)
150151
// Only auto-open FileSearchResults on desktop, not on mobile
151152
if (!isMobile) {
152-
setShowFileSearchResults(true)
153+
setShowToolResults(true)
153154
}
154155
dispatchAnalytics({ type: 'INCREMENT_FILE_SEARCHES' })
155-
},
156+
}, */
156157
})
157158

158159
const handleSubmit = async (message: string, ignoreTokenUsageWarning: boolean) => {
@@ -237,8 +238,8 @@ export const ChatV2 = () => {
237238
const handleReset = () => {
238239
if (window.confirm(t('chat:emptyConfirm'))) {
239240
setMessages([])
240-
setShowFileSearchResults(false)
241-
setActiveFileSearchResult(undefined)
241+
setShowToolResults(false)
242+
setActiveToolResult(undefined)
242243
setPrevResponse('')
243244
if (fileInputRef.current) {
244245
fileInputRef.current.value = ''
@@ -461,8 +462,8 @@ export const ChatV2 = () => {
461462
completion={completion}
462463
isStreaming={isStreaming}
463464
toolCalls={toolCalls}
464-
setActiveFileSearchResult={setActiveFileSearchResult}
465-
setShowFileSearchResults={setShowFileSearchResults}
465+
setActiveToolResult={setActiveToolResult}
466+
setShowToolResults={setShowToolResults}
466467
/>
467468
</Box>
468469

@@ -528,8 +529,8 @@ export const ChatV2 = () => {
528529
{isMobile && (
529530
<Drawer
530531
anchor="right"
531-
open={showFileSearchResults}
532-
onClose={() => setShowFileSearchResults(false)}
532+
open={showToolResults}
533+
onClose={() => setShowToolResults(false)}
533534
sx={{
534535
'& .MuiDrawer-paper': {
535536
width: '100%',
@@ -549,12 +550,12 @@ export const ChatV2 = () => {
549550
overflow: 'auto',
550551
}}
551552
>
552-
{activeFileSearchResult && <FileSearchResults fileSearchResult={activeFileSearchResult} setShowFileSearchResults={setShowFileSearchResults} />}
553+
{activeToolResult && <FileSearchResults fileSearchResult={activeToolResult} setShowFileSearchResults={setShowToolResults} />}
553554
</Box>
554555
</Drawer>
555556
)}
556557

557-
{!isMobile && showFileSearchResults && activeFileSearchResult && (
558+
{!isMobile && showToolResults && activeToolResult && (
558559
<Box
559560
sx={{
560561
width: { md: 300, lg: 400 },
@@ -568,7 +569,7 @@ export const ChatV2 = () => {
568569
paddingTop: !isEmbeddedMode ? '4rem' : 0,
569570
}}
570571
>
571-
<FileSearchResults fileSearchResult={activeFileSearchResult} setShowFileSearchResults={setShowFileSearchResults} />
572+
<FileSearchResults fileSearchResult={activeToolResult} setShowFileSearchResults={setShowToolResults} />
572573
</Box>
573574
)}
574575

src/client/components/ChatV2/Conversation.tsx

Lines changed: 81 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
66
import rehypeKatex from 'rehype-katex'
77
import remarkGfm from 'remark-gfm'
88
import remarkMath from 'remark-math'
9-
import type { FileSearchCompletedData } from '../../../shared/types'
109
import type { ActivityPeriod, Message } from '../../types'
1110
import { ConversationSplash } from './general/ConversationSplash'
1211
import { LoadingMessage } from './general/LoadingMessage'
@@ -18,7 +17,9 @@ import { t } from 'i18next'
1817
import FormatQuoteIcon from '@mui/icons-material/FormatQuote'
1918
import useLocalStorageState from '../../hooks/useLocalStorageState'
2019
import { BlueButton } from './general/Buttons'
21-
import { ToolCallStatusEvent } from '../../../shared/chat'
20+
import type { ToolCallResultEvent, ToolCallStatusEvent } from '../../../shared/chat'
21+
import { ChatToolResult } from '../../../shared/tools'
22+
import { useMemo } from 'react'
2223

2324
const UserMessage = ({ content, attachements }: { content: string; attachements?: string }) => (
2425
<Box
@@ -55,18 +56,67 @@ const UserMessage = ({ content, attachements }: { content: string; attachements?
5556
</Box>
5657
)
5758

59+
const ToolResult = ({ toolResult, handleToolResult }: { toolResult: ToolCallResultEvent; handleToolResult: (toolResult: ToolCallResultEvent) => void }) => {
60+
const sources = useMemo(() => Array.from(new Set<string>(toolResult.result.files.map((file) => file.fileName)).values()).join(', '), [])
61+
return (
62+
<Box
63+
data-testId="file-search-sources"
64+
sx={{
65+
display: 'flex',
66+
alignItems: { xs: 'flex-start', sm: 'center' },
67+
gap: 2,
68+
fontStyle: 'italic',
69+
maxWidth: 'fit-content',
70+
opacity: '0.85',
71+
mt: 3,
72+
cursor: 'pointer',
73+
padding: '0.6rem',
74+
borderRadius: '0.6rem',
75+
}}
76+
onClick={() => {
77+
handleToolResult(toolResult)
78+
}}
79+
>
80+
<FormatQuoteIcon sx={{ fontSize: '2rem' }} />
81+
<Box sx={{ minWidth: 0, mt: { xs: 0.5, md: 0 } }}>
82+
<Box
83+
sx={{
84+
display: 'flex',
85+
flexDirection: 'column',
86+
}}
87+
>
88+
<Typography
89+
variant="body2"
90+
sx={{
91+
mr: 2,
92+
wordBreak: 'break-all',
93+
textOverflow: 'ellipsis',
94+
overflow: 'hidden',
95+
whiteSpace: 'nowrap',
96+
}}
97+
>
98+
{`${t('chat:displaySources')}: `}
99+
100+
<em>{sources}</em>
101+
</Typography>
102+
</Box>
103+
</Box>
104+
</Box>
105+
)
106+
}
107+
58108
const AssistantMessage = ({
59109
content,
60110
error,
61-
fileSearchResult,
62-
setActiveFileSearchResult,
63-
setShowFileSearchResults,
111+
toolResults,
112+
setActiveToolResult,
113+
setShowToolResults,
64114
}: {
65115
content: string
66116
error?: string
67-
fileSearchResult?: FileSearchCompletedData
68-
setActiveFileSearchResult: (data: FileSearchCompletedData) => void
69-
setShowFileSearchResults: (show: boolean) => void
117+
toolResults?: Record<string, ToolCallResultEvent>
118+
setActiveToolResult: (data: ToolCallResultEvent) => void
119+
setShowToolResults: (show: boolean) => void
70120
}) => {
71121
const processedContent = preprocessMath(content)
72122
const katexOptions = {
@@ -109,9 +159,10 @@ const AssistantMessage = ({
109159
}
110160
let codeCount = 0
111161

112-
const handleFileSearchResult = (fileSearchResult: FileSearchCompletedData) => {
113-
setActiveFileSearchResult(fileSearchResult)
114-
setShowFileSearchResults(true)
162+
const handleToolResult = (toolResult: ToolCallResultEvent) => {
163+
console.log(toolResult)
164+
setActiveToolResult(toolResult)
165+
setShowToolResults(true)
115166
}
116167

117168
return (
@@ -215,53 +266,9 @@ const AssistantMessage = ({
215266
<Typography variant="body1" fontStyle="italic" color="#cc0000">{`\n\n ${error}`}</Typography>
216267
</Box>
217268
)}
218-
{fileSearchResult?.status === 'completed' && (
219-
<>
220-
<Box
221-
data-testId="file-search-sources"
222-
sx={{
223-
display: 'flex',
224-
alignItems: { xs: 'flex-start', sm: 'center' },
225-
gap: 2,
226-
fontStyle: 'italic',
227-
maxWidth: 'fit-content',
228-
opacity: '0.85',
229-
mt: 3,
230-
cursor: 'pointer',
231-
padding: '0.6rem',
232-
borderRadius: '0.6rem',
233-
}}
234-
onClick={() => {
235-
handleFileSearchResult(fileSearchResult)
236-
}}
237-
>
238-
<FormatQuoteIcon sx={{ fontSize: '2rem' }} />
239-
<Box sx={{ minWidth: 0, mt: { xs: 0.5, md: 0 } }}>
240-
<Box
241-
sx={{
242-
display: 'flex',
243-
flexDirection: 'column',
244-
}}
245-
>
246-
<Typography
247-
variant="body2"
248-
sx={{
249-
mr: 2,
250-
wordBreak: 'break-all',
251-
textOverflow: 'ellipsis',
252-
overflow: 'hidden',
253-
whiteSpace: 'nowrap',
254-
}}
255-
>
256-
{`${t('chat:displaySources')}: `}
257-
258-
<em>{fileSearchResult?.searchedFileNames.join('\r\n')}</em>
259-
</Typography>
260-
</Box>
261-
</Box>
262-
</Box>
263-
</>
264-
)}
269+
{Object.values(toolResults ?? {}).map((toolResult) => (
270+
<ToolResult key={toolResult.callId} toolResult={toolResult} handleToolResult={handleToolResult} />
271+
))}
265272
</Box>
266273
)
267274
}
@@ -270,14 +277,14 @@ const MessageItem = ({
270277
message,
271278
isLastAssistantNode,
272279
expandedNodeHeight,
273-
setActiveFileSearchResult,
274-
setShowFileSearchResults,
280+
setActiveToolResult,
281+
setShowToolResults,
275282
}: {
276283
message: Message
277284
isLastAssistantNode: boolean
278285
expandedNodeHeight: number
279-
setActiveFileSearchResult: (data: FileSearchCompletedData) => void
280-
setShowFileSearchResults: (show: boolean) => void
286+
setActiveToolResult: (data: ToolCallResultEvent) => void
287+
setShowToolResults: (show: boolean) => void
281288
}) => {
282289
if (message.role === 'assistant') {
283290
return (
@@ -292,9 +299,9 @@ const MessageItem = ({
292299
<AssistantMessage
293300
content={message.content}
294301
error={message.error}
295-
fileSearchResult={message.fileSearchResult}
296-
setActiveFileSearchResult={setActiveFileSearchResult}
297-
setShowFileSearchResults={setShowFileSearchResults}
302+
toolResults={message.toolCalls}
303+
setActiveToolResult={setActiveToolResult}
304+
setShowToolResults={setShowToolResults}
298305
/>
299306
</Box>
300307
)
@@ -316,8 +323,8 @@ export const Conversation = ({
316323
completion,
317324
toolCalls,
318325
isStreaming,
319-
setActiveFileSearchResult,
320-
setShowFileSearchResults,
326+
setActiveToolResult,
327+
setShowToolResults,
321328
}: {
322329
courseName?: string
323330
courseDate?: ActivityPeriod
@@ -327,8 +334,8 @@ export const Conversation = ({
327334
completion: string
328335
toolCalls: { [callId: string]: ToolCallStatusEvent }
329336
isStreaming: boolean
330-
setActiveFileSearchResult: (data: FileSearchCompletedData) => void
331-
setShowFileSearchResults: (show: boolean) => void
337+
setActiveToolResult: (data: ToolCallResultEvent) => void
338+
setShowToolResults: (show: boolean) => void
332339
}) => {
333340
const [reminderSeen, setReminderSeen] = useLocalStorageState<boolean>('reminderSeen', false)
334341

@@ -355,8 +362,8 @@ export const Conversation = ({
355362
message={message}
356363
isLastAssistantNode={isLastAssistantNode}
357364
expandedNodeHeight={expandedNodeHeight}
358-
setActiveFileSearchResult={setActiveFileSearchResult}
359-
setShowFileSearchResults={setShowFileSearchResults}
365+
setActiveToolResult={setActiveToolResult}
366+
setShowToolResults={setShowToolResults}
360367
/>
361368
)
362369
})}
@@ -368,11 +375,11 @@ export const Conversation = ({
368375
message={{ role: 'assistant', content: completion }}
369376
isLastAssistantNode={true}
370377
expandedNodeHeight={expandedNodeHeight}
371-
setActiveFileSearchResult={setActiveFileSearchResult}
372-
setShowFileSearchResults={setShowFileSearchResults}
378+
setActiveToolResult={setActiveToolResult}
379+
setShowToolResults={setShowToolResults}
373380
/>
374381
) : (
375-
<LoadingMessage expandedNodeHeight={expandedNodeHeight} isFileSearching={Object.values(toolCalls).some((call) => !!call.result)} />
382+
<LoadingMessage expandedNodeHeight={expandedNodeHeight} toolCalls={toolCalls} />
376383
))}
377384
</Box>
378385
{!reminderSeen && !isStreaming && messages.length > 15 && (

0 commit comments

Comments
 (0)