diff --git a/src/lib/llm/providers/tavily.ts b/src/lib/llm/providers/tavily.ts new file mode 100644 index 0000000..a76d78d --- /dev/null +++ b/src/lib/llm/providers/tavily.ts @@ -0,0 +1,69 @@ +export interface SearchResult { + title: string; + url: string; + content: string; + score: number; +} + +const TAVILY_API_URL = "https://api.tavily.com/search"; + +export async function searchItem( + itemName: string, + context: string +): Promise { + const apiKey = process.env.TAVILY_API_KEY; + if (!apiKey) { + return []; + } + + try { + const query = `${itemName} ${context}`.trim(); + + const response = await fetch(TAVILY_API_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + api_key: apiKey, + query, + max_results: 5, + include_answer: false, + search_depth: "advanced", + }), + }); + + if (!response.ok) { + console.error( + `Tavily API error: ${response.status} ${response.statusText}` + ); + return []; + } + + const data = await response.json(); + + if (!data.results || !Array.isArray(data.results)) { + return []; + } + + return data.results.map( + (result: { + title?: string; + url?: string; + content?: string; + score?: number; + }) => ({ + title: result.title ?? "", + url: result.url ?? "", + content: result.content ?? "", + score: result.score ?? 0, + }) + ); + } catch (error) { + console.error( + `Tavily search failed for "${itemName}":`, + error instanceof Error ? error.message : error + ); + return []; + } +}