@librechat/agents 2.4.320 → 2.4.322
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/tools/search/firecrawl.cjs +6 -4
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/format.cjs +117 -80
- package/dist/cjs/tools/search/format.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +43 -36
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs +70 -0
- package/dist/cjs/tools/search/schema.cjs.map +1 -0
- package/dist/cjs/tools/search/search.cjs +125 -52
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +162 -47
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/search/utils.cjs +34 -5
- package/dist/cjs/tools/search/utils.cjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +6 -4
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/format.mjs +118 -81
- package/dist/esm/tools/search/format.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +43 -36
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs +61 -0
- package/dist/esm/tools/search/schema.mjs.map +1 -0
- package/dist/esm/tools/search/search.mjs +126 -53
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +161 -46
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/search/utils.mjs +33 -6
- package/dist/esm/tools/search/utils.mjs.map +1 -1
- package/dist/types/tools/search/firecrawl.d.ts +1 -0
- package/dist/types/tools/search/rerankers.d.ts +8 -4
- package/dist/types/tools/search/schema.d.ts +16 -0
- package/dist/types/tools/search/tool.d.ts +13 -0
- package/dist/types/tools/search/types.d.ts +36 -0
- package/dist/types/tools/search/utils.d.ts +9 -2
- package/package.json +3 -2
- package/src/scripts/search.ts +3 -0
- package/src/tools/search/firecrawl.ts +9 -4
- package/src/tools/search/format.ts +157 -87
- package/src/tools/search/rerankers.ts +57 -36
- package/src/tools/search/schema.ts +63 -0
- package/src/tools/search/search.ts +165 -52
- package/src/tools/search/tool.ts +217 -44
- package/src/tools/search/types.ts +37 -0
- package/src/tools/search/utils.ts +37 -5
- package/src/utils/llmConfig.ts +1 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var axios = require('axios');
|
|
4
4
|
var content = require('./content.cjs');
|
|
5
|
+
var utils = require('./utils.cjs');
|
|
5
6
|
|
|
6
|
-
/* eslint-disable no-console */
|
|
7
7
|
/**
|
|
8
8
|
* Firecrawl scraper implementation
|
|
9
9
|
* Uses the Firecrawl API to scrape web pages
|
|
@@ -13,6 +13,7 @@ class FirecrawlScraper {
|
|
|
13
13
|
apiUrl;
|
|
14
14
|
defaultFormats;
|
|
15
15
|
timeout;
|
|
16
|
+
logger;
|
|
16
17
|
constructor(config = {}) {
|
|
17
18
|
this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';
|
|
18
19
|
const baseUrl = config.apiUrl ??
|
|
@@ -21,10 +22,11 @@ class FirecrawlScraper {
|
|
|
21
22
|
this.apiUrl = `${baseUrl.replace(/\/+$/, '')}/v1/scrape`;
|
|
22
23
|
this.defaultFormats = config.formats ?? ['markdown', 'html'];
|
|
23
24
|
this.timeout = config.timeout ?? 15000;
|
|
25
|
+
this.logger = config.logger || utils.createDefaultLogger();
|
|
24
26
|
if (!this.apiKey) {
|
|
25
|
-
|
|
27
|
+
this.logger.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');
|
|
26
28
|
}
|
|
27
|
-
|
|
29
|
+
this.logger.debug(`Firecrawl scraper initialized with API URL: ${this.apiUrl}`);
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Scrape a single URL
|
|
@@ -86,7 +88,7 @@ class FirecrawlScraper {
|
|
|
86
88
|
return [markdown, rest];
|
|
87
89
|
}
|
|
88
90
|
catch (error) {
|
|
89
|
-
|
|
91
|
+
this.logger.error('Error processing content:', error);
|
|
90
92
|
return [response.data.markdown, undefined];
|
|
91
93
|
}
|
|
92
94
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firecrawl.cjs","sources":["../../../../src/tools/search/firecrawl.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"firecrawl.cjs","sources":["../../../../src/tools/search/firecrawl.ts"],"sourcesContent":["import axios from 'axios';\nimport { processContent } from './content';\nimport type * as t from './types';\nimport { createDefaultLogger } from './utils';\n\n/**\n * Firecrawl scraper implementation\n * Uses the Firecrawl API to scrape web pages\n */\nexport class FirecrawlScraper {\n private apiKey: string;\n private apiUrl: string;\n private defaultFormats: string[];\n private timeout: number;\n private logger: t.Logger;\n\n constructor(config: t.FirecrawlScraperConfig = {}) {\n this.apiKey = config.apiKey ?? process.env.FIRECRAWL_API_KEY ?? '';\n\n const baseUrl =\n config.apiUrl ??\n process.env.FIRECRAWL_BASE_URL ??\n 'https://api.firecrawl.dev';\n this.apiUrl = `${baseUrl.replace(/\\/+$/, '')}/v1/scrape`;\n\n this.defaultFormats = config.formats ?? ['markdown', 'html'];\n this.timeout = config.timeout ?? 15000;\n\n this.logger = config.logger || createDefaultLogger();\n\n if (!this.apiKey) {\n this.logger.warn('FIRECRAWL_API_KEY is not set. Scraping will not work.');\n }\n\n this.logger.debug(\n `Firecrawl scraper initialized with API URL: ${this.apiUrl}`\n );\n }\n\n /**\n * Scrape a single URL\n * @param url URL to scrape\n * @param options Scrape options\n * @returns Scrape response\n */\n async scrapeUrl(\n url: string,\n options: t.FirecrawlScrapeOptions = {}\n ): Promise<[string, t.FirecrawlScrapeResponse]> {\n if (!this.apiKey) {\n return [\n url,\n {\n success: false,\n error: 'FIRECRAWL_API_KEY is not set',\n },\n ];\n }\n\n try {\n const response = await axios.post(\n this.apiUrl,\n {\n url,\n formats: options.formats || this.defaultFormats,\n includeTags: options.includeTags,\n excludeTags: options.excludeTags,\n headers: options.headers,\n waitFor: options.waitFor,\n timeout: options.timeout ?? this.timeout,\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n timeout: this.timeout,\n }\n );\n\n return [url, response.data];\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return [\n url,\n {\n success: false,\n error: `Firecrawl API request failed: ${errorMessage}`,\n },\n ];\n }\n }\n\n /**\n * Extract content from scrape response\n * @param response Scrape response\n * @returns Extracted content or empty string if not available\n */\n extractContent(\n response: t.FirecrawlScrapeResponse\n ): [string, undefined | t.References] {\n if (!response.success || !response.data) {\n return ['', undefined];\n }\n\n if (response.data.markdown != null && response.data.html != null) {\n try {\n const { markdown, ...rest } = processContent(\n response.data.html,\n response.data.markdown\n );\n return [markdown, rest];\n } catch (error) {\n this.logger.error('Error processing content:', error);\n return [response.data.markdown, undefined];\n }\n } else if (response.data.markdown != null) {\n return [response.data.markdown, undefined];\n }\n\n // Fall back to HTML content\n if (response.data.html != null) {\n return [response.data.html, undefined];\n }\n\n // Fall back to raw HTML content\n if (response.data.rawHtml != null) {\n return [response.data.rawHtml, undefined];\n }\n\n return ['', undefined];\n }\n\n /**\n * Extract metadata from scrape response\n * @param response Scrape response\n * @returns Metadata object\n */\n extractMetadata(response: t.FirecrawlScrapeResponse): t.ScrapeMetadata {\n if (!response.success || !response.data || !response.data.metadata) {\n return {};\n }\n\n return response.data.metadata;\n }\n}\n\n/**\n * Create a Firecrawl scraper instance\n * @param config Scraper configuration\n * @returns Firecrawl scraper instance\n */\nexport const createFirecrawlScraper = (\n config: t.FirecrawlScraperConfig = {}\n): FirecrawlScraper => {\n return new FirecrawlScraper(config);\n};\n"],"names":["createDefaultLogger","processContent"],"mappings":"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"}
|
|
@@ -2,10 +2,92 @@
|
|
|
2
2
|
|
|
3
3
|
var utils = require('./utils.cjs');
|
|
4
4
|
|
|
5
|
+
function addHighlightSection() {
|
|
6
|
+
return ['\n## Highlights', ''];
|
|
7
|
+
}
|
|
8
|
+
// Helper function to format a source (organic or top story)
|
|
9
|
+
function formatSource(source, index, turn, sourceType, references) {
|
|
10
|
+
/** Array of all lines to include in the output */
|
|
11
|
+
const outputLines = [];
|
|
12
|
+
// Add the title
|
|
13
|
+
outputLines.push(`# ${sourceType.charAt(0).toUpperCase() + sourceType.slice(1)} ${index}: ${source.title != null && source.title ? `"${source.title}"` : '(no title)'}`);
|
|
14
|
+
outputLines.push(`\nAnchor: \\ue202turn${turn}${sourceType}${index}`);
|
|
15
|
+
outputLines.push(`URL: ${source.link}`);
|
|
16
|
+
// Add optional fields
|
|
17
|
+
if ('snippet' in source && source.snippet != null) {
|
|
18
|
+
outputLines.push(`Summary: ${source.snippet}`);
|
|
19
|
+
}
|
|
20
|
+
if (source.date != null) {
|
|
21
|
+
outputLines.push(`Date: ${source.date}`);
|
|
22
|
+
}
|
|
23
|
+
if (source.attribution != null) {
|
|
24
|
+
outputLines.push(`Source: ${source.attribution}`);
|
|
25
|
+
}
|
|
26
|
+
// Add highlight section or empty line
|
|
27
|
+
if ((source.highlights?.length ?? 0) > 0) {
|
|
28
|
+
outputLines.push(...addHighlightSection());
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
outputLines.push('');
|
|
32
|
+
}
|
|
33
|
+
// Process highlights if they exist
|
|
34
|
+
(source.highlights ?? [])
|
|
35
|
+
.filter((h) => h.text.trim().length > 0)
|
|
36
|
+
.forEach((h, hIndex) => {
|
|
37
|
+
outputLines.push(`### Highlight ${hIndex + 1} [Relevance: ${h.score.toFixed(2)}]`);
|
|
38
|
+
outputLines.push('');
|
|
39
|
+
outputLines.push('```text');
|
|
40
|
+
outputLines.push(h.text.trim());
|
|
41
|
+
outputLines.push('```');
|
|
42
|
+
outputLines.push('');
|
|
43
|
+
if (h.references != null && h.references.length) {
|
|
44
|
+
let hasHeader = false;
|
|
45
|
+
const refLines = [];
|
|
46
|
+
for (let j = 0; j < h.references.length; j++) {
|
|
47
|
+
const ref = h.references[j];
|
|
48
|
+
if (ref.reference.originalUrl.includes('mailto:')) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
references.push({
|
|
52
|
+
type: ref.type,
|
|
53
|
+
link: ref.reference.originalUrl,
|
|
54
|
+
attribution: utils.getDomainName(ref.reference.originalUrl),
|
|
55
|
+
title: (((ref.reference.title ?? '') || ref.reference.text) ??
|
|
56
|
+
'').split('\n')[0],
|
|
57
|
+
});
|
|
58
|
+
if (ref.type !== 'link') {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (utils.fileExtRegex.test(ref.reference.originalUrl)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (!hasHeader) {
|
|
65
|
+
refLines.push('Core References:');
|
|
66
|
+
hasHeader = true;
|
|
67
|
+
}
|
|
68
|
+
refLines.push(`- ${ref.type}#${ref.originalIndex + 1}: ${ref.reference.originalUrl}`);
|
|
69
|
+
refLines.push(`\t- Anchor: \\ue202turn${turn}ref${references.length - 1}`);
|
|
70
|
+
}
|
|
71
|
+
if (hasHeader) {
|
|
72
|
+
outputLines.push(...refLines);
|
|
73
|
+
outputLines.push('');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (hIndex < (source.highlights?.length ?? 0) - 1) {
|
|
77
|
+
outputLines.push('---');
|
|
78
|
+
outputLines.push('');
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
outputLines.push('');
|
|
82
|
+
return outputLines.join('\n');
|
|
83
|
+
}
|
|
5
84
|
function formatResultsForLLM(turn, results) {
|
|
6
|
-
|
|
85
|
+
/** Array to collect all output lines */
|
|
86
|
+
const outputLines = [];
|
|
7
87
|
const addSection = (title) => {
|
|
8
|
-
|
|
88
|
+
outputLines.push('');
|
|
89
|
+
outputLines.push(`=== ${title} ===`);
|
|
90
|
+
outputLines.push('');
|
|
9
91
|
};
|
|
10
92
|
const references = [];
|
|
11
93
|
// Organic (web) results
|
|
@@ -13,82 +95,38 @@ function formatResultsForLLM(turn, results) {
|
|
|
13
95
|
addSection(`Web Results, Turn ${turn}`);
|
|
14
96
|
for (let i = 0; i < results.organic.length; i++) {
|
|
15
97
|
const r = results.organic[i];
|
|
16
|
-
|
|
17
|
-
`# Source ${i}: "${r.title ?? '(no title)'}"`,
|
|
18
|
-
`Anchor: \\ue202turn${turn}search${i}`,
|
|
19
|
-
`URL: ${r.link}`,
|
|
20
|
-
r.snippet != null ? `Summary: ${r.snippet}` : '',
|
|
21
|
-
r.date != null ? `Date: ${r.date}` : '',
|
|
22
|
-
r.attribution != null ? `Source: ${r.attribution}` : '',
|
|
23
|
-
'',
|
|
24
|
-
'\n## Highlights\n\n',
|
|
25
|
-
'',
|
|
26
|
-
'',
|
|
27
|
-
]
|
|
28
|
-
.filter(Boolean)
|
|
29
|
-
.join('\n');
|
|
30
|
-
(r.highlights ?? [])
|
|
31
|
-
.filter((h) => h.text.trim().length > 0)
|
|
32
|
-
.forEach((h, hIndex) => {
|
|
33
|
-
output += `### Highlight ${hIndex + 1} [Relevance: ${h.score.toFixed(2)}]\n\n`;
|
|
34
|
-
output += '```text\n' + h.text.trim() + '\n```\n\n';
|
|
35
|
-
if (h.references != null && h.references.length) {
|
|
36
|
-
output += 'Core References:\n';
|
|
37
|
-
output += h.references
|
|
38
|
-
.map((ref) => {
|
|
39
|
-
references.push({
|
|
40
|
-
link: ref.reference.originalUrl,
|
|
41
|
-
attribution: utils.getDomainName(ref.reference.originalUrl),
|
|
42
|
-
title: (((ref.reference.title ?? '') || ref.reference.text) ??
|
|
43
|
-
'').split('\n')[0],
|
|
44
|
-
});
|
|
45
|
-
return `- ${ref.type}#${ref.originalIndex + 1}: ${ref.reference.originalUrl}\n\t- Anchor: \\ue202turn${turn}ref${references.length - 1}`;
|
|
46
|
-
})
|
|
47
|
-
.join('\n');
|
|
48
|
-
output += '\n\n';
|
|
49
|
-
}
|
|
50
|
-
if (hIndex < (r.highlights?.length ?? 0) - 1) {
|
|
51
|
-
output += '---\n\n';
|
|
52
|
-
}
|
|
53
|
-
});
|
|
98
|
+
outputLines.push(formatSource(r, i, turn, 'search', references));
|
|
54
99
|
delete results.organic[i].highlights;
|
|
55
|
-
output += '\n';
|
|
56
100
|
}
|
|
57
101
|
}
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// r.attribution != null ? `Source: ${r.attribution}` : '',
|
|
71
|
-
// ''
|
|
72
|
-
// ].filter(Boolean).join('\n');
|
|
73
|
-
// });
|
|
74
|
-
// }
|
|
102
|
+
// Top stories (news)
|
|
103
|
+
const topStories = results.topStories ?? [];
|
|
104
|
+
if (topStories.length) {
|
|
105
|
+
addSection('News Results');
|
|
106
|
+
for (let i = 0; i < topStories.length; i++) {
|
|
107
|
+
const r = topStories[i];
|
|
108
|
+
outputLines.push(formatSource(r, i, turn, 'news', references));
|
|
109
|
+
if (results.topStories?.[i]?.highlights) {
|
|
110
|
+
delete results.topStories[i].highlights;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
75
114
|
// // Images
|
|
76
115
|
// const images = results.images ?? [];
|
|
77
116
|
// if (images.length) {
|
|
78
117
|
// addSection('Image Results');
|
|
79
|
-
// images.
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// });
|
|
118
|
+
// const imageLines = images.map((img, i) => [
|
|
119
|
+
// `Anchor: \ue202turn0image${i}`,
|
|
120
|
+
// `Title: ${img.title ?? '(no title)'}`,
|
|
121
|
+
// `Image URL: ${img.imageUrl}`,
|
|
122
|
+
// ''
|
|
123
|
+
// ].join('\n'));
|
|
124
|
+
// outputLines.push(imageLines.join('\n'));
|
|
87
125
|
// }
|
|
88
126
|
// Knowledge Graph
|
|
89
127
|
if (results.knowledgeGraph != null) {
|
|
90
128
|
addSection('Knowledge Graph');
|
|
91
|
-
|
|
129
|
+
const kgLines = [
|
|
92
130
|
`**Title:** ${results.knowledgeGraph.title ?? '(no title)'}`,
|
|
93
131
|
results.knowledgeGraph.type != null
|
|
94
132
|
? `**Type:** ${results.knowledgeGraph.type}`
|
|
@@ -112,14 +150,13 @@ function formatResultsForLLM(turn, results) {
|
|
|
112
150
|
? `**Attributes:**\n\`\`\`json\n${JSON.stringify(results.knowledgeGraph.attributes, null, 2)}\n\`\`\``
|
|
113
151
|
: '',
|
|
114
152
|
'',
|
|
115
|
-
]
|
|
116
|
-
|
|
117
|
-
.join('\n\n');
|
|
153
|
+
].filter(Boolean);
|
|
154
|
+
outputLines.push(kgLines.join('\n\n'));
|
|
118
155
|
}
|
|
119
156
|
// Answer Box
|
|
120
157
|
if (results.answerBox != null) {
|
|
121
158
|
addSection('Answer Box');
|
|
122
|
-
|
|
159
|
+
const abLines = [
|
|
123
160
|
results.answerBox.title != null
|
|
124
161
|
? `**Title:** ${results.answerBox.title}`
|
|
125
162
|
: '',
|
|
@@ -135,29 +172,29 @@ function formatResultsForLLM(turn, results) {
|
|
|
135
172
|
? `**Link:** ${results.answerBox.link}`
|
|
136
173
|
: '',
|
|
137
174
|
'',
|
|
138
|
-
]
|
|
139
|
-
|
|
140
|
-
.join('\n\n');
|
|
175
|
+
].filter(Boolean);
|
|
176
|
+
outputLines.push(abLines.join('\n\n'));
|
|
141
177
|
}
|
|
142
178
|
// People also ask
|
|
143
179
|
const peopleAlsoAsk = results.peopleAlsoAsk ?? [];
|
|
144
180
|
if (peopleAlsoAsk.length) {
|
|
145
181
|
addSection('People Also Ask');
|
|
182
|
+
const paaLines = [];
|
|
146
183
|
peopleAlsoAsk.forEach((p, i) => {
|
|
147
|
-
|
|
184
|
+
const questionLines = [
|
|
148
185
|
`### Question ${i + 1}:`,
|
|
149
186
|
`"${p.question}"`,
|
|
150
|
-
`${p.snippet != null && p.snippet ? `Snippet: ${p.snippet}
|
|
187
|
+
`${p.snippet != null && p.snippet ? `Snippet: ${p.snippet}` : ''}`,
|
|
151
188
|
`${p.title != null && p.title ? `Title: ${p.title}` : ''}`,
|
|
152
189
|
`${p.link != null && p.link ? `Link: ${p.link}` : ''}`,
|
|
153
190
|
'',
|
|
154
|
-
]
|
|
155
|
-
|
|
156
|
-
.join('\n\n');
|
|
191
|
+
].filter(Boolean);
|
|
192
|
+
paaLines.push(questionLines.join('\n\n'));
|
|
157
193
|
});
|
|
194
|
+
outputLines.push(paaLines.join(''));
|
|
158
195
|
}
|
|
159
196
|
return {
|
|
160
|
-
output:
|
|
197
|
+
output: outputLines.join('\n').trim(),
|
|
161
198
|
references,
|
|
162
199
|
};
|
|
163
200
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.cjs","sources":["../../../../src/tools/search/format.ts"],"sourcesContent":["import type * as t from './types';\nimport { getDomainName } from './utils';\n\nexport function formatResultsForLLM(\n turn: number,\n results: t.SearchResultData\n): { output: string; references: t.ResultReference[] } {\n let output = '';\n\n const addSection = (title: string): void => {\n output += `\\n=== ${title} ===\\n`;\n };\n\n const references: t.ResultReference[] = [];\n // Organic (web) results\n if (results.organic?.length != null && results.organic.length > 0) {\n addSection(`Web Results, Turn ${turn}`);\n for (let i = 0; i < results.organic.length; i++) {\n const r = results.organic[i];\n output += [\n `# Source ${i}: \"${r.title ?? '(no title)'}\"`,\n `Anchor: \\\\ue202turn${turn}search${i}`,\n `URL: ${r.link}`,\n r.snippet != null ? `Summary: ${r.snippet}` : '',\n r.date != null ? `Date: ${r.date}` : '',\n r.attribution != null ? `Source: ${r.attribution}` : '',\n '',\n '\\n## Highlights\\n\\n',\n '',\n '',\n ]\n .filter(Boolean)\n .join('\\n');\n\n (r.highlights ?? [])\n .filter((h) => h.text.trim().length > 0)\n .forEach((h, hIndex) => {\n output += `### Highlight ${hIndex + 1} [Relevance: ${h.score.toFixed(2)}]\\n\\n`;\n output += '```text\\n' + h.text.trim() + '\\n```\\n\\n';\n\n if (h.references != null && h.references.length) {\n output += 'Core References:\\n';\n output += h.references\n .map((ref) => {\n references.push({\n link: ref.reference.originalUrl,\n attribution: getDomainName(ref.reference.originalUrl),\n title: (\n ((ref.reference.title ?? '') || ref.reference.text) ??\n ''\n ).split('\\n')[0],\n });\n return `- ${ref.type}#${ref.originalIndex + 1}: ${ref.reference.originalUrl}\\n\\t- Anchor: \\\\ue202turn${turn}ref${references.length - 1}`;\n })\n .join('\\n');\n output += '\\n\\n';\n }\n\n if (hIndex < (r.highlights?.length ?? 0) - 1) {\n output += '---\\n\\n';\n }\n });\n\n delete results.organic[i].highlights;\n output += '\\n';\n }\n }\n\n // Ignoring these sections for now\n // // Top stories (news)\n // const topStores = results.topStories ?? [];\n // if (topStores.length) {\n // addSection('News Results');\n // topStores.forEach((r, i) => {\n // output += [\n // `Anchor: \\ue202turn0news${i}`,\n // `Title: ${r.title ?? '(no title)'}`,\n // `URL: ${r.link}`,\n // r.snippet != null ? `Snippet: ${r.snippet}` : '',\n // r.date != null ? `Date: ${r.date}` : '',\n // r.attribution != null ? `Source: ${r.attribution}` : '',\n // ''\n // ].filter(Boolean).join('\\n');\n // });\n // }\n\n // // Images\n // const images = results.images ?? [];\n // if (images.length) {\n // addSection('Image Results');\n // images.forEach((img, i) => {\n // output += [\n // `Anchor: \\ue202turn0image${i}`,\n // `Title: ${img.title ?? '(no title)'}`,\n // `Image URL: ${img.imageUrl}`,\n // ''\n // ].join('\\n');\n // });\n // }\n\n // Knowledge Graph\n if (results.knowledgeGraph != null) {\n addSection('Knowledge Graph');\n output += [\n `**Title:** ${results.knowledgeGraph.title ?? '(no title)'}`,\n results.knowledgeGraph.type != null\n ? `**Type:** ${results.knowledgeGraph.type}`\n : '',\n results.knowledgeGraph.description != null\n ? `**Description:** ${results.knowledgeGraph.description}`\n : '',\n results.knowledgeGraph.descriptionSource != null\n ? `**Description Source:** ${results.knowledgeGraph.descriptionSource}`\n : '',\n results.knowledgeGraph.descriptionLink != null\n ? `**Description Link:** ${results.knowledgeGraph.descriptionLink}`\n : '',\n results.knowledgeGraph.imageUrl != null\n ? `**Image URL:** ${results.knowledgeGraph.imageUrl}`\n : '',\n results.knowledgeGraph.website != null\n ? `**Website:** ${results.knowledgeGraph.website}`\n : '',\n results.knowledgeGraph.attributes != null\n ? `**Attributes:**\\n\\`\\`\\`json\\n${JSON.stringify(\n results.knowledgeGraph.attributes,\n null,\n 2\n )}\\n\\`\\`\\``\n : '',\n '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n }\n\n // Answer Box\n if (results.answerBox != null) {\n addSection('Answer Box');\n output += [\n results.answerBox.title != null\n ? `**Title:** ${results.answerBox.title}`\n : '',\n results.answerBox.snippet != null\n ? `**Snippet:** ${results.answerBox.snippet}`\n : '',\n results.answerBox.snippetHighlighted != null\n ? `**Snippet Highlighted:** ${results.answerBox.snippetHighlighted\n .map((s) => `\\`${s}\\``)\n .join(' ')}`\n : '',\n results.answerBox.link != null\n ? `**Link:** ${results.answerBox.link}`\n : '',\n '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n }\n\n // People also ask\n const peopleAlsoAsk = results.peopleAlsoAsk ?? [];\n if (peopleAlsoAsk.length) {\n addSection('People Also Ask');\n peopleAlsoAsk.forEach((p, i) => {\n output += [\n `### Question ${i + 1}:`,\n `\"${p.question}\"`,\n `${p.snippet != null && p.snippet ? `Snippet: ${p.snippet}}` : ''}`,\n `${p.title != null && p.title ? `Title: ${p.title}` : ''}`,\n `${p.link != null && p.link ? `Link: ${p.link}` : ''}`,\n '',\n ]\n .filter(Boolean)\n .join('\\n\\n');\n });\n }\n return {\n output: output.trim(),\n references,\n };\n}\n"],"names":["getDomainName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"format.cjs","sources":["../../../../src/tools/search/format.ts"],"sourcesContent":["import type * as t from './types';\nimport { getDomainName, fileExtRegex } from './utils';\n\nfunction addHighlightSection(): string[] {\n return ['\\n## Highlights', ''];\n}\n\n// Helper function to format a source (organic or top story)\nfunction formatSource(\n source: t.ValidSource,\n index: number,\n turn: number,\n sourceType: 'search' | 'news',\n references: t.ResultReference[]\n): string {\n /** Array of all lines to include in the output */\n const outputLines: string[] = [];\n\n // Add the title\n outputLines.push(\n `# ${sourceType.charAt(0).toUpperCase() + sourceType.slice(1)} ${index}: ${source.title != null && source.title ? `\"${source.title}\"` : '(no title)'}`\n );\n outputLines.push(`\\nAnchor: \\\\ue202turn${turn}${sourceType}${index}`);\n outputLines.push(`URL: ${source.link}`);\n\n // Add optional fields\n if ('snippet' in source && source.snippet != null) {\n outputLines.push(`Summary: ${source.snippet}`);\n }\n\n if (source.date != null) {\n outputLines.push(`Date: ${source.date}`);\n }\n\n if (source.attribution != null) {\n outputLines.push(`Source: ${source.attribution}`);\n }\n\n // Add highlight section or empty line\n if ((source.highlights?.length ?? 0) > 0) {\n outputLines.push(...addHighlightSection());\n } else {\n outputLines.push('');\n }\n\n // Process highlights if they exist\n (source.highlights ?? [])\n .filter((h) => h.text.trim().length > 0)\n .forEach((h, hIndex) => {\n outputLines.push(\n `### Highlight ${hIndex + 1} [Relevance: ${h.score.toFixed(2)}]`\n );\n outputLines.push('');\n outputLines.push('```text');\n outputLines.push(h.text.trim());\n outputLines.push('```');\n outputLines.push('');\n\n if (h.references != null && h.references.length) {\n let hasHeader = false;\n const refLines: string[] = [];\n\n for (let j = 0; j < h.references.length; j++) {\n const ref = h.references[j];\n if (ref.reference.originalUrl.includes('mailto:')) {\n continue;\n }\n references.push({\n type: ref.type,\n link: ref.reference.originalUrl,\n attribution: getDomainName(ref.reference.originalUrl),\n title: (\n ((ref.reference.title ?? '') || ref.reference.text) ??\n ''\n ).split('\\n')[0],\n });\n\n if (ref.type !== 'link') {\n continue;\n }\n\n if (fileExtRegex.test(ref.reference.originalUrl)) {\n continue;\n }\n\n if (!hasHeader) {\n refLines.push('Core References:');\n hasHeader = true;\n }\n\n refLines.push(\n `- ${ref.type}#${ref.originalIndex + 1}: ${ref.reference.originalUrl}`\n );\n refLines.push(\n `\\t- Anchor: \\\\ue202turn${turn}ref${references.length - 1}`\n );\n }\n\n if (hasHeader) {\n outputLines.push(...refLines);\n outputLines.push('');\n }\n }\n\n if (hIndex < (source.highlights?.length ?? 0) - 1) {\n outputLines.push('---');\n outputLines.push('');\n }\n });\n\n outputLines.push('');\n return outputLines.join('\\n');\n}\n\nexport function formatResultsForLLM(\n turn: number,\n results: t.SearchResultData\n): { output: string; references: t.ResultReference[] } {\n /** Array to collect all output lines */\n const outputLines: string[] = [];\n\n const addSection = (title: string): void => {\n outputLines.push('');\n outputLines.push(`=== ${title} ===`);\n outputLines.push('');\n };\n\n const references: t.ResultReference[] = [];\n\n // Organic (web) results\n if (results.organic?.length != null && results.organic.length > 0) {\n addSection(`Web Results, Turn ${turn}`);\n for (let i = 0; i < results.organic.length; i++) {\n const r = results.organic[i];\n outputLines.push(formatSource(r, i, turn, 'search', references));\n delete results.organic[i].highlights;\n }\n }\n\n // Top stories (news)\n const topStories = results.topStories ?? [];\n if (topStories.length) {\n addSection('News Results');\n for (let i = 0; i < topStories.length; i++) {\n const r = topStories[i];\n outputLines.push(formatSource(r, i, turn, 'news', references));\n if (results.topStories?.[i]?.highlights) {\n delete results.topStories[i].highlights;\n }\n }\n }\n\n // // Images\n // const images = results.images ?? [];\n // if (images.length) {\n // addSection('Image Results');\n // const imageLines = images.map((img, i) => [\n // `Anchor: \\ue202turn0image${i}`,\n // `Title: ${img.title ?? '(no title)'}`,\n // `Image URL: ${img.imageUrl}`,\n // ''\n // ].join('\\n'));\n // outputLines.push(imageLines.join('\\n'));\n // }\n\n // Knowledge Graph\n if (results.knowledgeGraph != null) {\n addSection('Knowledge Graph');\n const kgLines = [\n `**Title:** ${results.knowledgeGraph.title ?? '(no title)'}`,\n results.knowledgeGraph.type != null\n ? `**Type:** ${results.knowledgeGraph.type}`\n : '',\n results.knowledgeGraph.description != null\n ? `**Description:** ${results.knowledgeGraph.description}`\n : '',\n results.knowledgeGraph.descriptionSource != null\n ? `**Description Source:** ${results.knowledgeGraph.descriptionSource}`\n : '',\n results.knowledgeGraph.descriptionLink != null\n ? `**Description Link:** ${results.knowledgeGraph.descriptionLink}`\n : '',\n results.knowledgeGraph.imageUrl != null\n ? `**Image URL:** ${results.knowledgeGraph.imageUrl}`\n : '',\n results.knowledgeGraph.website != null\n ? `**Website:** ${results.knowledgeGraph.website}`\n : '',\n results.knowledgeGraph.attributes != null\n ? `**Attributes:**\\n\\`\\`\\`json\\n${JSON.stringify(\n results.knowledgeGraph.attributes,\n null,\n 2\n )}\\n\\`\\`\\``\n : '',\n '',\n ].filter(Boolean);\n\n outputLines.push(kgLines.join('\\n\\n'));\n }\n\n // Answer Box\n if (results.answerBox != null) {\n addSection('Answer Box');\n const abLines = [\n results.answerBox.title != null\n ? `**Title:** ${results.answerBox.title}`\n : '',\n results.answerBox.snippet != null\n ? `**Snippet:** ${results.answerBox.snippet}`\n : '',\n results.answerBox.snippetHighlighted != null\n ? `**Snippet Highlighted:** ${results.answerBox.snippetHighlighted\n .map((s) => `\\`${s}\\``)\n .join(' ')}`\n : '',\n results.answerBox.link != null\n ? `**Link:** ${results.answerBox.link}`\n : '',\n '',\n ].filter(Boolean);\n\n outputLines.push(abLines.join('\\n\\n'));\n }\n\n // People also ask\n const peopleAlsoAsk = results.peopleAlsoAsk ?? [];\n if (peopleAlsoAsk.length) {\n addSection('People Also Ask');\n\n const paaLines: string[] = [];\n peopleAlsoAsk.forEach((p, i) => {\n const questionLines = [\n `### Question ${i + 1}:`,\n `\"${p.question}\"`,\n `${p.snippet != null && p.snippet ? `Snippet: ${p.snippet}` : ''}`,\n `${p.title != null && p.title ? `Title: ${p.title}` : ''}`,\n `${p.link != null && p.link ? `Link: ${p.link}` : ''}`,\n '',\n ].filter(Boolean);\n\n paaLines.push(questionLines.join('\\n\\n'));\n });\n\n outputLines.push(paaLines.join(''));\n }\n\n return {\n output: outputLines.join('\\n').trim(),\n references,\n };\n}\n"],"names":["getDomainName","fileExtRegex"],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var axios = require('axios');
|
|
4
|
+
var utils = require('./utils.cjs');
|
|
4
5
|
|
|
5
|
-
/* eslint-disable no-console */
|
|
6
6
|
class BaseReranker {
|
|
7
7
|
apiKey;
|
|
8
|
-
|
|
8
|
+
logger;
|
|
9
|
+
constructor(logger) {
|
|
9
10
|
// Each specific reranker will set its API key
|
|
11
|
+
this.logger = logger || utils.createDefaultLogger();
|
|
10
12
|
}
|
|
11
13
|
getDefaultRanking(documents, topK) {
|
|
12
14
|
return documents
|
|
@@ -14,22 +16,22 @@ class BaseReranker {
|
|
|
14
16
|
.map((doc) => ({ text: doc, score: 0 }));
|
|
15
17
|
}
|
|
16
18
|
logDocumentSamples(documents) {
|
|
17
|
-
|
|
19
|
+
this.logger.debug('Sample documents being sent to API:');
|
|
18
20
|
for (let i = 0; i < Math.min(3, documents.length); i++) {
|
|
19
|
-
|
|
21
|
+
this.logger.debug(`Document ${i}: ${documents[i].substring(0, 100)}...`);
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
class JinaReranker extends BaseReranker {
|
|
24
|
-
constructor({ apiKey = process.env.JINA_API_KEY }) {
|
|
25
|
-
super();
|
|
26
|
+
constructor({ apiKey = process.env.JINA_API_KEY, logger, }) {
|
|
27
|
+
super(logger);
|
|
26
28
|
this.apiKey = apiKey;
|
|
27
29
|
}
|
|
28
30
|
async rerank(query, documents, topK = 5) {
|
|
29
|
-
|
|
31
|
+
this.logger.debug(`Reranking ${documents.length} documents with Jina`);
|
|
30
32
|
try {
|
|
31
33
|
if (this.apiKey == null || this.apiKey === '') {
|
|
32
|
-
|
|
34
|
+
this.logger.warn('JINA_API_KEY is not set. Using default ranking.');
|
|
33
35
|
return this.getDefaultRanking(documents, topK);
|
|
34
36
|
}
|
|
35
37
|
this.logDocumentSamples(documents);
|
|
@@ -47,13 +49,13 @@ class JinaReranker extends BaseReranker {
|
|
|
47
49
|
},
|
|
48
50
|
});
|
|
49
51
|
// Log the response data structure
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
this.logger.debug('Jina API response structure:');
|
|
53
|
+
this.logger.debug('Model:', response.data?.model);
|
|
54
|
+
this.logger.debug('Usage:', response.data?.usage);
|
|
55
|
+
this.logger.debug('Results count:', response.data?.results.length);
|
|
54
56
|
// Log a sample of the results
|
|
55
57
|
if ((response.data?.results.length ?? 0) > 0) {
|
|
56
|
-
|
|
58
|
+
this.logger.debug('Sample result:', JSON.stringify(response.data?.results[0], null, 2));
|
|
57
59
|
}
|
|
58
60
|
if (response.data && response.data.results.length) {
|
|
59
61
|
return response.data.results.map((result) => {
|
|
@@ -78,27 +80,27 @@ class JinaReranker extends BaseReranker {
|
|
|
78
80
|
});
|
|
79
81
|
}
|
|
80
82
|
else {
|
|
81
|
-
|
|
83
|
+
this.logger.warn('Unexpected response format from Jina API. Using default ranking.');
|
|
82
84
|
return this.getDefaultRanking(documents, topK);
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
catch (error) {
|
|
86
|
-
|
|
88
|
+
this.logger.error('Error using Jina reranker:', error);
|
|
87
89
|
// Fallback to default ranking on error
|
|
88
90
|
return this.getDefaultRanking(documents, topK);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
class CohereReranker extends BaseReranker {
|
|
93
|
-
constructor({ apiKey = process.env.COHERE_API_KEY }) {
|
|
94
|
-
super();
|
|
95
|
+
constructor({ apiKey = process.env.COHERE_API_KEY, logger, }) {
|
|
96
|
+
super(logger);
|
|
95
97
|
this.apiKey = apiKey;
|
|
96
98
|
}
|
|
97
99
|
async rerank(query, documents, topK = 5) {
|
|
98
|
-
|
|
100
|
+
this.logger.debug(`Reranking ${documents.length} documents with Cohere`);
|
|
99
101
|
try {
|
|
100
102
|
if (this.apiKey == null || this.apiKey === '') {
|
|
101
|
-
|
|
103
|
+
this.logger.warn('COHERE_API_KEY is not set. Using default ranking.');
|
|
102
104
|
return this.getDefaultRanking(documents, topK);
|
|
103
105
|
}
|
|
104
106
|
this.logDocumentSamples(documents);
|
|
@@ -115,13 +117,13 @@ class CohereReranker extends BaseReranker {
|
|
|
115
117
|
},
|
|
116
118
|
});
|
|
117
119
|
// Log the response data structure
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
this.logger.debug('Cohere API response structure:');
|
|
121
|
+
this.logger.debug('ID:', response.data?.id);
|
|
122
|
+
this.logger.debug('Meta:', response.data?.meta);
|
|
123
|
+
this.logger.debug('Results count:', response.data?.results.length);
|
|
122
124
|
// Log a sample of the results
|
|
123
125
|
if ((response.data?.results.length ?? 0) > 0) {
|
|
124
|
-
|
|
126
|
+
this.logger.debug('Sample result:', JSON.stringify(response.data?.results[0], null, 2));
|
|
125
127
|
}
|
|
126
128
|
if (response.data && response.data.results.length) {
|
|
127
129
|
return response.data.results.map((result) => {
|
|
@@ -132,24 +134,24 @@ class CohereReranker extends BaseReranker {
|
|
|
132
134
|
});
|
|
133
135
|
}
|
|
134
136
|
else {
|
|
135
|
-
|
|
137
|
+
this.logger.warn('Unexpected response format from Cohere API. Using default ranking.');
|
|
136
138
|
return this.getDefaultRanking(documents, topK);
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
catch (error) {
|
|
140
|
-
|
|
142
|
+
this.logger.error('Error using Cohere reranker:', error);
|
|
141
143
|
// Fallback to default ranking on error
|
|
142
144
|
return this.getDefaultRanking(documents, topK);
|
|
143
145
|
}
|
|
144
146
|
}
|
|
145
147
|
}
|
|
146
148
|
class InfinityReranker extends BaseReranker {
|
|
147
|
-
constructor() {
|
|
148
|
-
super();
|
|
149
|
+
constructor(logger) {
|
|
150
|
+
super(logger);
|
|
149
151
|
// No API key needed for the placeholder implementation
|
|
150
152
|
}
|
|
151
153
|
async rerank(query, documents, topK = 5) {
|
|
152
|
-
|
|
154
|
+
this.logger.debug(`Reranking ${documents.length} documents with Infinity (placeholder)`);
|
|
153
155
|
// This would be replaced with actual Infinity reranker implementation
|
|
154
156
|
return this.getDefaultRanking(documents, topK);
|
|
155
157
|
}
|
|
@@ -158,20 +160,25 @@ class InfinityReranker extends BaseReranker {
|
|
|
158
160
|
* Creates the appropriate reranker based on type and configuration
|
|
159
161
|
*/
|
|
160
162
|
const createReranker = (config) => {
|
|
161
|
-
const { rerankerType, jinaApiKey, cohereApiKey } = config;
|
|
163
|
+
const { rerankerType, jinaApiKey, cohereApiKey, logger } = config;
|
|
164
|
+
// Create a default logger if none is provided
|
|
165
|
+
const defaultLogger = logger || utils.createDefaultLogger();
|
|
162
166
|
switch (rerankerType.toLowerCase()) {
|
|
163
167
|
case 'jina':
|
|
164
|
-
return new JinaReranker({ apiKey: jinaApiKey });
|
|
168
|
+
return new JinaReranker({ apiKey: jinaApiKey, logger: defaultLogger });
|
|
165
169
|
case 'cohere':
|
|
166
|
-
return new CohereReranker({
|
|
170
|
+
return new CohereReranker({
|
|
171
|
+
apiKey: cohereApiKey,
|
|
172
|
+
logger: defaultLogger,
|
|
173
|
+
});
|
|
167
174
|
case 'infinity':
|
|
168
|
-
return new InfinityReranker();
|
|
175
|
+
return new InfinityReranker(defaultLogger);
|
|
169
176
|
case 'none':
|
|
170
|
-
|
|
177
|
+
defaultLogger.debug('Skipping reranking as reranker is set to "none"');
|
|
171
178
|
return undefined;
|
|
172
179
|
default:
|
|
173
|
-
|
|
174
|
-
return new JinaReranker({ apiKey: jinaApiKey });
|
|
180
|
+
defaultLogger.warn(`Unknown reranker type: ${rerankerType}. Defaulting to InfinityReranker.`);
|
|
181
|
+
return new JinaReranker({ apiKey: jinaApiKey, logger: defaultLogger });
|
|
175
182
|
}
|
|
176
183
|
};
|
|
177
184
|
// Example usage:
|