Skip to content

Commit 39fd1d7

Browse files
committed
feat: add searching state management to chat process
Signed-off-by: Bob Du <[email protected]>
1 parent a3dd6fb commit 39fd1d7

File tree

8 files changed

+72
-4
lines changed

8 files changed

+72
-4
lines changed

service/src/chatgpt/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ async function chatReplyProcess(options: RequestOptions) {
119119
let hasSearchResult = false
120120
const searchConfig = globalConfig.searchConfig
121121
if (searchConfig.enabled && searchConfig?.options?.apiKey && searchEnabled) {
122+
// Send searching status before starting to fetch search query
123+
process?.({
124+
searching: true,
125+
})
122126
try {
123127
const systemMessageGetSearchQuery = renderSystemMessage(searchConfig.systemMessageGetSearchQuery, dayjs().format('YYYY-MM-DD HH:mm:ss'))
124128

@@ -214,9 +218,19 @@ search result: <search_result>${searchResultContent}</search_result>`,
214218
}
215219
hasSearchResult = true
216220
}
221+
else {
222+
// Search query is empty, indicating this question doesn't need search, close search box
223+
process?.({
224+
searching: false,
225+
})
226+
}
217227
}
218228
catch (e) {
219229
globalThis.console.error('search error from tavily, ', e)
230+
// Close search box when search error occurs
231+
process?.({
232+
searching: false,
233+
})
220234
}
221235
}
222236

service/src/chatgpt/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface ChatMessage {
1313

1414
export interface ResponseChunk {
1515
id?: string
16+
searching?: boolean
1617
searchQuery?: string
1718
searchResults?: SearchResult[]
1819
searchUsageTime?: number

service/src/routes/chat.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
299299
lastResponse = chunk
300300

301301
// set sse event by different data type
302+
if (chunk.searching !== undefined) {
303+
sendSSEData('searching', { searching: chunk.searching })
304+
}
302305
if (chunk.searchQuery) {
303306
sendSSEData('search_query', { searchQuery: chunk.searchQuery })
304307
}

src/api/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export function fetchChatConfig<T = any>() {
2020
interface SSEEventHandlers {
2121
onMessage?: (data: any) => void
2222
onDelta?: (delta: { reasoning?: string, text?: string }) => void
23+
onSearching?: (data: { searching: boolean }) => void
2324
onSearchQuery?: (data: { searchQuery: string }) => void
2425
onSearchResults?: (data: { searchResults: any[], searchUsageTime: number }) => void
2526
onComplete?: (data: any) => void
@@ -87,6 +88,9 @@ export function fetchChatAPIProcessSSE(
8788
if (jsonData.message) {
8889
handlers.onError?.(jsonData.message)
8990
}
91+
else if (jsonData.searching !== undefined) {
92+
handlers.onSearching?.(jsonData)
93+
}
9094
else if (jsonData.searchQuery) {
9195
handlers.onSearchQuery?.(jsonData)
9296
}

src/typings/chat.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ declare namespace Chat {
88
interface Chat {
99
uuid?: number
1010
dateTime: string
11+
searching?: boolean
1112
searchQuery?: string
1213
searchResults?: SearchResult[]
1314
searchUsageTime?: number

src/views/chat/components/Message/Search.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ const searchBtnTitle = computed(() => {
2424
return t('chat.expandCollapseSearchResults')
2525
})
2626
27+
const searchHeadingText = computed(() => {
28+
if (props.searchQuery)
29+
return `${t('chat.searchQuery')}: ${props.searchQuery}`
30+
return t('chat.searching')
31+
})
32+
2733
const shouldShowSearchingIndicator = computed(() => {
2834
return props.loading && !props.searchEnd
2935
})
@@ -96,7 +102,7 @@ function toggleCollapse() {
96102
<span class="text-blue-700 dark:text-blue-200 truncate">{{ t('chat.searching') }}</span>
97103
<span class="ml-1.5 mr-5 text-blue-400 dark:text-blue-500">|</span>
98104
</template>
99-
<span class="text-blue-800 dark:text-blue-100 truncate">{{ `${t('chat.searchQuery')}: ${searchQuery}` }}</span>
105+
<span class="text-blue-800 dark:text-blue-100 truncate">{{ searchHeadingText }}</span>
100106
<template v-if="searchUsageTime">
101107
<span class="mr-1.5 ml-5 text-blue-400 dark:text-blue-500">|</span>
102108
<span class="text-blue-600 dark:text-blue-300 truncate">{{ `${t('chat.searchUsageTime')}: ${searchUsageTime.toFixed(2)}s` }}</span>

src/views/chat/components/Message/index.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface Props {
2222
currentNavIndex: number
2323
dateTime?: string
2424
model?: string
25+
searching?: boolean
2526
searchQuery?: string
2627
searchResults?: Chat.SearchResult[]
2728
searchUsageTime?: number
@@ -230,7 +231,7 @@ function isEventTargetValid(event: any) {
230231
</NSpace>
231232
</p>
232233
<Search
233-
v-if="searchQuery"
234+
v-if="searching || searchQuery"
234235
:search-query="searchQuery"
235236
:search-results="searchResults"
236237
:search-usage-time="searchUsageTime"

src/views/chat/index.vue

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ async function onConversation() {
134134
let lastText = ''
135135
let accumulatedReasoning = ''
136136
const fetchChatAPIOnce = async () => {
137+
let searching: boolean | undefined
137138
let searchQuery: string
138139
let searchResults: Chat.SearchResult[]
139140
let searchUsageTime: number
@@ -146,8 +147,19 @@ async function onConversation() {
146147
options,
147148
signal: controller.signal,
148149
}, {
150+
onSearching: (data) => {
151+
searching = data.searching
152+
chatStore.updateChatMessage(
153+
currentChatRoom.value!.roomId,
154+
dataSources.value.length - 1,
155+
{
156+
searching: data.searching,
157+
},
158+
)
159+
},
149160
onSearchQuery: (data) => {
150161
searchQuery = data.searchQuery
162+
searching = false
151163
},
152164
onSearchResults: (data) => {
153165
searchResults = data.searchResults
@@ -166,6 +178,7 @@ async function onConversation() {
166178
dataSources.value.length - 1,
167179
{
168180
dateTime: new Date().toLocaleString(),
181+
searching,
169182
searchQuery,
170183
searchResults,
171184
searchUsageTime,
@@ -183,8 +196,10 @@ async function onConversation() {
183196
},
184197
onMessage: async (data) => {
185198
// Handle complete message data (compatibility mode)
186-
if (data.searchQuery)
199+
if (data.searchQuery) {
187200
searchQuery = data.searchQuery
201+
searching = false
202+
}
188203
if (data.searchResults)
189204
searchResults = data.searchResults
190205
if (data.searchUsageTime)
@@ -204,6 +219,7 @@ async function onConversation() {
204219
dataSources.value.length - 1,
205220
{
206221
dateTime: new Date().toLocaleString(),
222+
searching,
207223
searchQuery,
208224
searchResults,
209225
searchUsageTime,
@@ -243,6 +259,7 @@ async function onConversation() {
243259
dataSources.value.length - 1,
244260
{
245261
dateTime: new Date().toLocaleString(),
262+
searching: false,
246263
searchQuery,
247264
searchResults,
248265
searchUsageTime,
@@ -369,6 +386,7 @@ async function onRegenerate(index: number) {
369386
let lastText = ''
370387
let accumulatedReasoning = ''
371388
const fetchChatAPIOnce = async () => {
389+
let searching: boolean | undefined
372390
let searchQuery: string
373391
let searchResults: Chat.SearchResult[]
374392
let searchUsageTime: number
@@ -381,8 +399,19 @@ async function onRegenerate(index: number) {
381399
options,
382400
signal: controller.signal,
383401
}, {
402+
onSearching: (data) => {
403+
searching = data.searching
404+
updateChat(
405+
currentChatRoom.value!.roomId,
406+
index,
407+
{
408+
searching: data.searching,
409+
},
410+
)
411+
},
384412
onSearchQuery: (data) => {
385413
searchQuery = data.searchQuery
414+
searching = false
386415
},
387416
onSearchResults: (data) => {
388417
searchResults = data.searchResults
@@ -402,6 +431,7 @@ async function onRegenerate(index: number) {
402431
index,
403432
{
404433
dateTime: new Date().toLocaleString(),
434+
searching,
405435
searchQuery,
406436
searchResults,
407437
searchUsageTime,
@@ -420,8 +450,10 @@ async function onRegenerate(index: number) {
420450
},
421451
onMessage: async (data) => {
422452
// Handle complete message data (compatibility mode)
423-
if (data.searchQuery)
453+
if (data.searchQuery) {
424454
searchQuery = data.searchQuery
455+
searching = false
456+
}
425457
if (data.searchResults)
426458
searchResults = data.searchResults
427459
if (data.searchUsageTime)
@@ -440,6 +472,7 @@ async function onRegenerate(index: number) {
440472
index,
441473
{
442474
dateTime: new Date().toLocaleString(),
475+
searching,
443476
searchQuery,
444477
searchResults,
445478
searchUsageTime,
@@ -480,6 +513,10 @@ async function onRegenerate(index: number) {
480513
index,
481514
{
482515
dateTime: new Date().toLocaleString(),
516+
searching: false,
517+
searchQuery,
518+
searchResults,
519+
searchUsageTime,
483520
reasoning: data?.reasoning || accumulatedReasoning,
484521
finish_reason: data?.finish_reason,
485522
text: data?.text || lastText,
@@ -895,6 +932,7 @@ onUnmounted(() => {
895932
:index="index"
896933
:current-nav-index="currentNavIndexRef"
897934
:date-time="item.dateTime"
935+
:searching="item?.searching"
898936
:search-query="item?.searchQuery"
899937
:search-results="item?.searchResults"
900938
:search-usage-time="item?.searchUsageTime"

0 commit comments

Comments
 (0)