import { useCallback, useEffect, useState } from 'react'; import { Download, Loader2 } from 'lucide-react'; import { Button } from '../../../../../shared/view/ui'; import { authenticatedFetch } from '../../../../../utils/api'; import SettingsCard from '../../SettingsCard'; import SettingsRow from '../../SettingsRow'; import SettingsSection from '../../SettingsSection'; import SettingsToggle from '../../SettingsToggle'; type BrowserUseSettings = { enabled: boolean; }; type BrowserUseStatus = { enabled: boolean; available: boolean; playwrightInstalled: boolean; chromiumInstalled: boolean; installInProgress: boolean; message: string; }; async function readJson(response: Response): Promise { const data = await response.json(); if (!response.ok || data.success === false) { throw new Error(data.error || data.details || `Request failed (${response.status})`); } return data as T; } export default function BrowserUseSettingsTab() { const [settings, setSettings] = useState(null); const [status, setStatus] = useState(null); const [isSettingsLoading, setIsSettingsLoading] = useState(true); const [isStatusLoading, setIsStatusLoading] = useState(true); const [isSaving, setIsSaving] = useState(false); const [isInstalling, setIsInstalling] = useState(false); const [error, setError] = useState(null); const loadSettings = useCallback(async () => { const settingsResponse = await authenticatedFetch('/api/browser-use/settings'); const settingsData = await readJson<{ data: { settings: BrowserUseSettings } }>(settingsResponse); setSettings(settingsData.data.settings); }, []); const loadStatus = useCallback(async () => { const statusResponse = await authenticatedFetch('/api/browser-use/status'); const statusData = await readJson<{ data: BrowserUseStatus }>(statusResponse); setStatus(statusData.data); }, []); useEffect(() => { setError(null); setIsSettingsLoading(true); setIsStatusLoading(true); void loadSettings() .catch((err) => setError(err instanceof Error ? err.message : 'Failed to load Browser settings')) .finally(() => setIsSettingsLoading(false)); void loadStatus() .catch((err) => setError(err instanceof Error ? err.message : 'Failed to load Browser status')) .finally(() => setIsStatusLoading(false)); }, [loadSettings, loadStatus]); const updateSettings = async (nextSettings: Partial) => { setIsSaving(true); setError(null); try { const response = await authenticatedFetch('/api/browser-use/settings', { method: 'PUT', body: JSON.stringify(nextSettings), }); const data = await readJson<{ data: { settings: BrowserUseSettings } }>(response); setSettings(data.data.settings); window.dispatchEvent(new Event('browserUseSettingsChanged')); setIsStatusLoading(true); await loadStatus(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to save Browser settings'); } finally { setIsStatusLoading(false); setIsSaving(false); } }; const installBrowserBinaries = async () => { setIsInstalling(true); setError(null); try { const response = await authenticatedFetch('/api/browser-use/runtime/install', { method: 'POST' }); await readJson(response); setIsStatusLoading(true); await loadStatus(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to install browser runtime'); } finally { setIsStatusLoading(false); setIsInstalling(false); } }; const browserEnabled = settings?.enabled === true; const needsBrowserBinaries = Boolean(browserEnabled && status && (!status.playwrightInstalled || !status.chromiumInstalled)); const runtimeLabel = (installed?: boolean) => { if (isStatusLoading && !status) { return 'checking...'; } return installed ? 'installed' : 'missing'; }; return (
{isSettingsLoading && !settings ? ( ) : ( void updateSettings({ enabled: value })} ariaLabel="Enable Browser" disabled={isSaving} /> )}
Playwright: {runtimeLabel(status?.playwrightInstalled)} Chromium: {runtimeLabel(status?.chromiumInstalled)} Status: {isStatusLoading && !status ? 'checking...' : status?.available ? 'ready' : browserEnabled ? 'setup required' : 'disabled'}
{needsBrowserBinaries && (
Browser runtime required

{status?.message || 'Install the browser runtime before agents can create Browser sessions.'}

)} {error && (
{error}
)}
); }