feat(05-02): exa-search research integration
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
const DEFAULT_EXA_API_URL = 'https://api.exa.ai/search';
|
||||
|
||||
const buildSummary = (results) => {
|
||||
if (!results || results.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const snippets = results
|
||||
.map((result) => result.snippet || result.highlight)
|
||||
.filter(Boolean);
|
||||
|
||||
if (snippets.length === 0) {
|
||||
return results
|
||||
.slice(0, 3)
|
||||
.map((result) => result.title)
|
||||
.filter(Boolean)
|
||||
.join(' · ');
|
||||
}
|
||||
|
||||
return snippets.slice(0, 3).join(' ');
|
||||
};
|
||||
|
||||
const searchExerciseResearch = async ({ query, numResults = 5 }) => {
|
||||
if (!query || typeof query !== 'string') {
|
||||
throw new Error('Query must be a non-empty string');
|
||||
}
|
||||
|
||||
const apiKey = process.env.EXA_API_KEY;
|
||||
if (!apiKey) {
|
||||
throw new Error('EXA_API_KEY is not configured');
|
||||
}
|
||||
|
||||
const apiUrl = process.env.EXA_API_URL || DEFAULT_EXA_API_URL;
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'x-api-key': apiKey
|
||||
},
|
||||
body: JSON.stringify({
|
||||
query,
|
||||
numResults,
|
||||
type: 'neural',
|
||||
useAutoprompt: true
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const text = await response.text();
|
||||
throw new Error(`Exa search failed: ${response.status} ${text}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const results = (data.results || []).map((result) => ({
|
||||
id: result.id,
|
||||
title: result.title,
|
||||
url: result.url,
|
||||
snippet: Array.isArray(result.highlights) && result.highlights.length > 0
|
||||
? result.highlights[0]
|
||||
: result.snippet,
|
||||
highlight: result.highlight,
|
||||
publishedDate: result.publishedDate,
|
||||
score: result.score
|
||||
}));
|
||||
|
||||
return {
|
||||
summary: buildSummary(results),
|
||||
results
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
searchExerciseResearch
|
||||
};
|
||||
Reference in New Issue
Block a user