@librechat/agents 3.1.75-dev.1 → 3.1.76
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.
- package/dist/cjs/llm/openai/index.cjs +43 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +19 -10
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +67 -10
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +55 -66
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
- package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tavily-search.cjs +372 -0
- package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +26 -4
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +10 -3
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +43 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +19 -10
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +67 -10
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +55 -66
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
- package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tavily-search.mjs +370 -0
- package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +26 -4
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +10 -3
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/types/messages/format.d.ts +4 -1
- package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
- package/dist/types/tools/search/tavily-search.d.ts +4 -0
- package/dist/types/tools/search/types.d.ts +99 -5
- package/dist/types/tools/search/utils.d.ts +2 -2
- package/package.json +1 -1
- package/src/llm/custom-chat-models.smoke.test.ts +175 -1
- package/src/llm/openai/index.ts +124 -0
- package/src/llm/openai/utils/index.ts +23 -14
- package/src/llm/openai/utils/messages.test.ts +159 -0
- package/src/messages/format.ts +90 -13
- package/src/messages/formatAgentMessages.test.ts +166 -1
- package/src/tools/search/search.ts +83 -73
- package/src/tools/search/tavily-scraper.ts +235 -0
- package/src/tools/search/tavily-search.ts +424 -0
- package/src/tools/search/tavily.test.ts +965 -0
- package/src/tools/search/tool.ts +36 -26
- package/src/tools/search/types.ts +134 -11
- package/src/tools/search/utils.ts +13 -5
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var axios = require('axios');
|
|
4
|
+
|
|
5
|
+
const DEFAULT_TAVILY_TIMEOUT = 15000;
|
|
6
|
+
const TAVILY_COUNTRY_ALIASES = {
|
|
7
|
+
ba: 'bosnia and herzegovina',
|
|
8
|
+
cg: 'congo',
|
|
9
|
+
cz: 'czech republic',
|
|
10
|
+
gb: 'united kingdom',
|
|
11
|
+
mm: 'myanmar',
|
|
12
|
+
tr: 'turkey',
|
|
13
|
+
tt: 'trinidad and tobago',
|
|
14
|
+
uk: 'united kingdom',
|
|
15
|
+
};
|
|
16
|
+
const TAVILY_SUPPORTED_COUNTRIES = new Set([
|
|
17
|
+
'afghanistan',
|
|
18
|
+
'albania',
|
|
19
|
+
'algeria',
|
|
20
|
+
'andorra',
|
|
21
|
+
'angola',
|
|
22
|
+
'argentina',
|
|
23
|
+
'armenia',
|
|
24
|
+
'australia',
|
|
25
|
+
'austria',
|
|
26
|
+
'azerbaijan',
|
|
27
|
+
'bahamas',
|
|
28
|
+
'bahrain',
|
|
29
|
+
'bangladesh',
|
|
30
|
+
'barbados',
|
|
31
|
+
'belarus',
|
|
32
|
+
'belgium',
|
|
33
|
+
'belize',
|
|
34
|
+
'benin',
|
|
35
|
+
'bhutan',
|
|
36
|
+
'bolivia',
|
|
37
|
+
'bosnia and herzegovina',
|
|
38
|
+
'botswana',
|
|
39
|
+
'brazil',
|
|
40
|
+
'brunei',
|
|
41
|
+
'bulgaria',
|
|
42
|
+
'burkina faso',
|
|
43
|
+
'burundi',
|
|
44
|
+
'cambodia',
|
|
45
|
+
'cameroon',
|
|
46
|
+
'canada',
|
|
47
|
+
'cape verde',
|
|
48
|
+
'central african republic',
|
|
49
|
+
'chad',
|
|
50
|
+
'chile',
|
|
51
|
+
'china',
|
|
52
|
+
'colombia',
|
|
53
|
+
'comoros',
|
|
54
|
+
'congo',
|
|
55
|
+
'costa rica',
|
|
56
|
+
'croatia',
|
|
57
|
+
'cuba',
|
|
58
|
+
'cyprus',
|
|
59
|
+
'czech republic',
|
|
60
|
+
'denmark',
|
|
61
|
+
'djibouti',
|
|
62
|
+
'dominican republic',
|
|
63
|
+
'ecuador',
|
|
64
|
+
'egypt',
|
|
65
|
+
'el salvador',
|
|
66
|
+
'equatorial guinea',
|
|
67
|
+
'eritrea',
|
|
68
|
+
'estonia',
|
|
69
|
+
'ethiopia',
|
|
70
|
+
'fiji',
|
|
71
|
+
'finland',
|
|
72
|
+
'france',
|
|
73
|
+
'gabon',
|
|
74
|
+
'gambia',
|
|
75
|
+
'georgia',
|
|
76
|
+
'germany',
|
|
77
|
+
'ghana',
|
|
78
|
+
'greece',
|
|
79
|
+
'guatemala',
|
|
80
|
+
'guinea',
|
|
81
|
+
'haiti',
|
|
82
|
+
'honduras',
|
|
83
|
+
'hungary',
|
|
84
|
+
'iceland',
|
|
85
|
+
'india',
|
|
86
|
+
'indonesia',
|
|
87
|
+
'iran',
|
|
88
|
+
'iraq',
|
|
89
|
+
'ireland',
|
|
90
|
+
'israel',
|
|
91
|
+
'italy',
|
|
92
|
+
'jamaica',
|
|
93
|
+
'japan',
|
|
94
|
+
'jordan',
|
|
95
|
+
'kazakhstan',
|
|
96
|
+
'kenya',
|
|
97
|
+
'kuwait',
|
|
98
|
+
'kyrgyzstan',
|
|
99
|
+
'latvia',
|
|
100
|
+
'lebanon',
|
|
101
|
+
'lesotho',
|
|
102
|
+
'liberia',
|
|
103
|
+
'libya',
|
|
104
|
+
'liechtenstein',
|
|
105
|
+
'lithuania',
|
|
106
|
+
'luxembourg',
|
|
107
|
+
'madagascar',
|
|
108
|
+
'malawi',
|
|
109
|
+
'malaysia',
|
|
110
|
+
'maldives',
|
|
111
|
+
'mali',
|
|
112
|
+
'malta',
|
|
113
|
+
'mauritania',
|
|
114
|
+
'mauritius',
|
|
115
|
+
'mexico',
|
|
116
|
+
'moldova',
|
|
117
|
+
'monaco',
|
|
118
|
+
'mongolia',
|
|
119
|
+
'montenegro',
|
|
120
|
+
'morocco',
|
|
121
|
+
'mozambique',
|
|
122
|
+
'myanmar',
|
|
123
|
+
'namibia',
|
|
124
|
+
'nepal',
|
|
125
|
+
'netherlands',
|
|
126
|
+
'new zealand',
|
|
127
|
+
'nicaragua',
|
|
128
|
+
'niger',
|
|
129
|
+
'nigeria',
|
|
130
|
+
'north korea',
|
|
131
|
+
'north macedonia',
|
|
132
|
+
'norway',
|
|
133
|
+
'oman',
|
|
134
|
+
'pakistan',
|
|
135
|
+
'panama',
|
|
136
|
+
'papua new guinea',
|
|
137
|
+
'paraguay',
|
|
138
|
+
'peru',
|
|
139
|
+
'philippines',
|
|
140
|
+
'poland',
|
|
141
|
+
'portugal',
|
|
142
|
+
'qatar',
|
|
143
|
+
'romania',
|
|
144
|
+
'russia',
|
|
145
|
+
'rwanda',
|
|
146
|
+
'saudi arabia',
|
|
147
|
+
'senegal',
|
|
148
|
+
'serbia',
|
|
149
|
+
'singapore',
|
|
150
|
+
'slovakia',
|
|
151
|
+
'slovenia',
|
|
152
|
+
'somalia',
|
|
153
|
+
'south africa',
|
|
154
|
+
'south korea',
|
|
155
|
+
'south sudan',
|
|
156
|
+
'spain',
|
|
157
|
+
'sri lanka',
|
|
158
|
+
'sudan',
|
|
159
|
+
'sweden',
|
|
160
|
+
'switzerland',
|
|
161
|
+
'syria',
|
|
162
|
+
'taiwan',
|
|
163
|
+
'tajikistan',
|
|
164
|
+
'tanzania',
|
|
165
|
+
'thailand',
|
|
166
|
+
'togo',
|
|
167
|
+
'trinidad and tobago',
|
|
168
|
+
'tunisia',
|
|
169
|
+
'turkey',
|
|
170
|
+
'turkmenistan',
|
|
171
|
+
'uganda',
|
|
172
|
+
'ukraine',
|
|
173
|
+
'united arab emirates',
|
|
174
|
+
'united kingdom',
|
|
175
|
+
'united states',
|
|
176
|
+
'uruguay',
|
|
177
|
+
'uzbekistan',
|
|
178
|
+
'venezuela',
|
|
179
|
+
'vietnam',
|
|
180
|
+
'yemen',
|
|
181
|
+
'zambia',
|
|
182
|
+
'zimbabwe',
|
|
183
|
+
]);
|
|
184
|
+
const TAVILY_REGION_NAMES = new Intl.DisplayNames(['en'], {
|
|
185
|
+
type: 'region',
|
|
186
|
+
});
|
|
187
|
+
const normalizeTavilyCountryName = (country) => country
|
|
188
|
+
.toLowerCase()
|
|
189
|
+
.replace(/\s*\([^)]*\)/g, '')
|
|
190
|
+
.replace(/\s*&\s*/g, ' and ')
|
|
191
|
+
.normalize('NFD')
|
|
192
|
+
.replace(/\p{Diacritic}/gu, '');
|
|
193
|
+
const normalizeTavilyCountry = (country) => {
|
|
194
|
+
const normalizedCountry = country?.trim().toLowerCase();
|
|
195
|
+
if (normalizedCountry == null || normalizedCountry === '') {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
const countryAlias = TAVILY_COUNTRY_ALIASES[normalizedCountry];
|
|
199
|
+
if (countryAlias != null) {
|
|
200
|
+
return TAVILY_SUPPORTED_COUNTRIES.has(countryAlias)
|
|
201
|
+
? countryAlias
|
|
202
|
+
: undefined;
|
|
203
|
+
}
|
|
204
|
+
if (/^[a-z]{2}$/.test(normalizedCountry)) {
|
|
205
|
+
const regionName = TAVILY_REGION_NAMES.of(normalizedCountry.toUpperCase());
|
|
206
|
+
if (regionName == null) {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
const countryName = normalizeTavilyCountryName(regionName);
|
|
210
|
+
return TAVILY_SUPPORTED_COUNTRIES.has(countryName)
|
|
211
|
+
? countryName
|
|
212
|
+
: undefined;
|
|
213
|
+
}
|
|
214
|
+
const countryName = normalizeTavilyCountryName(normalizedCountry);
|
|
215
|
+
return TAVILY_SUPPORTED_COUNTRIES.has(countryName) ? countryName : undefined;
|
|
216
|
+
};
|
|
217
|
+
const normalizeTavilyTimeRange = (timeRange) => {
|
|
218
|
+
switch (timeRange) {
|
|
219
|
+
case 'h':
|
|
220
|
+
case 'd':
|
|
221
|
+
return 'day';
|
|
222
|
+
case 'w':
|
|
223
|
+
return 'week';
|
|
224
|
+
case 'm':
|
|
225
|
+
return 'month';
|
|
226
|
+
case 'y':
|
|
227
|
+
return 'year';
|
|
228
|
+
case 'day':
|
|
229
|
+
case 'week':
|
|
230
|
+
case 'month':
|
|
231
|
+
case 'year':
|
|
232
|
+
return timeRange;
|
|
233
|
+
default:
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
const getHostname = (link) => {
|
|
238
|
+
try {
|
|
239
|
+
return new URL(link).hostname;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return link;
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
const createTavilyAPI = (apiKey, apiUrl, options) => {
|
|
246
|
+
const config = {
|
|
247
|
+
apiKey: apiKey ?? process.env.TAVILY_API_KEY,
|
|
248
|
+
apiUrl: apiUrl ??
|
|
249
|
+
process.env.TAVILY_SEARCH_URL ??
|
|
250
|
+
'https://api.tavily.com/search',
|
|
251
|
+
timeout: options?.timeout ?? DEFAULT_TAVILY_TIMEOUT,
|
|
252
|
+
};
|
|
253
|
+
if (config.apiKey == null || config.apiKey === '') {
|
|
254
|
+
throw new Error('TAVILY_API_KEY is required for Tavily API');
|
|
255
|
+
}
|
|
256
|
+
const getSources = async ({ query, date, country, numResults = 8, type, news, }) => {
|
|
257
|
+
if (!query.trim()) {
|
|
258
|
+
return { success: false, error: 'Query cannot be empty' };
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
const timeRange = normalizeTavilyTimeRange(options?.timeRange) ??
|
|
262
|
+
(date != null ? (normalizeTavilyTimeRange(date) ?? 'day') : undefined);
|
|
263
|
+
const topic = news === true || type === 'news'
|
|
264
|
+
? 'news'
|
|
265
|
+
: (options?.topic ?? 'general');
|
|
266
|
+
const maxResults = options?.maxResults ?? numResults;
|
|
267
|
+
const searchDepth = options?.searchDepth ?? 'basic';
|
|
268
|
+
const payload = {
|
|
269
|
+
query,
|
|
270
|
+
search_depth: searchDepth,
|
|
271
|
+
topic,
|
|
272
|
+
max_results: Math.min(Math.max(1, maxResults), 20),
|
|
273
|
+
};
|
|
274
|
+
if (options?.safeSearch != null &&
|
|
275
|
+
searchDepth !== 'fast' &&
|
|
276
|
+
searchDepth !== 'ultra-fast') {
|
|
277
|
+
payload.safe_search = options.safeSearch;
|
|
278
|
+
}
|
|
279
|
+
if (timeRange != null) {
|
|
280
|
+
payload.time_range = timeRange;
|
|
281
|
+
}
|
|
282
|
+
const tavilyCountry = topic === 'general' ? normalizeTavilyCountry(country) : undefined;
|
|
283
|
+
if (tavilyCountry != null) {
|
|
284
|
+
payload.country = tavilyCountry;
|
|
285
|
+
}
|
|
286
|
+
if (type === 'images' || options?.includeImages) {
|
|
287
|
+
payload.include_images = true;
|
|
288
|
+
}
|
|
289
|
+
if (options?.includeAnswer != null) {
|
|
290
|
+
payload.include_answer = options.includeAnswer;
|
|
291
|
+
}
|
|
292
|
+
if (options?.includeRawContent != null) {
|
|
293
|
+
payload.include_raw_content = options.includeRawContent;
|
|
294
|
+
}
|
|
295
|
+
if (options?.includeDomains != null &&
|
|
296
|
+
options.includeDomains.length > 0) {
|
|
297
|
+
payload.include_domains = options.includeDomains;
|
|
298
|
+
}
|
|
299
|
+
if (options?.excludeDomains != null &&
|
|
300
|
+
options.excludeDomains.length > 0) {
|
|
301
|
+
payload.exclude_domains = options.excludeDomains;
|
|
302
|
+
}
|
|
303
|
+
if (options?.includeImageDescriptions != null) {
|
|
304
|
+
payload.include_image_descriptions = options.includeImageDescriptions;
|
|
305
|
+
}
|
|
306
|
+
if (options?.includeFavicon != null) {
|
|
307
|
+
payload.include_favicon = options.includeFavicon;
|
|
308
|
+
}
|
|
309
|
+
if (options?.chunksPerSource != null && searchDepth === 'advanced') {
|
|
310
|
+
payload.chunks_per_source = options.chunksPerSource;
|
|
311
|
+
}
|
|
312
|
+
const response = await axios.post(config.apiUrl, payload, {
|
|
313
|
+
headers: {
|
|
314
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
315
|
+
'Content-Type': 'application/json',
|
|
316
|
+
},
|
|
317
|
+
timeout: config.timeout,
|
|
318
|
+
});
|
|
319
|
+
const data = response.data;
|
|
320
|
+
const organicResults = (data.results ?? []).map((result) => ({
|
|
321
|
+
title: result.title ?? '',
|
|
322
|
+
link: result.url ?? '',
|
|
323
|
+
snippet: result.content ?? '',
|
|
324
|
+
date: result.published_date,
|
|
325
|
+
}));
|
|
326
|
+
const imageResults = Array.isArray(data.images)
|
|
327
|
+
? data.images.slice(0, 6).reduce((acc, image) => {
|
|
328
|
+
const imageUrl = typeof image === 'string' ? image : image.url;
|
|
329
|
+
if (imageUrl == null || imageUrl === '') {
|
|
330
|
+
return acc;
|
|
331
|
+
}
|
|
332
|
+
acc.push({
|
|
333
|
+
imageUrl,
|
|
334
|
+
title: typeof image === 'string' ? undefined : image.description,
|
|
335
|
+
position: acc.length + 1,
|
|
336
|
+
});
|
|
337
|
+
return acc;
|
|
338
|
+
}, [])
|
|
339
|
+
: [];
|
|
340
|
+
const newsResults = topic === 'news'
|
|
341
|
+
? organicResults.map((r) => ({
|
|
342
|
+
title: r.title,
|
|
343
|
+
link: r.link,
|
|
344
|
+
snippet: r.snippet,
|
|
345
|
+
date: r.date,
|
|
346
|
+
source: getHostname(r.link),
|
|
347
|
+
}))
|
|
348
|
+
: [];
|
|
349
|
+
const results = {
|
|
350
|
+
organic: organicResults,
|
|
351
|
+
images: imageResults,
|
|
352
|
+
topStories: [],
|
|
353
|
+
videos: [],
|
|
354
|
+
news: newsResults,
|
|
355
|
+
answerBox: data.answer != null ? { snippet: data.answer } : undefined,
|
|
356
|
+
relatedSearches: [],
|
|
357
|
+
};
|
|
358
|
+
return { success: true, data: results };
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
362
|
+
return {
|
|
363
|
+
success: false,
|
|
364
|
+
error: `Tavily API request failed: ${errorMessage}`,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return { getSources };
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
exports.createTavilyAPI = createTavilyAPI;
|
|
372
|
+
//# sourceMappingURL=tavily-search.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tavily-search.cjs","sources":["../../../../src/tools/search/tavily-search.ts"],"sourcesContent":["import axios from 'axios';\nimport type * as t from './types';\n\nconst DEFAULT_TAVILY_TIMEOUT = 15000;\n\nconst TAVILY_COUNTRY_ALIASES: Record<string, string> = {\n ba: 'bosnia and herzegovina',\n cg: 'congo',\n cz: 'czech republic',\n gb: 'united kingdom',\n mm: 'myanmar',\n tr: 'turkey',\n tt: 'trinidad and tobago',\n uk: 'united kingdom',\n};\n\nconst TAVILY_SUPPORTED_COUNTRIES = new Set([\n 'afghanistan',\n 'albania',\n 'algeria',\n 'andorra',\n 'angola',\n 'argentina',\n 'armenia',\n 'australia',\n 'austria',\n 'azerbaijan',\n 'bahamas',\n 'bahrain',\n 'bangladesh',\n 'barbados',\n 'belarus',\n 'belgium',\n 'belize',\n 'benin',\n 'bhutan',\n 'bolivia',\n 'bosnia and herzegovina',\n 'botswana',\n 'brazil',\n 'brunei',\n 'bulgaria',\n 'burkina faso',\n 'burundi',\n 'cambodia',\n 'cameroon',\n 'canada',\n 'cape verde',\n 'central african republic',\n 'chad',\n 'chile',\n 'china',\n 'colombia',\n 'comoros',\n 'congo',\n 'costa rica',\n 'croatia',\n 'cuba',\n 'cyprus',\n 'czech republic',\n 'denmark',\n 'djibouti',\n 'dominican republic',\n 'ecuador',\n 'egypt',\n 'el salvador',\n 'equatorial guinea',\n 'eritrea',\n 'estonia',\n 'ethiopia',\n 'fiji',\n 'finland',\n 'france',\n 'gabon',\n 'gambia',\n 'georgia',\n 'germany',\n 'ghana',\n 'greece',\n 'guatemala',\n 'guinea',\n 'haiti',\n 'honduras',\n 'hungary',\n 'iceland',\n 'india',\n 'indonesia',\n 'iran',\n 'iraq',\n 'ireland',\n 'israel',\n 'italy',\n 'jamaica',\n 'japan',\n 'jordan',\n 'kazakhstan',\n 'kenya',\n 'kuwait',\n 'kyrgyzstan',\n 'latvia',\n 'lebanon',\n 'lesotho',\n 'liberia',\n 'libya',\n 'liechtenstein',\n 'lithuania',\n 'luxembourg',\n 'madagascar',\n 'malawi',\n 'malaysia',\n 'maldives',\n 'mali',\n 'malta',\n 'mauritania',\n 'mauritius',\n 'mexico',\n 'moldova',\n 'monaco',\n 'mongolia',\n 'montenegro',\n 'morocco',\n 'mozambique',\n 'myanmar',\n 'namibia',\n 'nepal',\n 'netherlands',\n 'new zealand',\n 'nicaragua',\n 'niger',\n 'nigeria',\n 'north korea',\n 'north macedonia',\n 'norway',\n 'oman',\n 'pakistan',\n 'panama',\n 'papua new guinea',\n 'paraguay',\n 'peru',\n 'philippines',\n 'poland',\n 'portugal',\n 'qatar',\n 'romania',\n 'russia',\n 'rwanda',\n 'saudi arabia',\n 'senegal',\n 'serbia',\n 'singapore',\n 'slovakia',\n 'slovenia',\n 'somalia',\n 'south africa',\n 'south korea',\n 'south sudan',\n 'spain',\n 'sri lanka',\n 'sudan',\n 'sweden',\n 'switzerland',\n 'syria',\n 'taiwan',\n 'tajikistan',\n 'tanzania',\n 'thailand',\n 'togo',\n 'trinidad and tobago',\n 'tunisia',\n 'turkey',\n 'turkmenistan',\n 'uganda',\n 'ukraine',\n 'united arab emirates',\n 'united kingdom',\n 'united states',\n 'uruguay',\n 'uzbekistan',\n 'venezuela',\n 'vietnam',\n 'yemen',\n 'zambia',\n 'zimbabwe',\n]);\n\nconst TAVILY_REGION_NAMES = new Intl.DisplayNames(['en'], {\n type: 'region',\n});\n\nconst normalizeTavilyCountryName = (country: string): string =>\n country\n .toLowerCase()\n .replace(/\\s*\\([^)]*\\)/g, '')\n .replace(/\\s*&\\s*/g, ' and ')\n .normalize('NFD')\n .replace(/\\p{Diacritic}/gu, '');\n\nconst normalizeTavilyCountry = (country?: string): string | undefined => {\n const normalizedCountry = country?.trim().toLowerCase();\n if (normalizedCountry == null || normalizedCountry === '') {\n return undefined;\n }\n\n const countryAlias = TAVILY_COUNTRY_ALIASES[normalizedCountry];\n if (countryAlias != null) {\n return TAVILY_SUPPORTED_COUNTRIES.has(countryAlias)\n ? countryAlias\n : undefined;\n }\n\n if (/^[a-z]{2}$/.test(normalizedCountry)) {\n const regionName = TAVILY_REGION_NAMES.of(normalizedCountry.toUpperCase());\n if (regionName == null) {\n return undefined;\n }\n const countryName = normalizeTavilyCountryName(regionName);\n return TAVILY_SUPPORTED_COUNTRIES.has(countryName)\n ? countryName\n : undefined;\n }\n\n const countryName = normalizeTavilyCountryName(normalizedCountry);\n return TAVILY_SUPPORTED_COUNTRIES.has(countryName) ? countryName : undefined;\n};\n\nconst normalizeTavilyTimeRange = (\n timeRange?: t.TavilyTimeRangeInput\n): t.TavilyTimeRange | undefined => {\n switch (timeRange) {\n case 'h':\n case 'd':\n return 'day';\n case 'w':\n return 'week';\n case 'm':\n return 'month';\n case 'y':\n return 'year';\n case 'day':\n case 'week':\n case 'month':\n case 'year':\n return timeRange;\n default:\n return undefined;\n }\n};\n\nconst getHostname = (link: string): string => {\n try {\n return new URL(link).hostname;\n } catch {\n return link;\n }\n};\n\nexport const createTavilyAPI = (\n apiKey?: string,\n apiUrl?: string,\n options?: t.TavilySearchOptions\n): {\n getSources: (params: t.GetSourcesParams) => Promise<t.SearchResult>;\n} => {\n const config = {\n apiKey: apiKey ?? process.env.TAVILY_API_KEY,\n apiUrl:\n apiUrl ??\n process.env.TAVILY_SEARCH_URL ??\n 'https://api.tavily.com/search',\n timeout: options?.timeout ?? DEFAULT_TAVILY_TIMEOUT,\n };\n\n if (config.apiKey == null || config.apiKey === '') {\n throw new Error('TAVILY_API_KEY is required for Tavily API');\n }\n\n const getSources = async ({\n query,\n date,\n country,\n numResults = 8,\n type,\n news,\n }: t.GetSourcesParams): Promise<t.SearchResult> => {\n if (!query.trim()) {\n return { success: false, error: 'Query cannot be empty' };\n }\n\n try {\n const timeRange =\n normalizeTavilyTimeRange(options?.timeRange) ??\n (date != null ? (normalizeTavilyTimeRange(date) ?? 'day') : undefined);\n const topic =\n news === true || type === 'news'\n ? 'news'\n : (options?.topic ?? 'general');\n const maxResults = options?.maxResults ?? numResults;\n const searchDepth = options?.searchDepth ?? 'basic';\n\n const payload: t.TavilySearchPayload = {\n query,\n search_depth: searchDepth,\n topic,\n max_results: Math.min(Math.max(1, maxResults), 20),\n };\n\n if (\n options?.safeSearch != null &&\n searchDepth !== 'fast' &&\n searchDepth !== 'ultra-fast'\n ) {\n payload.safe_search = options.safeSearch;\n }\n if (timeRange != null) {\n payload.time_range = timeRange;\n }\n const tavilyCountry =\n topic === 'general' ? normalizeTavilyCountry(country) : undefined;\n if (tavilyCountry != null) {\n payload.country = tavilyCountry;\n }\n if (type === 'images' || options?.includeImages) {\n payload.include_images = true;\n }\n if (options?.includeAnswer != null) {\n payload.include_answer = options.includeAnswer;\n }\n if (options?.includeRawContent != null) {\n payload.include_raw_content = options.includeRawContent;\n }\n if (\n options?.includeDomains != null &&\n options.includeDomains.length > 0\n ) {\n payload.include_domains = options.includeDomains;\n }\n if (\n options?.excludeDomains != null &&\n options.excludeDomains.length > 0\n ) {\n payload.exclude_domains = options.excludeDomains;\n }\n if (options?.includeImageDescriptions != null) {\n payload.include_image_descriptions = options.includeImageDescriptions;\n }\n if (options?.includeFavicon != null) {\n payload.include_favicon = options.includeFavicon;\n }\n if (options?.chunksPerSource != null && searchDepth === 'advanced') {\n payload.chunks_per_source = options.chunksPerSource;\n }\n\n const response = await axios.post<t.TavilySearchResponse>(\n config.apiUrl,\n payload,\n {\n headers: {\n Authorization: `Bearer ${config.apiKey}`,\n 'Content-Type': 'application/json',\n },\n timeout: config.timeout,\n }\n );\n\n const data = response.data;\n\n const organicResults: t.OrganicResult[] = (data.results ?? []).map(\n (result: t.TavilySearchResult) => ({\n title: result.title ?? '',\n link: result.url ?? '',\n snippet: result.content ?? '',\n date: result.published_date,\n })\n );\n\n const imageResults: t.ImageResult[] = Array.isArray(data.images)\n ? data.images.slice(0, 6).reduce<t.ImageResult[]>((acc, image) => {\n const imageUrl = typeof image === 'string' ? image : image.url;\n if (imageUrl == null || imageUrl === '') {\n return acc;\n }\n acc.push({\n imageUrl,\n title: typeof image === 'string' ? undefined : image.description,\n position: acc.length + 1,\n });\n return acc;\n }, [])\n : [];\n\n const newsResults: t.NewsResult[] =\n topic === 'news'\n ? organicResults.map((r) => ({\n title: r.title,\n link: r.link,\n snippet: r.snippet,\n date: r.date,\n source: getHostname(r.link),\n }))\n : [];\n\n const results: t.SearchResultData = {\n organic: organicResults,\n images: imageResults,\n topStories: [],\n videos: [],\n news: newsResults,\n answerBox: data.answer != null ? { snippet: data.answer } : undefined,\n relatedSearches: [],\n };\n\n return { success: true, data: results };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Tavily API request failed: ${errorMessage}`,\n };\n }\n };\n\n return { getSources };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ var tools = require('@langchain/core/tools');
|
|
|
4
4
|
var schema = require('./schema.cjs');
|
|
5
5
|
var search = require('./search.cjs');
|
|
6
6
|
var serperScraper = require('./serper-scraper.cjs');
|
|
7
|
+
var tavilyScraper = require('./tavily-scraper.cjs');
|
|
7
8
|
var firecrawl = require('./firecrawl.cjs');
|
|
8
9
|
var highlights = require('./highlights.cjs');
|
|
9
10
|
var format = require('./format.cjs');
|
|
@@ -131,7 +132,7 @@ async function executeParallelSearches({ searchAPI, query, date, country, safeSe
|
|
|
131
132
|
});
|
|
132
133
|
return { success: true, data: mergedResults };
|
|
133
134
|
}
|
|
134
|
-
function createSearchProcessor({ searchAPI, safeSearch, sourceProcessor, onGetHighlights, logger, }) {
|
|
135
|
+
function createSearchProcessor({ searchAPI, safeSearch, supportsVideos, sourceProcessor, onGetHighlights, logger, }) {
|
|
135
136
|
return async function ({ query, date, country, proMode = true, maxSources = 5, onSearchResults, images = false, videos = false, news = false, }) {
|
|
136
137
|
try {
|
|
137
138
|
// Execute parallel searches and merge results
|
|
@@ -142,7 +143,7 @@ function createSearchProcessor({ searchAPI, safeSearch, sourceProcessor, onGetHi
|
|
|
142
143
|
country,
|
|
143
144
|
safeSearch,
|
|
144
145
|
images,
|
|
145
|
-
videos,
|
|
146
|
+
videos: supportsVideos && videos,
|
|
146
147
|
news,
|
|
147
148
|
logger,
|
|
148
149
|
});
|
|
@@ -208,8 +209,14 @@ function createTool({ schema: schema$1, search, onSearchResults: _onSearchResult
|
|
|
208
209
|
});
|
|
209
210
|
}
|
|
210
211
|
const createSearchTool = (config = {}) => {
|
|
211
|
-
const { searchProvider = 'serper', serperApiKey, searxngInstanceUrl, searxngApiKey, rerankerType = 'cohere', topResults = 5, strategies = ['no_extraction'], filterContent = true, safeSearch = 1, scraperProvider = 'firecrawl', firecrawlApiKey, firecrawlApiUrl, firecrawlVersion, firecrawlOptions, serperScraperOptions, scraperTimeout, jinaApiKey, jinaApiUrl, cohereApiKey, onSearchResults: _onSearchResults, onGetHighlights, } = config;
|
|
212
|
+
const { searchProvider = 'serper', serperApiKey, searxngInstanceUrl, searxngApiKey, tavilyApiKey, tavilySearchUrl, tavilyExtractUrl, tavilySearchOptions, rerankerType = 'cohere', topResults = 5, strategies = ['no_extraction'], filterContent = true, safeSearch = 1, scraperProvider = 'firecrawl', firecrawlApiKey, firecrawlApiUrl, firecrawlVersion, firecrawlOptions, serperScraperOptions, tavilyScraperOptions, scraperTimeout, jinaApiKey, jinaApiUrl, cohereApiKey, onSearchResults: _onSearchResults, onGetHighlights, } = config;
|
|
212
213
|
const logger = config.logger || utils.createDefaultLogger();
|
|
214
|
+
const effectiveTavilySearchOptions = searchProvider === 'tavily' && config.safeSearch != null
|
|
215
|
+
? {
|
|
216
|
+
...tavilySearchOptions,
|
|
217
|
+
safeSearch: config.safeSearch !== 0,
|
|
218
|
+
}
|
|
219
|
+
: tavilySearchOptions;
|
|
213
220
|
const schemaProperties = {
|
|
214
221
|
query: schema.querySchema,
|
|
215
222
|
date: schema.dateSchema,
|
|
@@ -217,7 +224,7 @@ const createSearchTool = (config = {}) => {
|
|
|
217
224
|
videos: schema.videosSchema,
|
|
218
225
|
news: schema.newsSchema,
|
|
219
226
|
};
|
|
220
|
-
if (searchProvider === 'serper') {
|
|
227
|
+
if (searchProvider === 'serper' || searchProvider === 'tavily') {
|
|
221
228
|
schemaProperties.country = schema.countrySchema;
|
|
222
229
|
}
|
|
223
230
|
const toolSchema = {
|
|
@@ -230,6 +237,9 @@ const createSearchTool = (config = {}) => {
|
|
|
230
237
|
serperApiKey,
|
|
231
238
|
searxngInstanceUrl,
|
|
232
239
|
searxngApiKey,
|
|
240
|
+
tavilyApiKey,
|
|
241
|
+
tavilySearchUrl,
|
|
242
|
+
tavilySearchOptions: effectiveTavilySearchOptions,
|
|
233
243
|
});
|
|
234
244
|
/** Create scraper based on scraperProvider */
|
|
235
245
|
let scraperInstance;
|
|
@@ -241,6 +251,17 @@ const createSearchTool = (config = {}) => {
|
|
|
241
251
|
logger,
|
|
242
252
|
});
|
|
243
253
|
}
|
|
254
|
+
else if (scraperProvider === 'tavily') {
|
|
255
|
+
scraperInstance = tavilyScraper.createTavilyScraper({
|
|
256
|
+
...tavilyScraperOptions,
|
|
257
|
+
apiKey: tavilyScraperOptions?.apiKey ??
|
|
258
|
+
tavilyApiKey ??
|
|
259
|
+
process.env.TAVILY_API_KEY,
|
|
260
|
+
apiUrl: tavilyScraperOptions?.apiUrl ?? tavilyExtractUrl,
|
|
261
|
+
timeout: scraperTimeout ?? tavilyScraperOptions?.timeout,
|
|
262
|
+
logger,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
244
265
|
else {
|
|
245
266
|
scraperInstance = firecrawl.createFirecrawlScraper({
|
|
246
267
|
...firecrawlOptions,
|
|
@@ -270,6 +291,7 @@ const createSearchTool = (config = {}) => {
|
|
|
270
291
|
const search$1 = createSearchProcessor({
|
|
271
292
|
searchAPI,
|
|
272
293
|
safeSearch,
|
|
294
|
+
supportsVideos: searchProvider !== 'tavily',
|
|
273
295
|
sourceProcessor,
|
|
274
296
|
onGetHighlights,
|
|
275
297
|
logger,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.cjs","sources":["../../../../src/tools/search/tool.ts"],"sourcesContent":["import { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from './types';\nimport {\n WebSearchToolDescription,\n WebSearchToolName,\n countrySchema,\n imagesSchema,\n videosSchema,\n querySchema,\n dateSchema,\n newsSchema,\n DATE_RANGE,\n} from './schema';\nimport { createSearchAPI, createSourceProcessor } from './search';\nimport { createSerperScraper } from './serper-scraper';\nimport { createFirecrawlScraper } from './firecrawl';\nimport { expandHighlights } from './highlights';\nimport { formatResultsForLLM } from './format';\nimport { createDefaultLogger } from './utils';\nimport { createReranker } from './rerankers';\nimport { Constants } from '@/common';\n\n/**\n * Executes parallel searches and merges the results\n */\nasync function executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n}: {\n searchAPI: ReturnType<typeof createSearchAPI>;\n query: string;\n date?: DATE_RANGE;\n country?: string;\n safeSearch: t.SearchToolConfig['safeSearch'];\n images: boolean;\n videos: boolean;\n news: boolean;\n logger: t.Logger;\n}): Promise<t.SearchResult> {\n // Prepare all search tasks to run in parallel\n const searchTasks: Promise<t.SearchResult>[] = [\n // Main search\n searchAPI.getSources({\n query,\n date,\n country,\n safeSearch,\n }),\n ];\n\n if (images) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'images',\n })\n .catch((error) => {\n logger.error('Error fetching images:', error);\n return {\n success: false,\n error: `Images search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (videos) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'videos',\n })\n .catch((error) => {\n logger.error('Error fetching videos:', error);\n return {\n success: false,\n error: `Videos search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (news) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'news',\n })\n .catch((error) => {\n logger.error('Error fetching news:', error);\n return {\n success: false,\n error: `News search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n\n // Run all searches in parallel\n const results = await Promise.all(searchTasks);\n\n // Get the main search result (first result)\n const mainResult = results[0];\n if (!mainResult.success) {\n throw new Error(mainResult.error ?? 'Search failed');\n }\n\n // Merge additional results with the main results\n const mergedResults = { ...mainResult.data };\n\n // Convert existing news to topStories if present\n if (mergedResults.news !== undefined && mergedResults.news.length > 0) {\n const existingNewsAsTopStories = mergedResults.news\n .filter((newsItem) => newsItem.link !== undefined && newsItem.link !== '')\n .map((newsItem) => ({\n title: newsItem.title ?? '',\n link: newsItem.link ?? '',\n source: newsItem.source ?? '',\n date: newsItem.date ?? '',\n imageUrl: newsItem.imageUrl ?? '',\n processed: false,\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...existingNewsAsTopStories,\n ];\n delete mergedResults.news;\n }\n\n results.slice(1).forEach((result) => {\n if (result.success && result.data !== undefined) {\n if (result.data.images !== undefined && result.data.images.length > 0) {\n mergedResults.images = [\n ...(mergedResults.images ?? []),\n ...result.data.images,\n ];\n }\n if (result.data.videos !== undefined && result.data.videos.length > 0) {\n mergedResults.videos = [\n ...(mergedResults.videos ?? []),\n ...result.data.videos,\n ];\n }\n if (result.data.news !== undefined && result.data.news.length > 0) {\n const newsAsTopStories = result.data.news.map((newsItem) => ({\n ...newsItem,\n link: newsItem.link ?? '',\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...newsAsTopStories,\n ];\n }\n }\n });\n\n return { success: true, data: mergedResults };\n}\n\nfunction createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n}: {\n safeSearch: t.SearchToolConfig['safeSearch'];\n searchAPI: ReturnType<typeof createSearchAPI>;\n sourceProcessor: ReturnType<typeof createSourceProcessor>;\n onGetHighlights: t.SearchToolConfig['onGetHighlights'];\n logger: t.Logger;\n}) {\n return async function ({\n query,\n date,\n country,\n proMode = true,\n maxSources = 5,\n onSearchResults,\n images = false,\n videos = false,\n news = false,\n }: {\n query: string;\n country?: string;\n date?: DATE_RANGE;\n proMode?: boolean;\n maxSources?: number;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n }): Promise<t.SearchResultData> {\n try {\n // Execute parallel searches and merge results\n const searchResult = await executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n });\n\n onSearchResults?.(searchResult);\n\n const processedSources = await sourceProcessor.processSources({\n query,\n news,\n result: searchResult,\n proMode,\n onGetHighlights,\n numElements: maxSources,\n });\n\n return expandHighlights(processedSources);\n } catch (error) {\n logger.error('Error in search:', error);\n return {\n organic: [],\n topStories: [],\n images: [],\n videos: [],\n news: [],\n relatedSearches: [],\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n}\n\nfunction createOnSearchResults({\n runnableConfig,\n onSearchResults,\n}: {\n runnableConfig: RunnableConfig;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}) {\n return function (results: t.SearchResult): void {\n if (!onSearchResults) {\n return;\n }\n onSearchResults(results, runnableConfig);\n };\n}\n\nfunction createTool({\n schema,\n search,\n onSearchResults: _onSearchResults,\n}: {\n schema: Record<string, unknown>;\n search: ReturnType<typeof createSearchProcessor>;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}): DynamicStructuredTool {\n return tool(\n async (rawParams, runnableConfig) => {\n const params = rawParams as SearchToolParams;\n const { query, date, country: _c, images, videos, news } = params;\n const country = typeof _c === 'string' && _c ? _c : undefined;\n const searchResult = await search({\n query,\n date,\n country,\n images,\n videos,\n news,\n onSearchResults: createOnSearchResults({\n runnableConfig,\n onSearchResults: _onSearchResults,\n }),\n });\n const turn = runnableConfig.toolCall?.turn ?? 0;\n const { output, references } = formatResultsForLLM(turn, searchResult);\n const data: t.SearchResultData = { turn, ...searchResult, references };\n return [output, { [Constants.WEB_SEARCH]: data }];\n },\n {\n name: WebSearchToolName,\n description: WebSearchToolDescription,\n schema: schema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\n/**\n * Creates a search tool with a schema that dynamically includes the country field\n * only when the searchProvider is 'serper'.\n *\n * Supports multiple scraper providers:\n * - Firecrawl (default): Full-featured web scraping with multiple formats\n * - Serper: Lightweight scraping using Serper's scrape API\n *\n * @example\n * ```typescript\n * // Using Firecrawl scraper (default)\n * const searchTool = createSearchTool({\n * searchProvider: 'serper',\n * scraperProvider: 'firecrawl',\n * firecrawlApiKey: 'your-firecrawl-key'\n * });\n *\n * // Using Serper scraper\n * const searchTool = createSearchTool({\n * searchProvider: 'serper',\n * scraperProvider: 'serper',\n * serperApiKey: 'your-serper-key'\n * });\n * ```\n *\n * @param config - The search tool configuration\n * @returns A DynamicStructuredTool with a schema that depends on the searchProvider\n */\n/** Input params type for search tool */\ninterface SearchToolParams {\n query: string;\n date?: DATE_RANGE;\n country?: string;\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n}\n\nexport const createSearchTool = (\n config: t.SearchToolConfig = {}\n): DynamicStructuredTool => {\n const {\n searchProvider = 'serper',\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n rerankerType = 'cohere',\n topResults = 5,\n strategies = ['no_extraction'],\n filterContent = true,\n safeSearch = 1,\n scraperProvider = 'firecrawl',\n firecrawlApiKey,\n firecrawlApiUrl,\n firecrawlVersion,\n firecrawlOptions,\n serperScraperOptions,\n scraperTimeout,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n onSearchResults: _onSearchResults,\n onGetHighlights,\n } = config;\n\n const logger = config.logger || createDefaultLogger();\n\n const schemaProperties: Record<string, unknown> = {\n query: querySchema,\n date: dateSchema,\n images: imagesSchema,\n videos: videosSchema,\n news: newsSchema,\n };\n\n if (searchProvider === 'serper') {\n schemaProperties.country = countrySchema;\n }\n\n const toolSchema = {\n type: 'object',\n properties: schemaProperties,\n required: ['query'],\n };\n\n const searchAPI = createSearchAPI({\n searchProvider,\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n });\n\n /** Create scraper based on scraperProvider */\n let scraperInstance: t.BaseScraper;\n\n if (scraperProvider === 'serper') {\n scraperInstance = createSerperScraper({\n ...serperScraperOptions,\n apiKey: serperApiKey,\n timeout: scraperTimeout ?? serperScraperOptions?.timeout,\n logger,\n });\n } else {\n scraperInstance = createFirecrawlScraper({\n ...firecrawlOptions,\n apiKey: firecrawlApiKey ?? process.env.FIRECRAWL_API_KEY,\n apiUrl: firecrawlApiUrl,\n version: firecrawlVersion,\n timeout: scraperTimeout ?? firecrawlOptions?.timeout,\n formats: firecrawlOptions?.formats ?? ['markdown', 'rawHtml'],\n logger,\n });\n }\n\n const selectedReranker = createReranker({\n rerankerType,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n logger,\n });\n\n if (!selectedReranker) {\n logger.warn('No reranker selected. Using default ranking.');\n }\n\n const sourceProcessor = createSourceProcessor(\n {\n reranker: selectedReranker,\n topResults,\n strategies,\n filterContent,\n logger,\n },\n scraperInstance\n );\n\n const search = createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n });\n\n return createTool({\n search,\n schema: toolSchema,\n onSearchResults: _onSearchResults,\n });\n};\n"],"names":["expandHighlights","schema","tool","formatResultsForLLM","Constants","WebSearchToolName","WebSearchToolDescription","createDefaultLogger","querySchema","dateSchema","imagesSchema","videosSchema","newsSchema","countrySchema","createSearchAPI","createSerperScraper","createFirecrawlScraper","createReranker","createSourceProcessor","search"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tool.cjs","sources":["../../../../src/tools/search/tool.ts"],"sourcesContent":["import { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from './types';\nimport {\n WebSearchToolDescription,\n WebSearchToolName,\n countrySchema,\n imagesSchema,\n videosSchema,\n querySchema,\n dateSchema,\n newsSchema,\n DATE_RANGE,\n} from './schema';\nimport { createSearchAPI, createSourceProcessor } from './search';\nimport { createSerperScraper } from './serper-scraper';\nimport { createTavilyScraper } from './tavily-scraper';\nimport { createFirecrawlScraper } from './firecrawl';\nimport { expandHighlights } from './highlights';\nimport { formatResultsForLLM } from './format';\nimport { createDefaultLogger } from './utils';\nimport { createReranker } from './rerankers';\nimport { Constants } from '@/common';\n\n/**\n * Executes parallel searches and merges the results\n */\nasync function executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n}: {\n searchAPI: ReturnType<typeof createSearchAPI>;\n query: string;\n date?: DATE_RANGE;\n country?: string;\n safeSearch: t.SearchToolConfig['safeSearch'];\n images: boolean;\n videos: boolean;\n news: boolean;\n logger: t.Logger;\n}): Promise<t.SearchResult> {\n // Prepare all search tasks to run in parallel\n const searchTasks: Promise<t.SearchResult>[] = [\n // Main search\n searchAPI.getSources({\n query,\n date,\n country,\n safeSearch,\n }),\n ];\n\n if (images) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'images',\n })\n .catch((error) => {\n logger.error('Error fetching images:', error);\n return {\n success: false,\n error: `Images search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (videos) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'videos',\n })\n .catch((error) => {\n logger.error('Error fetching videos:', error);\n return {\n success: false,\n error: `Videos search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (news) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'news',\n })\n .catch((error) => {\n logger.error('Error fetching news:', error);\n return {\n success: false,\n error: `News search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n\n // Run all searches in parallel\n const results = await Promise.all(searchTasks);\n\n // Get the main search result (first result)\n const mainResult = results[0];\n if (!mainResult.success) {\n throw new Error(mainResult.error ?? 'Search failed');\n }\n\n // Merge additional results with the main results\n const mergedResults = { ...mainResult.data };\n\n // Convert existing news to topStories if present\n if (mergedResults.news !== undefined && mergedResults.news.length > 0) {\n const existingNewsAsTopStories = mergedResults.news\n .filter((newsItem) => newsItem.link !== undefined && newsItem.link !== '')\n .map((newsItem) => ({\n title: newsItem.title ?? '',\n link: newsItem.link ?? '',\n source: newsItem.source ?? '',\n date: newsItem.date ?? '',\n imageUrl: newsItem.imageUrl ?? '',\n processed: false,\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...existingNewsAsTopStories,\n ];\n delete mergedResults.news;\n }\n\n results.slice(1).forEach((result) => {\n if (result.success && result.data !== undefined) {\n if (result.data.images !== undefined && result.data.images.length > 0) {\n mergedResults.images = [\n ...(mergedResults.images ?? []),\n ...result.data.images,\n ];\n }\n if (result.data.videos !== undefined && result.data.videos.length > 0) {\n mergedResults.videos = [\n ...(mergedResults.videos ?? []),\n ...result.data.videos,\n ];\n }\n if (result.data.news !== undefined && result.data.news.length > 0) {\n const newsAsTopStories = result.data.news.map((newsItem) => ({\n ...newsItem,\n link: newsItem.link ?? '',\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...newsAsTopStories,\n ];\n }\n }\n });\n\n return { success: true, data: mergedResults };\n}\n\nfunction createSearchProcessor({\n searchAPI,\n safeSearch,\n supportsVideos,\n sourceProcessor,\n onGetHighlights,\n logger,\n}: {\n safeSearch: t.SearchToolConfig['safeSearch'];\n supportsVideos: boolean;\n searchAPI: ReturnType<typeof createSearchAPI>;\n sourceProcessor: ReturnType<typeof createSourceProcessor>;\n onGetHighlights: t.SearchToolConfig['onGetHighlights'];\n logger: t.Logger;\n}) {\n return async function ({\n query,\n date,\n country,\n proMode = true,\n maxSources = 5,\n onSearchResults,\n images = false,\n videos = false,\n news = false,\n }: {\n query: string;\n country?: string;\n date?: DATE_RANGE;\n proMode?: boolean;\n maxSources?: number;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n }): Promise<t.SearchResultData> {\n try {\n // Execute parallel searches and merge results\n const searchResult = await executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos: supportsVideos && videos,\n news,\n logger,\n });\n\n onSearchResults?.(searchResult);\n\n const processedSources = await sourceProcessor.processSources({\n query,\n news,\n result: searchResult,\n proMode,\n onGetHighlights,\n numElements: maxSources,\n });\n\n return expandHighlights(processedSources);\n } catch (error) {\n logger.error('Error in search:', error);\n return {\n organic: [],\n topStories: [],\n images: [],\n videos: [],\n news: [],\n relatedSearches: [],\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n}\n\nfunction createOnSearchResults({\n runnableConfig,\n onSearchResults,\n}: {\n runnableConfig: RunnableConfig;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}) {\n return function (results: t.SearchResult): void {\n if (!onSearchResults) {\n return;\n }\n onSearchResults(results, runnableConfig);\n };\n}\n\nfunction createTool({\n schema,\n search,\n onSearchResults: _onSearchResults,\n}: {\n schema: Record<string, unknown>;\n search: ReturnType<typeof createSearchProcessor>;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}): DynamicStructuredTool {\n return tool(\n async (rawParams, runnableConfig) => {\n const params = rawParams as SearchToolParams;\n const { query, date, country: _c, images, videos, news } = params;\n const country = typeof _c === 'string' && _c ? _c : undefined;\n const searchResult = await search({\n query,\n date,\n country,\n images,\n videos,\n news,\n onSearchResults: createOnSearchResults({\n runnableConfig,\n onSearchResults: _onSearchResults,\n }),\n });\n const turn = runnableConfig.toolCall?.turn ?? 0;\n const { output, references } = formatResultsForLLM(turn, searchResult);\n const data: t.SearchResultData = { turn, ...searchResult, references };\n return [output, { [Constants.WEB_SEARCH]: data }];\n },\n {\n name: WebSearchToolName,\n description: WebSearchToolDescription,\n schema: schema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\n/**\n * Creates a search tool with configurable search and scraper providers.\n *\n * Search providers: Serper (Google results), SearXNG (self-hosted meta-search), Tavily (AI-optimized).\n * Scraper providers: Firecrawl (default, full-featured), Serper (lightweight), Tavily (batch extraction).\n *\n * The country schema field is exposed to the LLM for providers that support localized results.\n */\n/** Input params type for search tool */\ninterface SearchToolParams {\n query: string;\n date?: DATE_RANGE;\n country?: string;\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n}\n\nexport const createSearchTool = (\n config: t.SearchToolConfig = {}\n): DynamicStructuredTool => {\n const {\n searchProvider = 'serper',\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n tavilyApiKey,\n tavilySearchUrl,\n tavilyExtractUrl,\n tavilySearchOptions,\n rerankerType = 'cohere',\n topResults = 5,\n strategies = ['no_extraction'],\n filterContent = true,\n safeSearch = 1,\n scraperProvider = 'firecrawl',\n firecrawlApiKey,\n firecrawlApiUrl,\n firecrawlVersion,\n firecrawlOptions,\n serperScraperOptions,\n tavilyScraperOptions,\n scraperTimeout,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n onSearchResults: _onSearchResults,\n onGetHighlights,\n } = config;\n\n const logger = config.logger || createDefaultLogger();\n const effectiveTavilySearchOptions =\n searchProvider === 'tavily' && config.safeSearch != null\n ? {\n ...tavilySearchOptions,\n safeSearch: config.safeSearch !== 0,\n }\n : tavilySearchOptions;\n\n const schemaProperties: Record<string, unknown> = {\n query: querySchema,\n date: dateSchema,\n images: imagesSchema,\n videos: videosSchema,\n news: newsSchema,\n };\n\n if (searchProvider === 'serper' || searchProvider === 'tavily') {\n schemaProperties.country = countrySchema;\n }\n\n const toolSchema = {\n type: 'object',\n properties: schemaProperties,\n required: ['query'],\n };\n\n const searchAPI = createSearchAPI({\n searchProvider,\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n tavilyApiKey,\n tavilySearchUrl,\n tavilySearchOptions: effectiveTavilySearchOptions,\n });\n\n /** Create scraper based on scraperProvider */\n let scraperInstance: t.BaseScraper;\n\n if (scraperProvider === 'serper') {\n scraperInstance = createSerperScraper({\n ...serperScraperOptions,\n apiKey: serperApiKey,\n timeout: scraperTimeout ?? serperScraperOptions?.timeout,\n logger,\n });\n } else if (scraperProvider === 'tavily') {\n scraperInstance = createTavilyScraper({\n ...tavilyScraperOptions,\n apiKey:\n tavilyScraperOptions?.apiKey ??\n tavilyApiKey ??\n process.env.TAVILY_API_KEY,\n apiUrl: tavilyScraperOptions?.apiUrl ?? tavilyExtractUrl,\n timeout: scraperTimeout ?? tavilyScraperOptions?.timeout,\n logger,\n });\n } else {\n scraperInstance = createFirecrawlScraper({\n ...firecrawlOptions,\n apiKey: firecrawlApiKey ?? process.env.FIRECRAWL_API_KEY,\n apiUrl: firecrawlApiUrl,\n version: firecrawlVersion,\n timeout: scraperTimeout ?? firecrawlOptions?.timeout,\n formats: firecrawlOptions?.formats ?? ['markdown', 'rawHtml'],\n logger,\n });\n }\n\n const selectedReranker = createReranker({\n rerankerType,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n logger,\n });\n\n if (!selectedReranker) {\n logger.warn('No reranker selected. Using default ranking.');\n }\n\n const sourceProcessor = createSourceProcessor(\n {\n reranker: selectedReranker,\n topResults,\n strategies,\n filterContent,\n logger,\n },\n scraperInstance\n );\n\n const search = createSearchProcessor({\n searchAPI,\n safeSearch,\n supportsVideos: searchProvider !== 'tavily',\n sourceProcessor,\n onGetHighlights,\n logger,\n });\n\n return createTool({\n search,\n schema: toolSchema,\n onSearchResults: _onSearchResults,\n });\n};\n"],"names":["expandHighlights","schema","tool","formatResultsForLLM","Constants","WebSearchToolName","WebSearchToolDescription","createDefaultLogger","querySchema","dateSchema","imagesSchema","videosSchema","newsSchema","countrySchema","createSearchAPI","createSerperScraper","createTavilyScraper","createFirecrawlScraper","createReranker","createSourceProcessor","search"],"mappings":"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"}
|
|
@@ -24,7 +24,13 @@ const createDefaultLogger = () => {
|
|
|
24
24
|
const fileExtRegex = /\.(pdf|jpe?g|png|gif|svg|webp|bmp|ico|tiff?|avif|heic|doc[xm]?|xls[xm]?|ppt[xm]?|zip|rar|mp[34]|mov|avi|wav)(?:\?.*)?$/i;
|
|
25
25
|
const getDomainName = (link, metadata, logger) => {
|
|
26
26
|
try {
|
|
27
|
-
const
|
|
27
|
+
const sourceUrl = metadata?.sourceURL;
|
|
28
|
+
const metadataUrl = metadata?.url;
|
|
29
|
+
const url = typeof sourceUrl === 'string'
|
|
30
|
+
? sourceUrl
|
|
31
|
+
: typeof metadataUrl === 'string'
|
|
32
|
+
? metadataUrl
|
|
33
|
+
: link || '';
|
|
28
34
|
const domain = new URL(url).hostname.replace(/^www\./, '');
|
|
29
35
|
if (domain) {
|
|
30
36
|
return domain;
|
|
@@ -46,13 +52,14 @@ function getAttribution(link, metadata, logger) {
|
|
|
46
52
|
return getDomainName(link, metadata, logger);
|
|
47
53
|
const twitterSite = metadata['twitter:site'];
|
|
48
54
|
const twitterSiteFormatted = typeof twitterSite === 'string' ? twitterSite.replace(/^@/, '') : undefined;
|
|
55
|
+
const title = metadata.title;
|
|
49
56
|
const possibleAttributions = [
|
|
50
57
|
metadata.ogSiteName,
|
|
51
58
|
metadata['og:site_name'],
|
|
52
|
-
|
|
59
|
+
typeof title === 'string' ? title.split('|').pop()?.trim() : undefined,
|
|
53
60
|
twitterSiteFormatted,
|
|
54
61
|
];
|
|
55
|
-
const attribution = possibleAttributions.find((attr) =>
|
|
62
|
+
const attribution = possibleAttributions.find((attr) => typeof attr === 'string' && attr.trim() !== '');
|
|
56
63
|
if (attribution != null) {
|
|
57
64
|
return attribution;
|
|
58
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sources":["../../../../src/tools/search/utils.ts"],"sourcesContent":["/* eslint-disable no-console */\n\nimport type * as t from './types';\n\n/**\n * Singleton instance of the default logger\n */\nlet defaultLoggerInstance: t.Logger | null = null;\n\n/**\n * Creates a default logger that maps to console methods\n * Uses a singleton pattern to avoid creating multiple instances\n * @returns A default logger that implements the Logger interface\n */\nexport const createDefaultLogger = (): t.Logger => {\n if (!defaultLoggerInstance) {\n defaultLoggerInstance = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n debug: console.debug,\n } as t.Logger;\n }\n return defaultLoggerInstance;\n};\n\nexport const fileExtRegex =\n /\\.(pdf|jpe?g|png|gif|svg|webp|bmp|ico|tiff?|avif|heic|doc[xm]?|xls[xm]?|ppt[xm]?|zip|rar|mp[34]|mov|avi|wav)(?:\\?.*)?$/i;\n\nexport const getDomainName = (\n link: string,\n metadata?: t.ScrapeMetadata,\n logger?: t.Logger\n): string | undefined => {\n try {\n const
|
|
1
|
+
{"version":3,"file":"utils.cjs","sources":["../../../../src/tools/search/utils.ts"],"sourcesContent":["/* eslint-disable no-console */\n\nimport type * as t from './types';\n\n/**\n * Singleton instance of the default logger\n */\nlet defaultLoggerInstance: t.Logger | null = null;\n\n/**\n * Creates a default logger that maps to console methods\n * Uses a singleton pattern to avoid creating multiple instances\n * @returns A default logger that implements the Logger interface\n */\nexport const createDefaultLogger = (): t.Logger => {\n if (!defaultLoggerInstance) {\n defaultLoggerInstance = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n debug: console.debug,\n } as t.Logger;\n }\n return defaultLoggerInstance;\n};\n\nexport const fileExtRegex =\n /\\.(pdf|jpe?g|png|gif|svg|webp|bmp|ico|tiff?|avif|heic|doc[xm]?|xls[xm]?|ppt[xm]?|zip|rar|mp[34]|mov|avi|wav)(?:\\?.*)?$/i;\n\nexport const getDomainName = (\n link: string,\n metadata?: t.ScrapeMetadata | t.GenericScrapeMetadata,\n logger?: t.Logger\n): string | undefined => {\n try {\n const sourceUrl = metadata?.sourceURL;\n const metadataUrl = metadata?.url;\n const url =\n typeof sourceUrl === 'string'\n ? sourceUrl\n : typeof metadataUrl === 'string'\n ? metadataUrl\n : link || '';\n const domain = new URL(url).hostname.replace(/^www\\./, '');\n if (domain) {\n return domain;\n }\n } catch (e) {\n // URL parsing failed\n if (logger) {\n logger.error('Error parsing URL:', e);\n } else {\n console.error('Error parsing URL:', e);\n }\n }\n\n return;\n};\n\nexport function getAttribution(\n link: string,\n metadata?: t.ScrapeMetadata | t.GenericScrapeMetadata,\n logger?: t.Logger\n): string | undefined {\n if (!metadata) return getDomainName(link, metadata, logger);\n\n const twitterSite = metadata['twitter:site'];\n const twitterSiteFormatted =\n typeof twitterSite === 'string' ? twitterSite.replace(/^@/, '') : undefined;\n const title = metadata.title;\n\n const possibleAttributions = [\n metadata.ogSiteName,\n metadata['og:site_name'],\n typeof title === 'string' ? title.split('|').pop()?.trim() : undefined,\n twitterSiteFormatted,\n ];\n\n const attribution = possibleAttributions.find(\n (attr): attr is string => typeof attr === 'string' && attr.trim() !== ''\n );\n if (attribution != null) {\n return attribution;\n }\n\n return getDomainName(link, metadata, logger);\n}\n"],"names":[],"mappings":";;AAAA;AAIA;;AAEG;AACH,IAAI,qBAAqB,GAAoB,IAAI;AAEjD;;;;AAIG;AACI,MAAM,mBAAmB,GAAG,MAAe;IAChD,IAAI,CAAC,qBAAqB,EAAE;AAC1B,QAAA,qBAAqB,GAAG;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;SACT;IACf;AACA,IAAA,OAAO,qBAAqB;AAC9B;AAEO,MAAM,YAAY,GACvB;AAEK,MAAM,aAAa,GAAG,CAC3B,IAAY,EACZ,QAAqD,EACrD,MAAiB,KACK;AACtB,IAAA,IAAI;AACF,QAAA,MAAM,SAAS,GAAG,QAAQ,EAAE,SAAS;AACrC,QAAA,MAAM,WAAW,GAAG,QAAQ,EAAE,GAAG;AACjC,QAAA,MAAM,GAAG,GACP,OAAO,SAAS,KAAK;AACnB,cAAE;AACF,cAAE,OAAO,WAAW,KAAK;AACvB,kBAAE;AACF,kBAAE,IAAI,IAAI,EAAE;AAClB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC1D,IAAI,MAAM,EAAE;AACV,YAAA,OAAO,MAAM;QACf;IACF;IAAE,OAAO,CAAC,EAAE;;QAEV,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC;QACvC;aAAO;AACL,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC;QACxC;IACF;IAEA;AACF;SAEgB,cAAc,CAC5B,IAAY,EACZ,QAAqD,EACrD,MAAiB,EAAA;AAEjB,IAAA,IAAI,CAAC,QAAQ;QAAE,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC;AAE3D,IAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC;IAC5C,MAAM,oBAAoB,GACxB,OAAO,WAAW,KAAK,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,SAAS;AAC7E,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK;AAE5B,IAAA,MAAM,oBAAoB,GAAG;AAC3B,QAAA,QAAQ,CAAC,UAAU;QACnB,QAAQ,CAAC,cAAc,CAAC;QACxB,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,SAAS;QACtE,oBAAoB;KACrB;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAC3C,CAAC,IAAI,KAAqB,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CACzE;AACD,IAAA,IAAI,WAAW,IAAI,IAAI,EAAE;AACvB,QAAA,OAAO,WAAW;IACpB;IAEA,OAAO,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC;AAC9C;;;;;;;"}
|