/** * JARVIS — Settings Modal * Runtime configuration: model status, memory stats, preferences. * Opens via keyboard shortcut Ctrl+, or settings button. */ import React, { useState, useEffect } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { X, Brain, Eye, Mic, Database, Zap, Server, RefreshCw, Trash2, CheckCircle, XCircle, AlertCircle, } from 'lucide-react' import clsx from 'clsx' import toast from 'react-hot-toast' import { healthAPI } from '../../services/api' import useAppStore from '../../stores/appStore' export default function SettingsModal({ open, onClose }) { const [health, setHealth] = useState(null) const [loading, setLoading] = useState(false) const { sessions, messages } = useAppStore() const fetchHealth = async () => { setLoading(true) try { const data = await healthAPI.check() setHealth(data) } catch { setHealth({ status: 'offline' }) } finally { setLoading(false) } } useEffect(() => { if (open) fetchHealth() }, [open]) const totalMessages = Object.values(messages).reduce( (sum, msgs) => sum + (msgs?.length || 0), 0 ) const models = [ { key: 'llm', label: 'Language Model', icon: Brain, desc: 'TinyLlama / Mistral' }, { key: 'blip', label: 'BLIP Vision', icon: Eye, desc: 'Image captioning' }, { key: 'clip', label: 'CLIP Vision', icon: Eye, desc: 'Image-text similarity' }, { key: 'whisper', label: 'Whisper STT', icon: Mic, desc: 'Speech-to-text' }, ] return ( {open && ( <> {/* Backdrop */} {/* Modal */}
{/* Header */}

SYSTEM STATUS

JARVIS Multi-Modal AI Assistant v1.0

{/* Backend status */}
{health?.status === 'online' ? 'FastAPI Online' : 'Connecting…'}
{/* AI Models */}
{models.map(({ key, label, icon: Icon, desc }) => { const status = health?.models?.[key] return (

{label}

{desc}

) })}
{/* Memory stats */}
{[ { label: 'Sessions', value: sessions.length }, { label: 'Messages', value: totalMessages }, { label: 'FAISS Vectors', value: health?.memory?.total_vectors ?? '—', }, { label: 'Memory Store', value: health?.memory?.initialized ? 'Ready' : 'Not ready', }, ].map(({ label, value }) => (

{label}

{value}

))}
{/* API endpoints */}
{[ { method: 'POST', path: '/api/chat/message', desc: 'Chat' }, { method: 'POST', path: '/api/image/analyze', desc: 'Vision' }, { method: 'POST', path: '/api/voice/interact', desc: 'Voice' }, { method: 'POST', path: '/api/tools/execute', desc: 'Tools' }, { method: 'WS', path: '/api/ws/chat/{id}', desc: 'Streaming' }, ].map(({ method, path, desc }) => (
{method} {path} {desc}
))}
{/* Docs link */}
)}
) } // ── Helpers ──────────────────────────────────────────────────── function SectionLabel({ icon: Icon, label }) { return (
{label}
) } function StatusDot({ ok }) { return (
) } function ModelStatus({ status }) { if (status === true) return if (status === false) return return }