@librechat/agents 2.4.317 → 2.4.319

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