@librechat/agents 2.4.317 → 2.4.318

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cjs/tools/search/content.cjs +140 -0
  2. package/dist/cjs/tools/search/content.cjs.map +1 -0
  3. package/dist/cjs/tools/search/firecrawl.cjs +17 -37
  4. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  5. package/dist/cjs/tools/search/format.cjs +79 -29
  6. package/dist/cjs/tools/search/format.cjs.map +1 -1
  7. package/dist/cjs/tools/search/highlights.cjs +64 -13
  8. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  9. package/dist/cjs/tools/search/search.cjs +13 -15
  10. package/dist/cjs/tools/search/search.cjs.map +1 -1
  11. package/dist/cjs/tools/search/tool.cjs +44 -12
  12. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  13. package/dist/cjs/tools/search/utils.cjs +35 -0
  14. package/dist/cjs/tools/search/utils.cjs.map +1 -0
  15. package/dist/esm/tools/search/content.mjs +119 -0
  16. package/dist/esm/tools/search/content.mjs.map +1 -0
  17. package/dist/esm/tools/search/firecrawl.mjs +18 -37
  18. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  19. package/dist/esm/tools/search/format.mjs +79 -29
  20. package/dist/esm/tools/search/format.mjs.map +1 -1
  21. package/dist/esm/tools/search/highlights.mjs +64 -13
  22. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  23. package/dist/esm/tools/search/search.mjs +12 -14
  24. package/dist/esm/tools/search/search.mjs.map +1 -1
  25. package/dist/esm/tools/search/tool.mjs +44 -12
  26. package/dist/esm/tools/search/tool.mjs.map +1 -1
  27. package/dist/esm/tools/search/utils.mjs +32 -0
  28. package/dist/esm/tools/search/utils.mjs.map +1 -0
  29. package/dist/types/tools/search/content.d.ts +4 -0
  30. package/dist/types/tools/search/firecrawl.d.ts +6 -86
  31. package/dist/types/tools/search/format.d.ts +4 -1
  32. package/dist/types/tools/search/highlights.d.ts +1 -1
  33. package/dist/types/tools/search/search.d.ts +1 -1
  34. package/dist/types/tools/search/test.d.ts +1 -0
  35. package/dist/types/tools/search/tool.d.ts +12 -4
  36. package/dist/types/tools/search/types.d.ts +380 -46
  37. package/dist/types/tools/search/utils.d.ts +3 -0
  38. package/package.json +2 -1
  39. package/src/scripts/search.ts +5 -3
  40. package/src/tools/search/content.test.ts +173 -0
  41. package/src/tools/search/content.ts +147 -0
  42. package/src/tools/search/firecrawl.ts +27 -144
  43. package/src/tools/search/format.ts +89 -31
  44. package/src/tools/search/highlights.ts +99 -17
  45. package/src/tools/search/output.md +2775 -0
  46. package/src/tools/search/search.ts +42 -54
  47. package/src/tools/search/test.html +884 -0
  48. package/src/tools/search/test.md +643 -0
  49. package/src/tools/search/test.ts +159 -0
  50. package/src/tools/search/tool.ts +54 -15
  51. package/src/tools/search/types.ts +430 -52
  52. package/src/tools/search/utils.ts +43 -0
@@ -4,72 +4,41 @@ import type { BaseReranker } from './rerankers';
4
4
  export type SearchProvider = 'serper' | 'searxng';
5
5
  export type RerankerType = 'infinity' | 'jina' | 'cohere' | 'none';
6
6
 
7
- export interface OrganicResult {
8
- position?: number;
9
- title?: string;
10
- link: string;
11
- snippet?: string;
12
- date?: string;
13
- }
14
-
15
- export interface TopStoryResult {
16
- title?: string;
17
- link: string;
18
- source?: string;
19
- date?: string;
20
- imageUrl?: string;
21
- }
22
-
23
- export interface ImageResult {
24
- title?: string;
25
- imageUrl?: string;
26
- }
27
-
28
- export interface KnowledgeGraphResult {
29
- title?: string;
30
- type?: string;
31
- description?: string;
32
- attributes?: Record<string, string>;
33
- imageUrl?: string;
34
- }
35
-
36
- export interface AnswerBoxResult {
37
- title?: string;
38
- answer?: string;
39
- snippet?: string;
40
- date?: string;
41
- }
42
-
43
- export interface PeopleAlsoAskResult {
44
- question?: string;
45
- answer?: string;
46
- }
47
-
48
7
  export interface Highlight {
49
8
  score: number;
50
9
  text: string;
10
+ references?: UsedReferences;
51
11
  }
52
12
 
53
- export interface ValidSource {
54
- link: string;
55
- position?: number;
56
- title?: string;
57
- snippet?: string;
58
- date?: string;
13
+ export type ProcessedSource = {
59
14
  content?: string;
60
15
  attribution?: string;
16
+ references?: References;
61
17
  highlights?: Highlight[];
62
- }
18
+ };
19
+
20
+ export type ProcessedOrganic = OrganicResult & ProcessedSource;
21
+ export type ProcessedTopStory = TopStoryResult & ProcessedSource;
22
+ export type ValidSource = ProcessedOrganic | ProcessedTopStory;
63
23
 
24
+ export type ResultReference = {
25
+ link: string;
26
+ title?: string;
27
+ attribution?: string;
28
+ };
64
29
  export interface SearchResultData {
65
- organic?: ValidSource[];
66
- topStories?: ValidSource[];
30
+ organic?: ProcessedOrganic[];
31
+ topStories?: ProcessedTopStory[];
67
32
  images?: ImageResult[];
33
+ videos?: VideoResult[];
34
+ places?: PlaceResult[];
35
+ news?: NewsResult[];
36
+ shopping?: ShoppingResult[];
68
37
  knowledgeGraph?: KnowledgeGraphResult;
69
38
  answerBox?: AnswerBoxResult;
70
39
  peopleAlsoAsk?: PeopleAlsoAskResult[];
71
- relatedSearches?: string[];
72
- suggestions?: string[];
40
+ relatedSearches?: Array<{ query: string }>;
41
+ references?: ResultReference[];
73
42
  error?: string;
74
43
  }
75
44
 
@@ -94,11 +63,17 @@ export interface SearchConfig {
94
63
  searxngApiKey?: string;
95
64
  }
96
65
 
66
+ export type References = {
67
+ links: MediaReference[];
68
+ images: MediaReference[];
69
+ videos: MediaReference[];
70
+ };
97
71
  export interface ScrapeResult {
98
72
  url: string;
99
73
  error?: boolean;
100
74
  content: string;
101
75
  attribution?: string;
76
+ references?: References;
102
77
  highlights?: Highlight[];
103
78
  }
104
79
 
@@ -177,3 +152,406 @@ export interface SearchToolConfig
177
152
  runnableConfig?: RunnableConfig
178
153
  ) => void;
179
154
  }
155
+ export interface MediaReference {
156
+ originalUrl: string;
157
+ title?: string;
158
+ text?: string;
159
+ }
160
+
161
+ export type UsedReferences = {
162
+ type: 'link' | 'image' | 'video';
163
+ originalIndex: number;
164
+ reference: MediaReference;
165
+ }[];
166
+
167
+ /** Firecrawl */
168
+
169
+ export interface FirecrawlScrapeOptions {
170
+ formats?: string[];
171
+ includeTags?: string[];
172
+ excludeTags?: string[];
173
+ headers?: Record<string, string>;
174
+ waitFor?: number;
175
+ timeout?: number;
176
+ }
177
+
178
+ export interface ScrapeMetadata {
179
+ // Core source information
180
+ sourceURL?: string;
181
+ url?: string;
182
+ scrapeId?: string;
183
+ statusCode?: number;
184
+ // Basic metadata
185
+ title?: string;
186
+ description?: string;
187
+ language?: string;
188
+ favicon?: string;
189
+ viewport?: string;
190
+ robots?: string;
191
+ 'theme-color'?: string;
192
+ // Open Graph metadata
193
+ 'og:url'?: string;
194
+ 'og:title'?: string;
195
+ 'og:description'?: string;
196
+ 'og:type'?: string;
197
+ 'og:image'?: string;
198
+ 'og:image:width'?: string;
199
+ 'og:image:height'?: string;
200
+ 'og:site_name'?: string;
201
+ ogUrl?: string;
202
+ ogTitle?: string;
203
+ ogDescription?: string;
204
+ ogImage?: string;
205
+ ogSiteName?: string;
206
+ // Article metadata
207
+ 'article:author'?: string;
208
+ 'article:published_time'?: string;
209
+ 'article:modified_time'?: string;
210
+ 'article:section'?: string;
211
+ 'article:tag'?: string;
212
+ 'article:publisher'?: string;
213
+ publishedTime?: string;
214
+ modifiedTime?: string;
215
+ // Twitter metadata
216
+ 'twitter:site'?: string;
217
+ 'twitter:creator'?: string;
218
+ 'twitter:card'?: string;
219
+ 'twitter:image'?: string;
220
+ 'twitter:dnt'?: string;
221
+ 'twitter:app:name:iphone'?: string;
222
+ 'twitter:app:id:iphone'?: string;
223
+ 'twitter:app:url:iphone'?: string;
224
+ 'twitter:app:name:ipad'?: string;
225
+ 'twitter:app:id:ipad'?: string;
226
+ 'twitter:app:url:ipad'?: string;
227
+ 'twitter:app:name:googleplay'?: string;
228
+ 'twitter:app:id:googleplay'?: string;
229
+ 'twitter:app:url:googleplay'?: string;
230
+ // Facebook metadata
231
+ 'fb:app_id'?: string;
232
+ // App links
233
+ 'al:ios:url'?: string;
234
+ 'al:ios:app_name'?: string;
235
+ 'al:ios:app_store_id'?: string;
236
+ // Allow for additional properties that might be present
237
+ [key: string]: string | number | boolean | null | undefined;
238
+ }
239
+
240
+ export interface FirecrawlScrapeResponse {
241
+ success: boolean;
242
+ data?: {
243
+ markdown?: string;
244
+ html?: string;
245
+ rawHtml?: string;
246
+ screenshot?: string;
247
+ links?: string[];
248
+ metadata?: ScrapeMetadata;
249
+ };
250
+ error?: string;
251
+ }
252
+
253
+ export interface FirecrawlScraperConfig {
254
+ apiKey?: string;
255
+ apiUrl?: string;
256
+ formats?: string[];
257
+ timeout?: number;
258
+ }
259
+
260
+ export type GetSourcesParams = {
261
+ query: string;
262
+ country?: string;
263
+ numResults?: number;
264
+ };
265
+
266
+ /** Serper API */
267
+ export interface VideoResult {
268
+ title?: string;
269
+ link?: string;
270
+ snippet?: string;
271
+ imageUrl?: string;
272
+ duration?: string;
273
+ source?: string;
274
+ channel?: string;
275
+ date?: string;
276
+ position?: number;
277
+ }
278
+
279
+ export interface PlaceResult {
280
+ position?: number;
281
+ name?: string;
282
+ address?: string;
283
+ latitude?: number;
284
+ longitude?: number;
285
+ rating?: number;
286
+ ratingCount?: number;
287
+ category?: string;
288
+ identifier?: string;
289
+ }
290
+
291
+ export interface NewsResult {
292
+ title?: string;
293
+ link?: string;
294
+ snippet?: string;
295
+ date?: string;
296
+ source?: string;
297
+ imageUrl?: string;
298
+ position?: number;
299
+ }
300
+
301
+ export interface ShoppingResult {
302
+ title?: string;
303
+ source?: string;
304
+ link?: string;
305
+ price?: string;
306
+ delivery?: string;
307
+ imageUrl?: string;
308
+ rating?: number;
309
+ ratingCount?: number;
310
+ offers?: string;
311
+ productId?: string;
312
+ position?: number;
313
+ }
314
+
315
+ export interface ScholarResult {
316
+ title?: string;
317
+ link?: string;
318
+ publicationInfo?: string;
319
+ snippet?: string;
320
+ year?: number;
321
+ citedBy?: number;
322
+ }
323
+
324
+ export interface ImageResult {
325
+ title?: string;
326
+ imageUrl?: string;
327
+ imageWidth?: number;
328
+ imageHeight?: number;
329
+ thumbnailUrl?: string;
330
+ thumbnailWidth?: number;
331
+ thumbnailHeight?: number;
332
+ source?: string;
333
+ domain?: string;
334
+ link?: string;
335
+ googleUrl?: string;
336
+ position?: number;
337
+ }
338
+
339
+ export interface SerperSearchPayload extends SerperSearchInput {
340
+ /**
341
+ * Search type/vertical
342
+ * Options: "search" (web), "images", "news", "places", "videos"
343
+ */
344
+ type?: 'search' | 'images' | 'news' | 'places' | 'videos';
345
+
346
+ /**
347
+ * Starting index for search results pagination (used instead of page)
348
+ */
349
+ start?: number;
350
+
351
+ /**
352
+ * Filtering for safe search
353
+ * Options: "off", "moderate", "active"
354
+ */
355
+ safe?: 'off' | 'moderate' | 'active';
356
+ }
357
+
358
+ export type SerperSearchParameters = Pick<SerperSearchPayload, 'q' | 'type'> & {
359
+ engine: 'google';
360
+ };
361
+
362
+ export interface OrganicResult {
363
+ position?: number;
364
+ title?: string;
365
+ link: string;
366
+ snippet?: string;
367
+ date?: string;
368
+ sitelinks?: Array<{
369
+ title: string;
370
+ link: string;
371
+ }>;
372
+ }
373
+
374
+ export interface TopStoryResult {
375
+ title?: string;
376
+ link: string;
377
+ source?: string;
378
+ date?: string;
379
+ imageUrl?: string;
380
+ }
381
+ export interface KnowledgeGraphResult {
382
+ title?: string;
383
+ type?: string;
384
+ imageUrl?: string;
385
+ description?: string;
386
+ descriptionSource?: string;
387
+ descriptionLink?: string;
388
+ attributes?: Record<string, string>;
389
+ website?: string;
390
+ }
391
+
392
+ export interface AnswerBoxResult {
393
+ title?: string;
394
+ snippet?: string;
395
+ snippetHighlighted?: string[];
396
+ link?: string;
397
+ date?: string;
398
+ }
399
+
400
+ export interface PeopleAlsoAskResult {
401
+ question?: string;
402
+ snippet?: string;
403
+ title?: string;
404
+ link?: string;
405
+ }
406
+
407
+ export type RelatedSearches = Array<{ query: string }>;
408
+
409
+ export interface SerperSearchInput {
410
+ /**
411
+ * The search query string
412
+ */
413
+ q: string;
414
+
415
+ /**
416
+ * Country code for localized results
417
+ * Examples: "us", "uk", "ca", "de", etc.
418
+ */
419
+ gl?: string;
420
+
421
+ /**
422
+ * Interface language
423
+ * Examples: "en", "fr", "de", etc.
424
+ */
425
+ hl?: string;
426
+
427
+ /**
428
+ * Number of results to return (up to 100)
429
+ */
430
+ num?: number;
431
+ /**
432
+ * Specific location for contextual results
433
+ * Example: "New York, NY"
434
+ */
435
+ location?: string;
436
+
437
+ /**
438
+ * Search autocorrection setting
439
+ */
440
+ autocorrect?: boolean;
441
+ page?: number;
442
+ }
443
+
444
+ export type SerperResultData = {
445
+ searchParameters: SerperSearchPayload;
446
+ organic?: OrganicResult[];
447
+ topStories?: TopStoryResult[];
448
+ images?: ImageResult[];
449
+ videos?: VideoResult[];
450
+ places?: PlaceResult[];
451
+ news?: NewsResult[];
452
+ shopping?: ShoppingResult[];
453
+ peopleAlsoAsk?: PeopleAlsoAskResult[];
454
+ relatedSearches?: RelatedSearches;
455
+ knowledgeGraph?: KnowledgeGraphResult;
456
+ answerBox?: AnswerBoxResult;
457
+ credits?: number;
458
+ };
459
+
460
+ /** SearXNG */
461
+
462
+ export interface SearxNGSearchPayload {
463
+ /**
464
+ * The search query string
465
+ * Supports syntax specific to different search engines
466
+ * Example: "site:github.com SearXNG"
467
+ */
468
+ q: string;
469
+
470
+ /**
471
+ * Comma-separated list of search categories
472
+ * Example: "general,images,news"
473
+ */
474
+ categories?: string;
475
+
476
+ /**
477
+ * Comma-separated list of search engines to use
478
+ * Example: "google,bing,duckduckgo"
479
+ */
480
+ engines?: string;
481
+
482
+ /**
483
+ * Code of the language for search results
484
+ * Example: "en", "fr", "de", "es"
485
+ */
486
+ language?: string;
487
+
488
+ /**
489
+ * Search page number
490
+ * Default: 1
491
+ */
492
+ pageno?: number;
493
+
494
+ /**
495
+ * Time range filter for search results
496
+ * Options: "day", "month", "year"
497
+ */
498
+ time_range?: 'day' | 'month' | 'year';
499
+
500
+ /**
501
+ * Output format of results
502
+ * Options: "json", "csv", "rss"
503
+ */
504
+ format?: 'json' | 'csv' | 'rss';
505
+
506
+ /**
507
+ * Open search results on new tab
508
+ * Options: `0` (off), `1` (on)
509
+ */
510
+ results_on_new_tab?: 0 | 1;
511
+
512
+ /**
513
+ * Proxy image results through SearxNG
514
+ * Options: true, false
515
+ */
516
+ image_proxy?: boolean;
517
+
518
+ /**
519
+ * Service for autocomplete suggestions
520
+ * Options: "google", "dbpedia", "duckduckgo", "mwmbl",
521
+ * "startpage", "wikipedia", "stract", "swisscows", "qwant"
522
+ */
523
+ autocomplete?: string;
524
+
525
+ /**
526
+ * Safe search filtering level
527
+ * Options: "0" (off), "1" (moderate), "2" (strict)
528
+ */
529
+ safesearch?: 0 | 1 | 2;
530
+
531
+ /**
532
+ * Theme to use for results page
533
+ * Default: "simple" (other themes may be available per instance)
534
+ */
535
+ theme?: string;
536
+
537
+ /**
538
+ * List of enabled plugins
539
+ * Default: "Hash_plugin,Self_Information,Tracker_URL_remover,Ahmia_blacklist"
540
+ */
541
+ enabled_plugins?: string;
542
+
543
+ /**
544
+ * List of disabled plugins
545
+ */
546
+ disabled_plugins?: string;
547
+
548
+ /**
549
+ * List of enabled engines
550
+ */
551
+ enabled_engines?: string;
552
+
553
+ /**
554
+ * List of disabled engines
555
+ */
556
+ disabled_engines?: string;
557
+ }
@@ -0,0 +1,43 @@
1
+ /* eslint-disable no-console */
2
+ import type * as t from './types';
3
+
4
+ export const getDomainName = (
5
+ link: string,
6
+ metadata?: t.ScrapeMetadata
7
+ ): string | undefined => {
8
+ try {
9
+ const url = metadata?.sourceURL ?? metadata?.url ?? (link || '');
10
+ const domain = new URL(url).hostname.replace(/^www\./, '');
11
+ if (domain) {
12
+ return domain;
13
+ }
14
+ } catch (e) {
15
+ // URL parsing failed
16
+ console.error('Error parsing URL:', e);
17
+ }
18
+
19
+ return;
20
+ };
21
+
22
+ export function getAttribution(
23
+ link: string,
24
+ metadata?: t.ScrapeMetadata
25
+ ): string | undefined {
26
+ if (!metadata) return getDomainName(link, metadata);
27
+
28
+ const possibleAttributions = [
29
+ metadata.ogSiteName,
30
+ metadata['og:site_name'],
31
+ metadata.title?.split('|').pop()?.trim(),
32
+ metadata['twitter:site']?.replace(/^@/, ''),
33
+ ];
34
+
35
+ const attribution = possibleAttributions.find(
36
+ (attr) => attr != null && typeof attr === 'string' && attr.trim() !== ''
37
+ );
38
+ if (attribution != null) {
39
+ return attribution;
40
+ }
41
+
42
+ return getDomainName(link, metadata);
43
+ }