import type { ProviderSearchOptions, SearchProviderAdapter } from "./provider.ts"; export interface SearchProviderDefinition { id: string; label: string; load(): Promise; } function define(id: string, label: string, factory: () => Promise): SearchProviderDefinition { let loaded: Promise | undefined; return { id, label, load: () => loaded ??= factory() }; } const definitions: SearchProviderDefinition[] = [ define("openai", "OpenAI", async () => { const provider = await import("../providers/openai/search.ts"); return adapter("openai", "OpenAI", options => provider.isOpenAISearchAvailable(options.extensionContext), (query, options, current) => current ? provider.searchWithCurrentModelOpenAI(query, options, options.extensionContext) : provider.searchWithOpenAI(query, options, options.extensionContext), options => provider.isCurrentModelHostedSearchEligible(options.extensionContext)); }), define("brave", "Brave", async () => { const provider = await import("../providers/brave.ts"); return adapter("brave", "Brave", provider.isBraveAvailable, provider.searchWithBrave); }), define("parallel", "Parallel", async () => { const provider = await import("../providers/parallel.ts"); return adapter("parallel", "Parallel", provider.isParallelAvailable, provider.searchWithParallel); }), define("parallel-mcp", "Parallel MCP", async () => { const provider = await import("../providers/parallel-mcp.ts"); return adapter("parallel-mcp", "Parallel MCP", provider.isParallelMcpAvailable, provider.searchWithParallelMcp); }), define("tinyfish", "TinyFish", async () => { const provider = await import("../providers/tinyfish.ts"); return adapter("tinyfish", "TinyFish", provider.isTinyFishAvailable, provider.searchWithTinyFish); }), define("search1api", "Search1API", async () => { const provider = await import("../providers/search1api.ts"); return adapter("search1api", "Search1API", provider.isSearch1APIAvailable, provider.searchWithSearch1API); }), define("searchinfinity", "Searchinfinity", async () => { const provider = await import("../providers/searchinfinity.ts"); return adapter("searchinfinity", "Searchinfinity", provider.isSearchinfinityAvailable, provider.searchWithSearchinfinity); }), define("querit", "Querit", async () => { const provider = await import("../providers/querit.ts"); return adapter("querit", "Querit", provider.isQueritAvailable, provider.searchWithQuerit); }), define("tavily", "Tavily", async () => { const provider = await import("../providers/tavily.ts"); return adapter("tavily", "Tavily", provider.isTavilyAvailable, provider.searchWithTavily); }), define("firecrawl", "Firecrawl", async () => { const provider = await import("../providers/firecrawl.ts"); return adapter("firecrawl", "Firecrawl", provider.isFirecrawlAvailable, provider.searchWithFirecrawl); }), define("jina", "Jina", async () => { const provider = await import("../providers/jina.ts"); return adapter("jina", "Jina", provider.isJinaSearchAvailable, provider.searchWithJina); }), define("serpdive", "SERPdive", async () => { const provider = await import("../providers/serpdive.ts"); return adapter("serpdive", "SERPdive", provider.isSerpdiveAvailable, provider.searchWithSerpdive); }), define("kagi", "Kagi", async () => { const provider = await import("../providers/kagi.ts"); return adapter("kagi", "Kagi", provider.isKagiAvailable, provider.searchWithKagi); }), define("bocha", "Bocha", async () => { const provider = await import("../providers/bocha.ts"); return adapter("bocha", "Bocha", provider.isBochaAvailable, provider.searchWithBocha); }), define("ollama", "Ollama", async () => { const provider = await import("../providers/ollama.ts"); return adapter("ollama", "Ollama", provider.isOllamaAvailable, provider.searchWithOllama); }), define("searxng", "SearXNG", async () => { const provider = await import("../providers/searxng.ts"); return adapter("searxng", "SearXNG", provider.isSearXNGAvailable, provider.searchWithSearXNG); }), define("duckduckgo", "DuckDuckGo", async () => { const provider = await import("../providers/duckduckgo.ts"); return adapter("duckduckgo", "DuckDuckGo", provider.isDuckDuckGoAvailable, provider.searchWithDuckDuckGo); }), define("perplexity", "Perplexity", async () => { const provider = await import("../providers/perplexity.ts"); return adapter("perplexity", "Perplexity", provider.isPerplexityAvailable, provider.searchWithPerplexity); }), define("gemini", "Gemini", async () => (await import("../providers/gemini/search.ts")).geminiSearchProvider), define("kimi", "Kimi", async () => { const provider = await import("../providers/kimi.ts"); return adapter("kimi", "Kimi", options => provider.isKimiSearchAvailable(options.extensionContext), (query, options) => provider.searchWithKimi(query, options, options.extensionContext)); }), define("exa", "Exa", async () => { const provider = await import("../providers/exa/search.ts"); return adapter("exa", "Exa", provider.isExaAvailable, async (query, options) => { const result = await provider.searchWithExa(query, options); if (!result) throw new Error("Exa search returned no results."); return result; }); }), define("anysearch", "AnySearch", async () => { const provider = await import("../providers/anysearch.ts"); return adapter("anysearch", "AnySearch", provider.isAnySearchAvailable, provider.searchWithAnySearch); }), define("xcrawl", "XCrawl", async () => { const provider = await import("../providers/xcrawl.ts"); return adapter("xcrawl", "XCrawl", provider.isXcrawlAvailable, provider.searchWithXCrawl); }), define("xai", "xAI", async () => { const provider = await import("../providers/xai.ts"); return adapter("xai", "xAI", options => provider.isXaiSearchAvailable(options.extensionContext), (query, options) => provider.searchWithXai(query, options, options.extensionContext)); }), define("brightdata", "Bright Data", async () => { const provider = await import("../providers/brightdata/search.ts"); return adapter("brightdata", "Bright Data", provider.isBrightDataAvailable, provider.searchWithBrightData); }), define("serpbase", "SerpBase", async () => { const provider = await import("../providers/serpbase.ts"); return adapter("serpbase", "SerpBase", provider.isSerpBaseAvailable, provider.searchWithSerpBase); }), define("serper", "Serper", async () => { const provider = await import("../providers/serper.ts"); return adapter("serper", "Serper", provider.isSerperAvailable, provider.searchWithSerper); }), define("valyu", "Valyu", async () => { const provider = await import("../providers/valyu.ts"); return adapter("valyu", "Valyu", provider.isValyuAvailable, provider.searchWithValyu); }), ]; function adapter( id: string, label: string, available: SearchProviderAdapter["isAvailable"], search: SearchProviderAdapter["search"], currentModelAvailable?: (options: ProviderSearchOptions) => boolean, ): SearchProviderAdapter { return { id, label, isAvailable(options, useCurrentModel) { return useCurrentModel && currentModelAvailable ? currentModelAvailable(options) : available(options); }, search, }; } export const searchProviderRegistry = new Map(definitions.map(provider => [provider.id, provider])); export function getSearchProviderDefinition(id: string): SearchProviderDefinition { const provider = searchProviderRegistry.get(id); if (!provider) throw new Error(`Unknown search Provider: ${id}`); return provider; } export async function loadSearchProvider(id: string): Promise { return getSearchProviderDefinition(id).load(); }