/ src / server / tools / web-search / dispatch.ts
dispatch.ts
 1  import process from 'node:process'
 2  
 3  import {
 4    performBraveSearch,
 5  } from '@/server/tools/web-search/provider-brave'
 6  import {
 7    performDuckDuckGoImageSearch,
 8    performDuckDuckGoNewsSearch,
 9    performDuckDuckGoSearch,
10    performDuckDuckGoVideoSearch,
11  } from '@/server/tools/web-search/provider-duckduckgo'
12  import {
13    performGeminiSearch,
14  } from '@/server/tools/web-search/provider-gemini'
15  import {
16    performGrokSearch,
17  } from '@/server/tools/web-search/provider-grok'
18  import {
19    performKimiSearch,
20  } from '@/server/tools/web-search/provider-kimi'
21  import {
22    performOpenRouterSearch,
23  } from '@/server/tools/web-search/provider-openrouter'
24  import {
25    performPerplexitySearch,
26  } from '@/server/tools/web-search/provider-perplexity'
27  import type {
28    WebSearchProvider,
29    WebSearchRequest,
30    WebSearchResult,
31  } from '@/server/tools/web-search/types'
32  
33  export async function dispatchSearchProvider(input: {
34    provider: WebSearchProvider
35    request: WebSearchRequest
36  }): Promise<WebSearchResult[]> {
37    switch (input.provider) {
38      case 'brave':
39        return performBraveSearch(input.request)
40      case 'perplexity':
41        return performPerplexitySearch(input.request)
42      case 'grok':
43        return performGrokSearch(input.request)
44      case 'gemini':
45        return performGeminiSearch(input.request)
46      case 'kimi':
47        return performKimiSearch(input.request)
48      case 'openrouter':
49        return performOpenRouterSearch(input.request)
50      case 'duckduckgo': {
51        const searchType = input.request.searchType ?? 'web'
52        switch (searchType) {
53          case 'image':
54            return performDuckDuckGoImageSearch(input.request)
55          case 'news':
56            return performDuckDuckGoNewsSearch(input.request)
57          case 'video':
58            return performDuckDuckGoVideoSearch(input.request)
59          default:
60            return performDuckDuckGoSearch(input.request)
61        }
62      }
63      default:
64        throw new Error(`Unsupported search provider: ${input.provider}`)
65    }
66  }
67  
68  export function resolveSearchProvider(request: WebSearchRequest): WebSearchProvider {
69    if (request.provider) {
70      return request.provider
71    }
72  
73    const apiKeyPriority: Record<WebSearchProvider, string | undefined> = {
74      brave: process.env.BRAVE_API_KEY,
75      gemini: process.env.GEMINI_API_KEY,
76      kimi: process.env.KIMI_API_KEY || process.env.MOONSHOT_API_KEY,
77      perplexity: process.env.PERPLEXITY_API_KEY,
78      grok: process.env.XAI_API_KEY,
79      openrouter: process.env.OPENROUTER_API_KEY,
80      duckduckgo: undefined,
81    }
82  
83    for (const [provider, apiKey] of Object.entries(apiKeyPriority)) {
84      if (apiKey) {
85        return provider as WebSearchProvider
86      }
87    }
88  
89    return 'duckduckgo'
90  }