/ src / server / tools / web-search / provider-perplexity.ts
provider-perplexity.ts
 1  import process from 'node:process'
 2  
 3  import { safeFetch } from '@/lib/web-core'
 4  import { extractSearchResultsFromText } from '@/server/tools/web-search/normalize'
 5  import type {
 6    WebSearchRequest,
 7    WebSearchResult,
 8  } from '@/server/tools/web-search/types'
 9  
10  export async function performPerplexitySearch(
11    request: WebSearchRequest,
12  ): Promise<WebSearchResult[]> {
13    const apiKey =
14      process.env.PERPLEXITY_API_KEY || process.env.OPENROUTER_API_KEY
15    if (!apiKey) {
16      throw new Error(
17        'PERPLEXITY_API_KEY or OPENROUTER_API_KEY environment variable is not set',
18      )
19    }
20  
21    const response = await safeFetch(
22      'https://api.perplexity.ai/chat/completions',
23      {
24        method: 'POST',
25        headers: {
26          Authorization: `Bearer ${apiKey}`,
27          'Content-Type': 'application/json',
28        },
29        body: JSON.stringify({
30          model: 'sonar-pro',
31          messages: [
32            {
33              role: 'system',
34              content:
35                'You are a helpful assistant. When asked to search, provide search results in a structured format with title, URL, and snippet.',
36            },
37            {
38              role: 'user',
39              content: `Search for: ${request.query}`,
40            },
41          ],
42          max_tokens: 1000,
43        }),
44      },
45    )
46  
47    if (!response.ok) {
48      throw new Error(
49        `Perplexity API error: ${response.status} ${response.statusText}`,
50      )
51    }
52  
53    const data = await response.json()
54    const text = data.choices?.[0]?.message?.content ?? ''
55    return extractSearchResultsFromText(text)
56  }