1
1
const { SystemSettings } = require ( "../../../../models/systemSettings" ) ;
2
+ const { TokenManager } = require ( "../../../helpers/tiktoken" ) ;
3
+ const tiktoken = new TokenManager ( ) ;
2
4
3
5
const webBrowsing = {
4
6
name : "web-browsing" ,
@@ -12,6 +14,11 @@ const webBrowsing = {
12
14
aibitat . function ( {
13
15
super : aibitat ,
14
16
name : this . name ,
17
+ countTokens : ( string ) =>
18
+ tiktoken
19
+ . countFromString ( string )
20
+ . toString ( )
21
+ . replace ( / \B (? = ( \d { 3 } ) + (? ! \d ) ) / g, "," ) ,
15
22
description :
16
23
"Searches for a given query using a search engine to get better results for the user query." ,
17
24
examples : [
@@ -89,6 +96,18 @@ const webBrowsing = {
89
96
return await this [ engine ] ( query ) ;
90
97
} ,
91
98
99
+ /**
100
+ * Utility function to truncate a string to a given length for debugging
101
+ * calls to the API while keeping the actual values mostly intact
102
+ * @param {string } str - The string to truncate
103
+ * @param {number } length - The length to truncate the string to
104
+ * @returns {string } The truncated string
105
+ */
106
+ middleTruncate ( str , length = 5 ) {
107
+ if ( str . length <= length ) return str ;
108
+ return `${ str . slice ( 0 , length ) } ...${ str . slice ( - length ) } ` ;
109
+ } ,
110
+
92
111
/**
93
112
* Use Google Custom Search Engines
94
113
* Free to set up, easy to use, 100 calls/day
@@ -115,7 +134,12 @@ const webBrowsing = {
115
134
} "`
116
135
) ;
117
136
const data = await fetch ( searchURL )
118
- . then ( ( res ) => res . json ( ) )
137
+ . then ( ( res ) => {
138
+ if ( res . ok ) return res . json ( ) ;
139
+ throw new Error (
140
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { key : this . middleTruncate ( process . env . AGENT_GSE_KEY , 5 ) , cx : this . middleTruncate ( process . env . AGENT_GSE_CTX , 5 ) , q : query } ) } `
141
+ ) ;
142
+ } )
119
143
. then ( ( searchResult ) => searchResult ?. items || [ ] )
120
144
. then ( ( items ) => {
121
145
return items . map ( ( item ) => {
@@ -127,16 +151,20 @@ const webBrowsing = {
127
151
} ) ;
128
152
} )
129
153
. catch ( ( e ) => {
130
- console . log ( e ) ;
154
+ this . super . handlerProps . log (
155
+ `${ this . name } : Google Search Error: ${ e . message } `
156
+ ) ;
131
157
return [ ] ;
132
158
} ) ;
133
159
134
160
if ( data . length === 0 )
135
161
return `No information was found online for the search query.` ;
162
+
163
+ const result = JSON . stringify ( data ) ;
136
164
this . super . introspect (
137
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
165
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
138
166
) ;
139
- return JSON . stringify ( data ) ;
167
+ return result ;
140
168
} ,
141
169
142
170
/**
@@ -173,11 +201,17 @@ const webBrowsing = {
173
201
"X-SearchApi-Source" : "AnythingLLM" ,
174
202
} ,
175
203
} )
176
- . then ( ( res ) => res . json ( ) )
204
+ . then ( ( res ) => {
205
+ if ( res . ok ) return res . json ( ) ;
206
+ throw new Error (
207
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { auth : this . middleTruncate ( process . env . AGENT_SEARCHAPI_API_KEY , 5 ) , q : query } ) } `
208
+ ) ;
209
+ } )
177
210
. then ( ( data ) => {
178
211
return { response : data , error : null } ;
179
212
} )
180
213
. catch ( ( e ) => {
214
+ this . super . handlerProps . log ( `SearchApi Error: ${ e . message } ` ) ;
181
215
return { response : null , error : e . message } ;
182
216
} ) ;
183
217
if ( error )
@@ -199,10 +233,12 @@ const webBrowsing = {
199
233
200
234
if ( data . length === 0 )
201
235
return `No information was found online for the search query.` ;
236
+
237
+ const result = JSON . stringify ( data ) ;
202
238
this . super . introspect (
203
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
239
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
204
240
) ;
205
- return JSON . stringify ( data ) ;
241
+ return result ;
206
242
} ,
207
243
208
244
/**
@@ -235,11 +271,17 @@ const webBrowsing = {
235
271
redirect : "follow" ,
236
272
}
237
273
)
238
- . then ( ( res ) => res . json ( ) )
274
+ . then ( ( res ) => {
275
+ if ( res . ok ) return res . json ( ) ;
276
+ throw new Error (
277
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { auth : this . middleTruncate ( process . env . AGENT_SERPER_DEV_KEY , 5 ) , q : query } ) } `
278
+ ) ;
279
+ } )
239
280
. then ( ( data ) => {
240
281
return { response : data , error : null } ;
241
282
} )
242
283
. catch ( ( e ) => {
284
+ this . super . handlerProps . log ( `Serper.dev Error: ${ e . message } ` ) ;
243
285
return { response : null , error : e . message } ;
244
286
} ) ;
245
287
if ( error )
@@ -259,10 +301,12 @@ const webBrowsing = {
259
301
260
302
if ( data . length === 0 )
261
303
return `No information was found online for the search query.` ;
304
+
305
+ const result = JSON . stringify ( data ) ;
262
306
this . super . introspect (
263
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
307
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
264
308
) ;
265
- return JSON . stringify ( data ) ;
309
+ return result ;
266
310
} ,
267
311
_bingWebSearch : async function ( query ) {
268
312
if ( ! process . env . AGENT_BING_SEARCH_API_KEY ) {
@@ -289,7 +333,12 @@ const webBrowsing = {
289
333
process . env . AGENT_BING_SEARCH_API_KEY ,
290
334
} ,
291
335
} )
292
- . then ( ( res ) => res . json ( ) )
336
+ . then ( ( res ) => {
337
+ if ( res . ok ) return res . json ( ) ;
338
+ throw new Error (
339
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { auth : this . middleTruncate ( process . env . AGENT_BING_SEARCH_API_KEY , 5 ) , q : query } ) } `
340
+ ) ;
341
+ } )
293
342
. then ( ( data ) => {
294
343
const searchResults = data . webPages ?. value || [ ] ;
295
344
return searchResults . map ( ( result ) => ( {
@@ -299,16 +348,20 @@ const webBrowsing = {
299
348
} ) ) ;
300
349
} )
301
350
. catch ( ( e ) => {
302
- console . log ( e ) ;
351
+ this . super . handlerProps . log (
352
+ `Bing Web Search Error: ${ e . message } `
353
+ ) ;
303
354
return [ ] ;
304
355
} ) ;
305
356
306
357
if ( searchResponse . length === 0 )
307
358
return `No information was found online for the search query.` ;
359
+
360
+ const result = JSON . stringify ( searchResponse ) ;
308
361
this . super . introspect (
309
- `${ this . caller } : I found ${ searchResponse . length } results - looking over them now.`
362
+ `${ this . caller } : I found ${ searchResponse . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
310
363
) ;
311
- return JSON . stringify ( searchResponse ) ;
364
+ return result ;
312
365
} ,
313
366
_serplyEngine : async function (
314
367
query ,
@@ -353,20 +406,24 @@ const webBrowsing = {
353
406
"X-User-Agent" : device_type ,
354
407
} ,
355
408
} )
356
- . then ( ( res ) => res . json ( ) )
409
+ . then ( ( res ) => {
410
+ if ( res . ok ) return res . json ( ) ;
411
+ throw new Error (
412
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { auth : this . middleTruncate ( process . env . AGENT_SERPLY_API_KEY , 5 ) , q : query } ) } `
413
+ ) ;
414
+ } )
357
415
. then ( ( data ) => {
358
- if ( data ?. message === "Unauthorized" ) {
359
- return {
360
- response : null ,
361
- error :
362
- "Unauthorized. Please double check your AGENT_SERPLY_API_KEY" ,
363
- } ;
364
- }
416
+ if ( data ?. message === "Unauthorized" )
417
+ throw new Error (
418
+ "Unauthorized. Please double check your AGENT_SERPLY_API_KEY"
419
+ ) ;
365
420
return { response : data , error : null } ;
366
421
} )
367
422
. catch ( ( e ) => {
423
+ this . super . handlerProps . log ( `Serply Error: ${ e . message } ` ) ;
368
424
return { response : null , error : e . message } ;
369
425
} ) ;
426
+
370
427
if ( error )
371
428
return `There was an error searching for content. ${ error } ` ;
372
429
@@ -382,10 +439,12 @@ const webBrowsing = {
382
439
383
440
if ( data . length === 0 )
384
441
return `No information was found online for the search query.` ;
442
+
443
+ const result = JSON . stringify ( data ) ;
385
444
this . super . introspect (
386
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
445
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
387
446
) ;
388
- return JSON . stringify ( data ) ;
447
+ return result ;
389
448
} ,
390
449
_searXNGEngine : async function ( query ) {
391
450
let searchURL ;
@@ -421,11 +480,19 @@ const webBrowsing = {
421
480
"User-Agent" : "anything-llm" ,
422
481
} ,
423
482
} )
424
- . then ( ( res ) => res . json ( ) )
483
+ . then ( ( res ) => {
484
+ if ( res . ok ) return res . json ( ) ;
485
+ throw new Error (
486
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { url : searchURL . toString ( ) } ) } `
487
+ ) ;
488
+ } )
425
489
. then ( ( data ) => {
426
490
return { response : data , error : null } ;
427
491
} )
428
492
. catch ( ( e ) => {
493
+ this . super . handlerProps . log (
494
+ `SearXNG Search Error: ${ e . message } `
495
+ ) ;
429
496
return { response : null , error : e . message } ;
430
497
} ) ;
431
498
if ( error )
@@ -444,10 +511,12 @@ const webBrowsing = {
444
511
445
512
if ( data . length === 0 )
446
513
return `No information was found online for the search query.` ;
514
+
515
+ const result = JSON . stringify ( data ) ;
447
516
this . super . introspect (
448
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
517
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
449
518
) ;
450
- return JSON . stringify ( data ) ;
519
+ return result ;
451
520
} ,
452
521
_tavilySearch : async function ( query ) {
453
522
if ( ! process . env . AGENT_TAVILY_API_KEY ) {
@@ -474,11 +543,19 @@ const webBrowsing = {
474
543
query : query ,
475
544
} ) ,
476
545
} )
477
- . then ( ( res ) => res . json ( ) )
546
+ . then ( ( res ) => {
547
+ if ( res . ok ) return res . json ( ) ;
548
+ throw new Error (
549
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { auth : this . middleTruncate ( process . env . AGENT_TAVILY_API_KEY , 5 ) , q : query } ) } `
550
+ ) ;
551
+ } )
478
552
. then ( ( data ) => {
479
553
return { response : data , error : null } ;
480
554
} )
481
555
. catch ( ( e ) => {
556
+ this . super . handlerProps . log (
557
+ `Tavily Search Error: ${ e . message } `
558
+ ) ;
482
559
return { response : null , error : e . message } ;
483
560
} ) ;
484
561
@@ -497,10 +574,12 @@ const webBrowsing = {
497
574
498
575
if ( data . length === 0 )
499
576
return `No information was found online for the search query.` ;
577
+
578
+ const result = JSON . stringify ( data ) ;
500
579
this . super . introspect (
501
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
580
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
502
581
) ;
503
- return JSON . stringify ( data ) ;
582
+ return result ;
504
583
} ,
505
584
_duckDuckGoEngine : async function ( query ) {
506
585
this . super . introspect (
@@ -512,15 +591,23 @@ const webBrowsing = {
512
591
const searchURL = new URL ( "https://html.duckduckgo.com/html" ) ;
513
592
searchURL . searchParams . append ( "q" , query ) ;
514
593
515
- const response = await fetch ( searchURL . toString ( ) ) ;
516
-
517
- if ( ! response . ok ) {
518
- return `There was an error searching DuckDuckGo. Status: ${ response . status } ` ;
519
- }
594
+ const response = await fetch ( searchURL . toString ( ) )
595
+ . then ( ( res ) => {
596
+ if ( res . ok ) return res . text ( ) ;
597
+ throw new Error (
598
+ `${ res . status } - ${ res . statusText } . params: ${ JSON . stringify ( { url : searchURL . toString ( ) } ) } `
599
+ ) ;
600
+ } )
601
+ . catch ( ( e ) => {
602
+ this . super . handlerProps . log (
603
+ `DuckDuckGo Search Error: ${ e . message } `
604
+ ) ;
605
+ return null ;
606
+ } ) ;
520
607
521
- const html = await response . text ( ) ;
608
+ if ( ! response ) return `There was an error searching DuckDuckGo.` ;
609
+ const html = response ;
522
610
const data = [ ] ;
523
-
524
611
const results = html . split ( '<div class="result results_links' ) ;
525
612
526
613
// Skip first element since it's before the first result
@@ -556,11 +643,11 @@ const webBrowsing = {
556
643
return `No information was found online for the search query.` ;
557
644
}
558
645
646
+ const result = JSON . stringify ( data ) ;
559
647
this . super . introspect (
560
- `${ this . caller } : I found ${ data . length } results - looking over them now.`
648
+ `${ this . caller } : I found ${ data . length } results - reviewing the results now. (~ ${ this . countTokens ( result ) } tokens) `
561
649
) ;
562
-
563
- return JSON . stringify ( data ) ;
650
+ return result ;
564
651
} ,
565
652
} ) ;
566
653
} ,
0 commit comments