import { Article as ArticleIcon, Assessment as AssessmentIcon, Book as BookIcon, Download as DownloadIcon, Hub as HubIcon, EmojiEvents as LeaderboardIcon, RestartAlt as RestartIcon, RocketLaunch as RocketLaunchIcon, } from "@mui/icons-material"; import { alpha, Box, Button, Chip, CircularProgress, IconButton, Link, Paper, Stack, Tooltip, Typography, } from "@mui/material"; import React, { useCallback, useState } from "react"; import { FormData, UserInfo } from "../types"; import { DevModeLoginButton } from "./DevModeLoginButton"; import { HuggingFaceLoginButton } from "./HuggingFaceLoginButton"; import { ModelProviderSelector } from "./ModelProviderSelector"; import { TooltipIcon } from "./TooltipIcon"; import { McpConfigurationWarningDialog } from "./dialogs"; const TRANSITION = "all 0.3s ease-in-out"; interface InitialFormProps { formData: FormData; userInfo: UserInfo | null; accessToken: string | null; loginLabel: string; isStarting: boolean; defaultMcpFile: File | null; onFormChange: (formData: FormData) => void; onSubmit: () => void; onLoginStateChange: ( userInfo: UserInfo | null, accessToken: string | null, loginLabel: string, ) => void; } export const InitialForm: React.FC = ({ formData, userInfo, accessToken, loginLabel, isStarting, defaultMcpFile, onFormChange, onSubmit, onLoginStateChange, }) => { const [dialogOpen, setDialogOpen] = useState(false); const [pendingFile, setPendingFile] = useState(null); const [selectedOption, setSelectedOption] = useState<"suggested" | "custom">( "suggested", ); const [selectedSuggestion, setSelectedSuggestion] = useState("0"); const [customProvider, setCustomProvider] = useState(""); const [customModel, setCustomModel] = useState(""); // Define the suggested models const suggestedModels = [ { provider: "novita", model: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", label: "Llama-4-Maverick-17B-128E-Instruct-FP8", }, { provider: "novita", model: "zai-org/GLM-4.5", label: "GLM-4.5", }, { provider: "novita", model: "moonshotai/Kimi-K2-Instruct-0905", label: "Kimi-K2-Instruct-0905", }, { provider: "novita", model: "deepseek-ai/DeepSeek-V3.1", label: "DeepSeek-V3.1", }, { provider: "novita", model: "Qwen/Qwen3-Next-80B-A3B-Instruct", label: "Qwen3-Next-80B-A3B-Instruct", }, { provider: "novita", model: "Qwen/Qwen3-Coder-480B-A35B-Instruct", label: "Qwen3-Coder-480B-A35B-Instruct", }, ]; // Initialize form with first suggested model only when form is empty on mount React.useEffect(() => { if ( selectedOption === "suggested" && suggestedModels[0] && !formData.provider && !formData.model ) { onFormChange({ ...formData, provider: suggestedModels[0].provider, model: suggestedModels[0].model, }); } }, []); // Only run once on mount const isFormValid = Boolean( formData.model.trim() && formData.provider.trim() && userInfo?.sub, ); const isLoggedIn = Boolean(userInfo?.sub); const handleFileChange = useCallback( (event: React.ChangeEvent) => { const file = event.target.files?.[0] || null; if (file) { setPendingFile(file); setDialogOpen(true); } else { onFormChange({ ...formData, mcpFile: null }); } }, [formData, onFormChange], ); const resetFile = useCallback(() => { setPendingFile(null); onFormChange({ ...formData, mcpFile: defaultMcpFile }); }, [formData, onFormChange]); const handleDialogClose = useCallback(() => { setDialogOpen(false); setPendingFile(null); // Clear the file input element to reset the UI const fileInput = document.querySelector( 'input[type="file"]', ) as HTMLInputElement; if (fileInput) { fileInput.value = ""; } }, []); const handleDialogConfirm = useCallback(() => { if (pendingFile) { onFormChange({ ...formData, mcpFile: pendingFile }); } setDialogOpen(false); setPendingFile(null); }, [formData, onFormChange, pendingFile]); return ( <> Meta Agents Research Environments Welcome to the Meta ARE (Agents Research Environments) and Gaia2 demo! ARE is a research platform to easily interact with and evaluate agents. In this demo, you can: Test a simulated universe with apps representing a smartphone agent, similar to Gaia2. Find out which agent is the best assistant by trying different models! Visualize Gaia2 scenarios, to better understand the benchmark and debug your agent! Check out the{" "} documentation {" "} to find out how to run the Gaia2 benchmark with ARE. {/* Mobile warning message - only shown on xs screens */} 📱 This demo is not optimized for mobile devices. Please use a desktop or tablet for the best experience. {/* Informational links */} Additional links } label="Docs" component="a" href="https://facebookresearch.github.io/meta-agents-research-environments/" target="_blank" variant="outlined" clickable sx={{ pl: 0.5, }} /> } label="Gaia2" component="a" href="https://huggingface.co/datasets/meta-agents-research-environments/gaia2" target="_blank" variant="outlined" clickable sx={{ pl: 0.5, }} /> } label="Paper" component="a" href="https://arxiv.org/abs/2509.17158" target="_blank" variant="outlined" clickable sx={{ pl: 0.5, }} /> } label="Leaderboard" component="a" href="https://huggingface.co/spaces/meta-agents-research-environments/leaderboard" target="_blank" variant="outlined" clickable sx={{ pl: 0.5, }} /> } label="Blog" component="a" href="https://huggingface.co/blog/gaia2" target="_blank" variant="outlined" clickable sx={{ pl: 0.5, }} /> Get started {/* Login Section */} isLoggedIn ? alpha(theme.palette.action.disabled, 0.1) : "primary.main", borderRadius: 1.5, transition: TRANSITION, }} > Sign in with your Hugging Face account to access the inference providers.{" "} This demo is free to use - we've provided credits to cover the inference costs for your agent runs. {" "} We only use your Hugging Face account for authentication and do not access any of your other data or resources. {process.env.NODE_ENV === "development" ? ( ) : ( )} {/* Model and Provider Selection */} {/* Model Suggestions with two boxes */} {}} onProviderChange={() => {}} suggestedModels={suggestedModels} selectedSuggestion={selectedSuggestion} onSuggestionChange={(value, provider, model) => { setSelectedSuggestion(value); onFormChange({ ...formData, provider, model }); }} customProvider={customProvider} customModel={customModel} onCustomProviderChange={(provider) => { setCustomProvider(provider); if (customModel) { onFormChange({ ...formData, provider, model: customModel, }); } }} onCustomModelChange={(model) => { setCustomModel(model); if (customProvider) { onFormChange({ ...formData, provider: customProvider, model, }); } }} selectedOption={selectedOption} onOptionChange={(option) => { setSelectedOption(option); if (option === "suggested") { // Use currently selected suggestion, or default to first one if none selected const selectedIndex = selectedSuggestion !== "" ? parseInt(selectedSuggestion) : 0; const model = suggestedModels[selectedIndex]; if (model) { onFormChange({ ...formData, provider: model.provider, model: model.model, }); } } }} isDisabled={!isLoggedIn || isStarting} /> Upload an MCP configuration Optional {/* Start Button */} {/* MCP File Upload Warning Dialog */} ); };