import React, { useEffect, useRef, useState } from "react"; import Admin from "@/models/admin"; import SerpApiIcon from "./icons/serpapi.png"; import SearchApiIcon from "./icons/searchapi.png"; import SerperDotDevIcon from "./icons/serper.png"; import BingSearchIcon from "./icons/bing.png"; import BaiduSearchIcon from "./icons/baidu.png"; import SerplySearchIcon from "./icons/serply.png"; import SearXNGSearchIcon from "./icons/searxng.png"; import TavilySearchIcon from "./icons/tavily.svg"; import DuckDuckGoIcon from "./icons/duckduckgo.png"; import ExaIcon from "./icons/exa.png"; import PerplexitySearchIcon from "./icons/perplexity.png"; import { CaretUpDown, MagnifyingGlass, X, ListMagnifyingGlass, } from "@phosphor-icons/react"; import Toggle from "@/components/lib/Toggle"; import SearchProviderItem from "./SearchProviderItem"; import WebSearchImage from "@/media/agents/scrape-websites.png"; import { SerpApiOptions, SearchApiOptions, SerperDotDevOptions, BingSearchOptions, BaiduSearchOptions, SerplySearchOptions, SearXNGOptions, TavilySearchOptions, DuckDuckGoOptions, ExaSearchOptions, PerplexitySearchOptions, } from "./SearchProviderOptions"; const SEARCH_PROVIDERS = [ { name: "DuckDuckGo", value: "duckduckgo-engine", logo: DuckDuckGoIcon, options: () => , description: "Free and privacy-focused web search using DuckDuckGo.", }, { name: "SerpApi", value: "serpapi", logo: SerpApiIcon, options: (settings) => , description: "Scrape Google and several other search engines with SerpApi. 250 free searches every month, and then paid.", }, { name: "SearchApi", value: "searchapi", logo: SearchApiIcon, options: (settings) => , description: "SearchApi delivers structured data from multiple search engines. Free for 100 queries, but then paid. ", }, { name: "Serper.dev", value: "serper-dot-dev", logo: SerperDotDevIcon, options: (settings) => , description: "Serper.dev web-search. Free account with a 2,500 calls, but then paid.", }, { name: "Bing Search", value: "bing-search", logo: BingSearchIcon, options: (settings) => , description: "Web search powered by the Bing Search API (paid service).", }, { name: "Baidu Search", value: "baidu-search", logo: BaiduSearchIcon, options: (settings) => , description: "Web search powered by Baidu Search for stronger zh-CN retrieval.", }, { name: "Serply.io", value: "serply-engine", logo: SerplySearchIcon, options: (settings) => , description: "Serply.io web-search. Free account with a 100 calls/month forever.", }, { name: "SearXNG", value: "searxng-engine", logo: SearXNGSearchIcon, options: (settings) => , description: "Free, open-source, internet meta-search engine with no tracking.", }, { name: "Tavily Search", value: "tavily-search", logo: TavilySearchIcon, options: (settings) => , description: "Tavily Search API. Offers a free tier with 1000 queries per month.", }, { name: "Exa Search", value: "exa-search", logo: ExaIcon, options: (settings) => , description: "One of the best web search APIs for AI agents with real-time results and full page contents.", }, { name: "Perplexity Search", value: "perplexity-search", logo: PerplexitySearchIcon, options: (settings) => , description: "AI-powered web search using the Perplexity Search API.", }, ]; export default function AgentWebSearchSelection({ skill, title, description, settings, toggleSkill, enabled = false, setHasChanges, }) { const searchInputRef = useRef(null); const [filteredResults, setFilteredResults] = useState([]); const [selectedProvider, setSelectedProvider] = useState("duckduckgo-engine"); const [searchQuery, setSearchQuery] = useState(""); const [searchMenuOpen, setSearchMenuOpen] = useState(false); function updateChoice(selection) { setSearchQuery(""); setSelectedProvider(selection); setSearchMenuOpen(false); setHasChanges(true); } function handleXButton() { if (searchQuery.length > 0) { setSearchQuery(""); if (searchInputRef.current) searchInputRef.current.value = ""; } else { setSearchMenuOpen(!searchMenuOpen); } } useEffect(() => { const filtered = SEARCH_PROVIDERS.filter((provider) => provider.name.toLowerCase().includes(searchQuery.toLowerCase()) ); setFilteredResults(filtered); }, [searchQuery, selectedProvider]); useEffect(() => { Admin.systemPreferencesByFields(["agent_search_provider"]) .then((res) => setSelectedProvider( res?.settings?.agent_search_provider ?? "duckduckgo-engine" ) ) .catch(() => setSelectedProvider("duckduckgo-engine")); }, []); const selectedSearchProviderObject = SEARCH_PROVIDERS.find((provider) => provider.value === selectedProvider) ?? SEARCH_PROVIDERS[1]; return (
toggleSkill(skill)} />
Web Search

{description}

); }