1
- import { getAllModelNicknames } from '../nickname' ;
2
1
import {
3
2
ChatHistory ,
4
3
HistoryInfo ,
@@ -13,7 +12,21 @@ import {
13
12
14
13
} from "./types"
15
14
import { db } from './schema' ;
16
- const PAGE_SIZE = 30 ;
15
+ import { getAllModelNicknames } from "./nickname" ;
16
+ const PAGE_SIZE = 30 ;
17
+
18
+ function searchQueryInContent ( content : string , query : string ) : boolean {
19
+ if ( ! content || ! query ) {
20
+ return false ;
21
+ }
22
+
23
+ const normalizedContent = content . toLowerCase ( ) ;
24
+ const normalizedQuery = query . toLowerCase ( ) . trim ( ) ;
25
+
26
+ const wordBoundaryPattern = new RegExp ( `\\b${ normalizedQuery . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } \\b` , 'i' ) ;
27
+
28
+ return wordBoundaryPattern . test ( normalizedContent ) ;
29
+ }
17
30
18
31
function fastForward ( lastRow : any , idProp : string , otherCriterion ?: ( item : any ) => boolean ) {
19
32
let fastForwardComplete = false ;
@@ -26,50 +39,6 @@ function fastForward(lastRow: any, idProp: string, otherCriterion?: (item: any)
26
39
} ;
27
40
}
28
41
29
- function simpleFuzzyMatch ( text : string , query : string ) : boolean {
30
- if ( ! text || ! query ) {
31
- return false ;
32
- }
33
-
34
- const lowerText = text . toLowerCase ( ) ;
35
- const lowerQuery = query . toLowerCase ( ) . trim ( ) ;
36
-
37
- if ( lowerQuery === '' ) {
38
- return true ;
39
- }
40
-
41
- if ( lowerText . includes ( lowerQuery ) ) {
42
- return true ;
43
- }
44
-
45
- const queryWords = lowerQuery . split ( / \s + / ) . filter ( ( word ) => word . length > 2 ) ;
46
-
47
- if ( queryWords . length > 1 ) {
48
- const matchedWords = queryWords . filter ( ( word ) => lowerText . includes ( word ) ) ;
49
- return matchedWords . length >= Math . ceil ( queryWords . length * 0.7 ) ;
50
- }
51
-
52
- if ( lowerQuery . length > 3 ) {
53
- const maxDistance = Math . floor ( lowerQuery . length * 0.3 ) ;
54
-
55
- const textWords = lowerText . split ( / \s + / ) ;
56
- return textWords . some ( ( word ) => {
57
- if ( Math . abs ( word . length - lowerQuery . length ) > maxDistance ) {
58
- return false ;
59
- }
60
- let matches = 0 ;
61
- for ( let i = 0 ; i < lowerQuery . length ; i ++ ) {
62
- if ( word . includes ( lowerQuery [ i ] ) ) {
63
- matches ++ ;
64
- }
65
- }
66
-
67
- return matches >= lowerQuery . length - maxDistance ;
68
- } ) ;
69
- }
70
-
71
- return false ;
72
- }
73
42
74
43
75
44
export class PageAssistDatabase {
@@ -154,6 +123,38 @@ export class PageAssistDatabase {
154
123
return await db . chatHistories . orderBy ( 'createdAt' ) . reverse ( ) . toArray ( ) ;
155
124
}
156
125
126
+ async fullTextSearchChatHistories ( query : string ) : Promise < ChatHistory > {
127
+ const normalizedQuery = query . toLowerCase ( ) . trim ( ) ;
128
+ if ( ! normalizedQuery ) {
129
+ return this . getChatHistories ( ) ;
130
+ }
131
+
132
+ const titleMatches = await db . chatHistories
133
+ . where ( 'title' )
134
+ . startsWithIgnoreCase ( normalizedQuery )
135
+ . or ( 'title' )
136
+ . anyOfIgnoreCase ( normalizedQuery . split ( ' ' ) )
137
+ . toArray ( ) ;
138
+
139
+ const messageMatches = await db . messages
140
+ . filter ( message => searchQueryInContent ( message . content , normalizedQuery ) )
141
+ . toArray ( ) ;
142
+
143
+ const historyIdsFromMessages = [ ...new Set ( messageMatches . map ( msg => msg . history_id ) ) ] ;
144
+
145
+ const historiesFromMessages = await db . chatHistories
146
+ . where ( 'id' )
147
+ . anyOf ( historyIdsFromMessages )
148
+ . toArray ( ) ;
149
+
150
+ const allMatches = [ ...titleMatches , ...historiesFromMessages ] ;
151
+ const uniqueHistories = allMatches . filter ( ( history , index , self ) =>
152
+ index === self . findIndex ( h => h . id === history . id )
153
+ ) ;
154
+
155
+ return uniqueHistories . sort ( ( a , b ) => b . createdAt - a . createdAt ) ;
156
+ }
157
+
157
158
async getChatHistoryTitleById ( id : string ) : Promise < string > {
158
159
const chatHistory = await db . chatHistories . get ( id ) ;
159
160
return chatHistory ?. title || '' ;
@@ -228,11 +229,12 @@ export class PageAssistDatabase {
228
229
totalCount : number ;
229
230
} > {
230
231
const offset = ( page - 1 ) * PAGE_SIZE ;
231
-
232
+
232
233
if ( searchQuery ) {
233
- const allResults = await this . searchChatHistories ( searchQuery ) ;
234
- const paginatedResults = allResults . slice ( offset , offset + PAGE_SIZE ) ;
235
-
234
+ console . log ( "Searching chat histories with query:" , searchQuery ) ;
235
+ const allResults = await this . fullTextSearchChatHistories ( searchQuery ) ;
236
+ const paginatedResults = allResults . slice ( offset , offset + PAGE_SIZE )
237
+ console . log ( "Paginated search results:" , paginatedResults ) ;
236
238
return {
237
239
histories : paginatedResults ,
238
240
hasMore : offset + PAGE_SIZE < allResults . length ,
@@ -246,9 +248,9 @@ export class PageAssistDatabase {
246
248
. reverse ( )
247
249
. limit ( PAGE_SIZE )
248
250
. toArray ( ) ;
249
-
251
+
250
252
const totalCount = await db . chatHistories . count ( ) ;
251
-
253
+
252
254
return {
253
255
histories,
254
256
hasMore : histories . length === PAGE_SIZE ,
@@ -262,9 +264,9 @@ export class PageAssistDatabase {
262
264
. offset ( skipCount )
263
265
. limit ( PAGE_SIZE )
264
266
. toArray ( ) ;
265
-
267
+
266
268
const totalCount = await db . chatHistories . count ( ) ;
267
-
269
+
268
270
return {
269
271
histories,
270
272
hasMore : offset + PAGE_SIZE < totalCount ,
@@ -277,7 +279,7 @@ export class PageAssistDatabase {
277
279
hasMore : boolean ;
278
280
} > {
279
281
if ( searchQuery ) {
280
- const allResults = await this . searchChatHistories ( searchQuery ) ;
282
+ const allResults = await this . fullTextSearchChatHistories ( searchQuery ) ;
281
283
return {
282
284
histories : allResults . slice ( 0 , PAGE_SIZE ) ,
283
285
hasMore : allResults . length > PAGE_SIZE
@@ -290,7 +292,7 @@ export class PageAssistDatabase {
290
292
. reverse ( )
291
293
. limit ( PAGE_SIZE )
292
294
. toArray ( ) ;
293
-
295
+
294
296
return {
295
297
histories,
296
298
hasMore : histories . length === PAGE_SIZE
@@ -303,7 +305,7 @@ export class PageAssistDatabase {
303
305
. limit ( PAGE_SIZE )
304
306
. reverse ( )
305
307
. toArray ( ) ;
306
-
308
+
307
309
return {
308
310
histories,
309
311
hasMore : histories . length === PAGE_SIZE
@@ -359,50 +361,7 @@ export class PageAssistDatabase {
359
361
await db . userSettings . put ( { id : 'main' , user_id : id } ) ;
360
362
}
361
363
362
- // Search Methods
363
- async searchChatHistories ( query : string ) : Promise < ChatHistory > {
364
- const normalizedQuery = query . toLowerCase ( ) . trim ( ) ;
365
- if ( ! normalizedQuery ) {
366
- return this . getChatHistories ( ) ;
367
- }
368
-
369
- const allHistories = await this . getChatHistories ( ) ;
370
- const matchedHistories : ChatHistory = [ ] ;
371
- const matchedHistoryIds = new Set < string > ( ) ;
372
-
373
- for ( const history of allHistories ) {
374
- if ( simpleFuzzyMatch ( history . title , normalizedQuery ) ) {
375
- if ( ! matchedHistoryIds . has ( history . id ) ) {
376
- matchedHistories . push ( history ) ;
377
- matchedHistoryIds . add ( history . id ) ;
378
- }
379
- continue ;
380
- }
381
364
382
- try {
383
- const messages = await this . getChatHistory ( history . id ) ;
384
- for ( const message of messages ) {
385
- if (
386
- message . content &&
387
- simpleFuzzyMatch ( message . content , normalizedQuery )
388
- ) {
389
- if ( ! matchedHistoryIds . has ( history . id ) ) {
390
- matchedHistories . push ( history ) ;
391
- matchedHistoryIds . add ( history . id ) ;
392
- }
393
- break ;
394
- }
395
- }
396
- } catch ( error ) {
397
- console . error (
398
- `Error fetching messages for history ${ history . id } :` ,
399
- error
400
- ) ;
401
- }
402
- }
403
-
404
- return matchedHistories ;
405
- }
406
365
async importChatHistoryV2 ( data : any [ ] , options : {
407
366
replaceExisting ?: boolean ;
408
367
mergeData ?: boolean ;
0 commit comments