import { useState, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Save, Loader2, Globe } from "lucide-react"; import { api } from "@/lib/api"; interface WebSearchConfig { provider: string; api_key?: string; base_url?: string; max_results: number; } export function WebSearchConfig() { const { t } = useTranslation(); const [config, setConfig] = useState({ provider: 'duckduckgo', max_results: 5 }); const [isLoading, setIsLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(''); const [success, setSuccess] = useState(''); const fetchConfig = async () => { setIsLoading(true); try { const data = await api.get('/api/v1/web-search/config'); setConfig({ provider: data.provider || 'duckduckgo', api_key: data.api_key || '', base_url: data.base_url || '', max_results: data.max_results || 5 }); } catch (err: unknown) { console.error("Failed to load web search config", err); setError(t('failedToLoadConfig', 'Failed to load configuration')); } finally { setIsLoading(false); } }; useEffect(() => { fetchConfig(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleSave = async () => { setError(''); setSuccess(''); setIsSaving(true); try { await api.put('/api/v1/web-search/config', config); setSuccess(t('configSaved', 'Configuration saved successfully. Note: Active agents may require a restart to pick up the new configuration.')); } catch (err: unknown) { console.error("Failed to save web search config", err); const errorMessage = err instanceof Error ? err.message : t('failedToSaveConfig', 'Failed to save configuration'); setError(errorMessage); } finally { setIsSaving(false); } }; if (isLoading) { return (
); } const needsApiKey = ['brave', 'tavily', 'jina'].includes(config.provider); const needsBaseUrl = config.provider === 'searxng'; return (
{t('webSearchConfig', 'Web Search Configuration')}
{error &&
{error}
} {success &&
{success}
} {t('webSearchConfig', 'Web Search Configuration')} {t('configureWebSearchProvider', 'Configure the default web search provider and settings for the AI agent.')}
{needsApiKey && (
setConfig({ ...config, api_key: e.target.value })} />

{t('apiKeyRequiredFor', 'An API Key is required for {{provider}}', { provider: config.provider })}

)} {needsBaseUrl && (
setConfig({ ...config, base_url: e.target.value })} />

{t('baseUrlRequiredFor', 'A Base URL is required for {{provider}}', { provider: config.provider })}

)}
setConfig({ ...config, max_results: parseInt(e.target.value) || 5 })} />

{t('maxResultsDescription', 'Maximum number of search results to return (1-20)')}

); }