Spaces:
Paused
Paused
import React, { useState, useRef } from 'react'; | |
import { useNavigate } from 'react-router-dom'; | |
import Box from '@mui/material/Box'; | |
import Slider from '@mui/material/Slider'; | |
import Stack from '@mui/material/Stack'; | |
import Button from '@mui/material/Button'; | |
import IconButton from '@mui/material/IconButton'; | |
import './IntialSetting.css'; | |
import { FaTimes, FaEye, FaEyeSlash } from 'react-icons/fa'; | |
function IntialSetting(props) { | |
// State variables for form controls | |
const [selectedProvider, setSelectedProvider] = useState("OpenAI"); | |
const [modelTemperature, setModelTemperature] = useState(0.0); | |
const [modelTopP, setModelTopP] = useState(1.0); | |
const [showPassword, setShowPassword] = useState(false); | |
// Ref for the form and navigation hook | |
const formRef = useRef(null); | |
const navigate = useNavigate(); | |
// Model options for different providers | |
const modelOptions = { | |
OpenAI: { | |
"GPT-4 Turbo": "gpt-4-turbo", | |
"GPT-4o": "gpt-4o", | |
"GPT-4o Latest": "gpt-4o-2024-11-20", | |
"GPT-4o Mini": "gpt-4o-mini", | |
"ChatGPT": "chatgpt-4o-latest", | |
}, | |
Anthropic: { | |
"Claude 3.5 Sonnet": "claude-3-5-sonnet-20241022", | |
"Claude 3.5 Haiku": "claude-3-5-haiku-20241022", | |
"Claude 3 Opus": "claude-3-opus-20240229", | |
"Claude 3 Sonnet": "claude-3-sonnet-20240229", | |
"Claude 3 Haiku": "claude-3-haiku-20240307", | |
}, | |
Google: { | |
"Gemini 1.5 Pro": "gemini-1.5-pro", | |
"Gemini 1.5 Flash": "gemini-1.5-flash", | |
"Gemini 2.0 Flash Lite": "gemini-2.0-flash-lite-preview-02-05", | |
"Gemini 2.0 Flash Experimental": "gemini-2.0-flash-exp", | |
"Gemini 2.0 Flash": "gemini-2.0-flash", | |
"Gemini 2.0 Pro Experimental": "gemini-2.0-pro-exp-02-05", | |
}, | |
XAI: { | |
"Grok-2": "grok-2-latest", | |
"Grok Beta": "grok-beta", | |
}, | |
}; | |
// Reset form and state variables | |
const handleReset = (e) => { | |
e.preventDefault(); | |
if (formRef.current) { | |
formRef.current.reset(); | |
} | |
setSelectedProvider("OpenAI"); | |
setModelTemperature(0.0); | |
setModelTopP(1.0); | |
}; | |
// Handle form submission and save settings | |
const handleSave = async (e) => { | |
e.preventDefault(); | |
const form = formRef.current; | |
// Retrieve form values | |
const modelProvider = form.elements["model-provider"].value; | |
const modelName = form.elements["model-name"].value; | |
const modelAPIKeys = form.elements["model-api"].value; | |
const braveAPIKey = form.elements["brave-api"].value; | |
const proxyList = form.elements["proxy-list"].value; | |
// Check for missing required fields | |
const missingFields = []; | |
if (!modelProvider || modelProvider.trim() === "") missingFields.push("Model Provider"); | |
if (!modelName || modelName.trim() === "") missingFields.push("Model Name"); | |
if (!modelAPIKeys || modelAPIKeys.trim() === "") missingFields.push("Model API Key"); | |
if (!braveAPIKey || braveAPIKey.trim() === "") missingFields.push("Brave Search API Key"); | |
if (missingFields.length > 0) { | |
props.openSnackbar( | |
"Please fill in the following required fields: " + missingFields.join(", "), | |
"error" | |
); | |
return; | |
} | |
// Build payload for backend | |
const payload = { | |
"Model_Provider": modelProvider.toLowerCase(), | |
"Model_Name": modelName, | |
"Model_API_Keys": modelAPIKeys, | |
"Brave_Search_API_Key": braveAPIKey, | |
"Model_Temperature": modelTemperature, | |
"Model_Top_P": modelTopP, | |
}; | |
if (proxyList && proxyList.trim() !== "") { | |
payload["Proxy_List"] = proxyList; | |
} | |
// Show appropriate notification based on context | |
if (props.fromAiPage) { | |
props.openSnackbar( | |
<Box mt={1} display="flex" alignItems="center"> | |
<Box className="re-applying-settings-custom-spinner" /> | |
<Box ml={1} className="re-applying-settings-text"> | |
<span>Re-applying settings. This may take a few minutes...</span> | |
</Box> | |
</Box>, | |
"info" | |
); | |
} else { | |
props.openSnackbar("Settings saved successfully!", "success"); | |
if (props.onInitializationStart) { | |
props.onInitializationStart(); | |
} | |
} | |
// Send settings to backend | |
try { | |
const response = await fetch("/settings", { | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify(payload), | |
}); | |
if (response.ok) { | |
const data = await response.json(); | |
if (data.success === true) { | |
if (props.fromAiPage) { | |
props.openSnackbar("Settings saved successfully!", "success"); | |
} | |
navigate("/AiPage"); | |
} else { | |
props.openSnackbar("Error saving settings. Please try again.", "error"); | |
} | |
} else { | |
props.openSnackbar("Error saving settings. Please try again.", "error"); | |
} | |
} catch (error) { | |
console.error("Error saving settings:", error); | |
props.openSnackbar("Error saving settings. Please try again.", "error"); | |
} | |
}; | |
// Render the settings modal | |
return props.trigger ? ( | |
<div className="showSetting" onClick={() => props.setTrigger(false)}> | |
<div className="showSetting-inner" onClick={(e) => e.stopPropagation()}> | |
<label className="setting-size">Settings</label> | |
<button className="close-btn" onClick={() => props.setTrigger(false)}> | |
<FaTimes /> | |
</button> | |
<form ref={formRef}> | |
<div className="form-group"> | |
<label htmlFor="model-provider">Model Provider</label> | |
<select | |
id="model-provider" | |
name="model-provider" | |
value={selectedProvider} | |
onChange={(e) => setSelectedProvider(e.target.value)} | |
> | |
{Object.keys(modelOptions).map(provider => ( | |
<option key={provider} value={provider}> | |
{provider} | |
</option> | |
))} | |
</select> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="model-name">Model Name</label> | |
<select id="model-name" name="model-name"> | |
{Object.entries(modelOptions[selectedProvider]).map( | |
([displayName, backendName]) => ( | |
<option key={backendName} value={backendName}> | |
{displayName} | |
</option> | |
) | |
)} | |
</select> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="model-api">Model API Key</label> | |
<textarea | |
id="model-api" | |
name="model-api" | |
placeholder="Enter API Key, one per line" | |
></textarea> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="brave-api">Brave Search API Key</label> | |
<input | |
type="text" | |
id="brave-api" | |
name="brave-api" | |
placeholder="Enter API Key" | |
/> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="proxy-list">Proxy List</label> | |
<textarea | |
id="proxy-list" | |
name="proxy-list" | |
placeholder="Enter proxies, one per line" | |
></textarea> | |
</div> | |
{/* Commented Neo4j configuration fields */} | |
{/* <div className="form-group"> | |
<label htmlFor="neo4j-url">Neo4j URL</label> | |
<input | |
type="text" | |
id="neo4j-url" | |
name="neo4j-url" | |
placeholder="Enter Neo4j URL" | |
/> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="neo4j-username">Neo4j Username</label> | |
<input | |
type="text" | |
id="neo4j-username" | |
name="neo4j-username" | |
placeholder="Enter Username" | |
/> | |
</div> | |
<div className="form-group"> | |
<label htmlFor="neo4j-password">Neo4j Password</label> | |
<div className="password-wrapper"> | |
<input | |
type={showPassword ? "text" : "password"} | |
id="neo4j-password" | |
name="neo4j-password" | |
placeholder="Enter Password" | |
/> | |
<IconButton | |
onClick={() => setShowPassword(prev => !prev)} | |
className="password-toggle" | |
sx={{ | |
color: "white", | |
p: 0, | |
m: 0 | |
}} | |
> | |
{showPassword ? <FaEyeSlash /> : <FaEye />} | |
</IconButton> | |
</div> | |
</div> */} | |
<div className="form-group"> | |
<div className="sliders-container"> | |
<div className="slider-item"> | |
<label htmlFor="temperature">Temperature</label> | |
<Slider | |
id="temperature" | |
value={modelTemperature} | |
onChange={(e, newValue) => setModelTemperature(newValue)} | |
step={0.05} | |
min={0.0} | |
max={1.0} | |
valueLabelDisplay="auto" | |
sx={{ width: '100%', color: 'success.main' }} | |
/> | |
</div> | |
<div className="slider-item"> | |
<label htmlFor="top-p">Top-P</label> | |
<Slider | |
id="top-p" | |
value={modelTopP} | |
onChange={(e, newValue) => setModelTopP(newValue)} | |
step={0.05} | |
min={0.0} | |
max={1.0} | |
valueLabelDisplay="auto" | |
sx={{ width: '100%', color: 'success.main' }} | |
/> | |
</div> | |
</div> | |
</div> | |
<Stack direction="row" spacing={2} sx={{ justifyContent: 'flex-end' }}> | |
<Button | |
type="button" | |
className="reset-btn" | |
sx={{ color: "#2196f3" }} | |
onClick={handleReset} | |
> | |
Reset | |
</Button> | |
<Button | |
type="button" | |
variant="contained" | |
color="success" | |
className="save-btn" | |
onClick={handleSave} | |
> | |
Save | |
</Button> | |
</Stack> | |
</form> | |
{props.children} | |
</div> | |
</div> | |
) : null; | |
} | |
export default IntialSetting; |