"use client"; import React, { useState, useEffect, useRef } from "react"; import { Activity, Terminal, User, Cpu, ShieldAlert, CheckCircle, XCircle, Database, FileText, Sparkles, Send, RefreshCw, Play, GitPullRequest, Layers, Settings, AlertCircle, Trash2, HeartPulse, LogOut, Maximize2, CloudSun, Wind, Droplets, Thermometer, Compass, MessageSquare, Mail } from "lucide-react"; import WhatsAppAgentUI from "../components/WhatsAppAgentUI"; import GmailAgentUI from "../components/GmailAgentUI"; export default function Page() { const [activeTab, setActiveTab] = useState("dashboard"); // Claw Chat State const [messages, setMessages] = useState([ { role: "assistant", content: "Hello! I am Claw, your local agent. Try:\n• `weather` — live weather for Mars, PA\n• `whatsapp me: message` — send now to your phone\n• `remind me at 3pm: call doctor` — schedule for later\n• `remind me tomorrow at 6am: gym` — future reminders\n• Or give me a list with times and I'll schedule them all!", timestamp: "Just now" } ]); const [inputValue, setInputValue] = useState(""); const [isClawTyping, setIsClawTyping] = useState(false); const [clawTerminalLogs, setClawTerminalLogs] = useState([]); const [weatherCard, setWeatherCard] = useState(null); const [weatherSending, setWeatherSending] = useState(false); const [weatherSent, setWeatherSent] = useState(false); const [scheduledReminders, setScheduledReminders] = useState([]); // OpsAgent State const [pendingApprovals, setPendingApprovals] = useState([ { id: "ops-req-102", targetType: "proxmox", targetId: "102", action: "clean_disk", details: "LXC container root filesystem is at 94% disk usage. Recommending apt cache clean and temporary file removal.", timestamp: "5 mins ago", status: "pending" }, { id: "ops-req-201", targetType: "kubernetes", targetId: "curio-app-xyz", action: "restart_pod", details: "Pod curio-app-xyz is in CrashLoopBackOff state. Logs indicate: 'Database connection failed: Connection refused by 10.96.20.10:5432'. Recommending pod deletion to trigger k8s reschedule.", timestamp: "10 mins ago", status: "pending" } ]); const [opsLogs, setOpsLogs] = useState([ "2026-05-29 01:10:00 [OpsAgent] Initialized diagnostic run on K8s cluster...", "2026-05-29 01:10:15 [OpsAgent] Found Pod 'curio-app-xyz' in CrashLoopBackOff. Emitting warning.", "2026-05-29 01:12:02 [OpsAgent] Proxmox VMID 102 root usage checked: 94%. Action required." ]); // Curio HMS State const [dictationText, setDictationText] = useState( "Patient is a 45-year-old male presenting with severe, crushing chest pain radiating to his left arm. He has a past medical history of hypertension. Admitting to Cardiac ICU." ); const [clinicalNote, setClinicalNote] = useState(null); const [billingCodes, setBillingCodes] = useState([]); const [isProcessingClinical, setIsProcessingClinical] = useState(false); // Workflow logs state const [workflows, setWorkflows] = useState([ { id: "wf-bernard-001", name: "PRReviewWorkflow", agent: "Bernard", target: "pr-401", status: "completed", result: "Approved with suggestions" }, { id: "wf-gumbo-002", name: "GumboSummarizeWorkflow", agent: "Gumbo", target: "api-spec.md", status: "completed", result: "Summary persisted in PG" }, { id: "wf-ops-003", name: "OpsRemediateWorkflow", agent: "OpsAgent", target: "VMID 102", status: "running", result: "Awaiting approval signal" } ]); // Trips State const [tripsList, setTripsList] = useState([]); const [selectedTripId, setSelectedTripId] = useState(null); const [tripEditorJson, setTripEditorJson] = useState(""); const [isSavingTrip, setIsSavingTrip] = useState(false); const [isTestingTrip, setIsTestingTrip] = useState(false); // Config State const [configData, setConfigData] = useState({ defaultGroupUrl: "", tripGroupUrl: "" }); const [isSavingConfig, setIsSavingConfig] = useState(false); const [configLoaded, setConfigLoaded] = useState(false); const messagesEndRef = useRef(null); const terminalEndRef = useRef(null); useEffect(() => { if (activeTab === "config" && !configLoaded) { fetch('/api/config/whatsapp') .then(res => res.json()) .then(data => { if (data.success) { setConfigData({ defaultGroupUrl: data.data['default-group-url'] || "", tripGroupUrl: data.data['trip-group-url'] || "" }); setConfigLoaded(true); } }) .catch(console.error); } }, [activeTab, configLoaded]); const handleSaveConfig = async () => { setIsSavingConfig(true); try { const res = await fetch('/api/config/whatsapp', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(configData) }); const data = await res.json(); if (data.success) { alert("Configuration saved successfully to Kubernetes manifest!"); } else { alert("Failed to save: " + data.error); } } catch (e) { alert("Error saving config: " + e.message); } finally { setIsSavingConfig(false); } }; useEffect(() => { messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages, isClawTyping]); useEffect(() => { terminalEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [clawTerminalLogs]); useEffect(() => { if (activeTab === "trips") { fetch('/api/trips').then(res => res.json()).then(data => { if(Array.isArray(data)) setTripsList(data); }).catch(() => {}); } }, [activeTab]); // Simulated Claw response logic const handleSendMessage = async (e) => { e.preventDefault(); if (!inputValue.trim()) return; const userText = inputValue; setMessages(prev => [...prev, { role: "user", content: userText, timestamp: "Just now" }]); setInputValue(""); setIsClawTyping(true); setWeatherCard(null); setWeatherSent(false); setClawTerminalLogs(prev => [...prev, `[Claw] Received instruction: "${userText}"`]); let responseText = ""; let logs = []; const cleanInput = userText.toLowerCase(); // ── WhatsApp Send Command ──────────────────────────────────────────────── // Matches: "whatsapp me: ...", "send to whatsapp ...", "message me ...", // "text me ...", "wa me ...", "send 'X' to my whatsapp" const waIntent = /(?:whatsapp\s+me|message\s+me|text\s+me|send\s+(?:to\s+)?(?:my\s+)?whatsapp|wa\s+me|remind\s+me\s+via\s+whatsapp)[:\s]+(.+)/i; const waMatch = userText.match(waIntent); if (waMatch) { const waMsg = waMatch[1].replace(/^["'`]|["'`]$/g, '').trim(); // strip surrounding quotes setClawTerminalLogs(prev => [...prev, `[Claw] WhatsApp send detected. Message: "${waMsg}"`, `[Claw] Calling /api/send-whatsapp (personalOnly) ...` ]); try { const res = await fetch('/api/send-whatsapp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: `📌 *Claw Reminder*\n\n${waMsg}`, personalOnly: true }), }); const data = await res.json(); if (data.success) { setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Delivered to +14085505485. MsgID: ${data.messageId}`]); responseText = `✅ Done! I've sent that to your WhatsApp (+14085505485):\n\n> "${waMsg}"\n\nYou should see it arrive shortly.`; } else { throw new Error(data.error || 'Gateway error'); } } catch (err) { setClawTerminalLogs(prev => [...prev, `[Claw] ❌ WhatsApp send failed: ${err.message}`]); responseText = `❌ Couldn't send to WhatsApp: ${err.message}. Make sure the gateway is running.`; } // ── Scheduled Reminder ───────────────────────────────────────────────────── // Patterns: "remind me at X: msg", "schedule (whatsapp) at X: msg", // "send to whatsapp at X: msg", multi-bullet lists } else if ( /(?:remind\s+me|schedule\s+(?:a\s+)?(?:whatsapp\s+)?(?:reminder|message)?)\s+(?:at|on|for|in|tomorrow|monday|tuesday|wednesday|thursday|friday|saturday|sunday)/i.test(userText) || /send\s+to\s+whatsapp\s+(?:at|in|tomorrow|on\s+)/i.test(userText) || // multi-bullet list: "schedule these:\n- msg at 3pm\n- msg2 at 6am" (/(?:schedule|remind\s+me)/i.test(userText) && userText.includes('\n')) ) { // Check for multi-item list (lines starting with - or •) const lines = userText.split('\n').map(l => l.trim()).filter(Boolean); const bulletLines = lines.filter(l => /^[-•*]\s+/.test(l) || (lines.length > 2 && l !== lines[0])); const isBatch = bulletLines.length > 1; if (isBatch) { // Batch scheduling const items = []; const skipped = []; for (const line of bulletLines) { const clean = line.replace(/^[-•*]\s*/, '').trim(); // Try to split into message + time: "call doctor at 2pm" or "2pm: call doctor" // Strategy: extract time, rest is the message const sendAt = parseScheduleDateTime(clean); if (!sendAt) { skipped.push(clean); continue; } // Remove the time expression from the label const label = clean.replace(/(at|by|on|for)?\s*\d{1,2}(?::\d{2})?\s*(am|pm)/gi, '').replace(/tomorrow|today|monday|tuesday|wednesday|thursday|friday|saturday|sunday/gi, '').replace(/in\s+\d+\s+(hour|hr|minute|min)s?/gi, '').trim().replace(/\s+/g, ' '); const formatted = `⏰ *Claw Reminder*\n\n${label}\n\n_Scheduled for ${sendAt.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true })} ET_`; items.push({ message: formatted, sendAt: sendAt.toISOString(), label }); } if (items.length === 0) { responseText = `❌ I couldn't parse any valid times from your list. Make sure each item includes a time like "at 3pm", "tomorrow at 9am", or "in 2 hours".`; } else { setClawTerminalLogs(prev => [...prev, `[Claw] Scheduling ${items.length} reminders...`]); try { const res = await fetch('/api/reminders', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items }) }); const data = await res.json(); const lines2 = data.created?.map(c => `✅ "${c.label}" → ${formatReminderTime(c.sendAt)} ET`) || []; if (skipped.length) lines2.push(...skipped.map(s => `⚠️ Skipped (no time): "${s}"`)); responseText = `📅 Scheduled ${data.created?.length || 0} reminder(s):\n\n${lines2.join('\n')}`; // Refresh reminder panel fetch('/api/reminders?status=pending').then(r => r.json()).then(d => { if (Array.isArray(d)) setScheduledReminders(d); }); setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Batch scheduled: ${items.length} reminders`]); } catch (err) { responseText = `❌ Failed to schedule: ${err.message}`; } } } else { // Single reminder // Parse message after colon: "remind me at 3pm: call doctor" → msg = "call doctor" const colonSplit = userText.match(/[:\u2014]\s*(.+)$/s); const msgText = colonSplit ? colonSplit[1].trim() : userText; const sendAt = parseScheduleDateTime(userText); if (!sendAt) { responseText = `❌ I couldn't find a valid time in your message. Try: "remind me at 3pm: call doctor" or "remind me tomorrow at 9am: gym".`; } else { const etLabel = sendAt.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true }); const waMsg = `⏰ *Claw Reminder*\n\n${msgText}\n\n_Scheduled for ${etLabel} ET_`; setClawTerminalLogs(prev => [...prev, `[Claw] Scheduling: "${msgText}" → ${sendAt.toISOString()}`]); try { const res = await fetch('/api/schedule-reminder', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: waMsg, sendAt: sendAt.toISOString(), label: msgText }), }); const data = await res.json(); if (data.success) { responseText = `✅ Reminder scheduled!\n\n📌 **"${msgText}"**\n🕐 Delivers at **${etLabel} ET** to your WhatsApp (+14085505485)`; fetch('/api/reminders?status=pending').then(r => r.json()).then(d => { if (Array.isArray(d)) setScheduledReminders(d); }); setClawTerminalLogs(prev => [...prev, `[Claw] ✅ Scheduled ID: ${data.id}`]); } else { throw new Error(data.error || 'Scheduling failed'); } } catch (err) { responseText = `❌ Couldn't schedule: ${err.message}`; setClawTerminalLogs(prev => [...prev, `[Claw] ❌ ${err.message}`]); } } } } else if (cleanInput.includes("weather")) { // Extract optional location override const locMatch = userText.match(/(?:weather\s+(?:in|for|at)?\s*)(.+)/i); const location = locMatch ? locMatch[1].trim() : '16046'; logs = [ `[Claw] Fetching live weather data for "${location}"...`, "[Claw] Connecting to wttr.in weather service...", ]; setClawTerminalLogs(prev => [...prev, ...logs]); try { const res = await fetch(`/api/weather?location=${encodeURIComponent(location)}`); const wx = await res.json(); if (wx.error) throw new Error(wx.error); setWeatherCard(wx); setClawTerminalLogs(prev => [...prev, `[Claw] Got weather for ${wx.location}: ${wx.current.tempF}°F, ${wx.current.desc}`, "[Claw] Rendering weather card. Use the button to push to WhatsApp." ]); const emoji = getWeatherEmoji(wx.current.desc); responseText = `${emoji} Here's the live weather for **${wx.location}**:\n\n🌡️ **${wx.current.tempF}°F** (feels like ${wx.current.feelsLikeF}°F) — ${wx.current.desc}\n💧 Humidity: ${wx.current.humidity}% | 💨 Wind: ${wx.current.windMph} mph ${wx.current.windDir}\n📊 Today: ${wx.today.minF}°F – ${wx.today.maxF}°F | 🌅 ${wx.today.sunrise} / 🌇 ${wx.today.sunset}\n\nI've generated the full report card below. Hit **Send to WhatsApp** to push it to your group!`; } catch (err) { responseText = `❌ Could not fetch weather: ${err.message}. Check your internet or try a city name like \`weather Toronto\`.`; setClawTerminalLogs(prev => [...prev, `[Claw] Error: ${err.message}`]); } } else if (cleanInput.includes("pod") || cleanInput.includes("k8s") || cleanInput.includes("kubectl")) { await new Promise(resolve => setTimeout(resolve, 1500)); logs = [ "Connecting to Kubernetes API server...", "Executing: kubectl get pods -n default", "Found 2 pods in namespace 'default':", " - web-pod-xyz 0/1 CrashLoopBackOff 5 2h", " - db-pod-abc 1/1 Running 0 5d", "Fetching logs for 'web-pod-xyz'...", " Error detected: Database connection refused by 10.96.20.10:5432" ]; responseText = "I've checked the Kubernetes pods. Pod `web-pod-xyz` is currently failing due to a database connection refusal. You can use the **OpsAgent** tab to approve a pod restart or scale the DB deployment."; } else if (cleanInput.includes("proxmox") || cleanInput.includes("vmid") || cleanInput.includes("disk")) { await new Promise(resolve => setTimeout(resolve, 1500)); logs = [ "Establishing SSH connection to Proxmox cluster host 192.168.8.225...", "Running: pct status 102", " status: running", "Running: pct exec 102 -- df -h /", " Filesystem Size Used Avail Use% Mounted on", " /dev/loop0 20G 19G 0.2G 94% /", "Disk usage critically high! Proposed action: clean_disk" ]; responseText = "Proxmox Container ID `102` is running out of disk space (94% used). I have created a pending action under the **OpsAgent Center** to perform automated cleanup. Would you like me to execute it?"; } else if (cleanInput.includes("hello") || cleanInput.includes("hi")) { await new Promise(resolve => setTimeout(resolve, 800)); responseText = "Hi there! I am Claw, your local personal assistant. Try asking me to `check k8s pods`, `diagnose proxmox container 102`, or just type `weather` for a live report!"; } else { await new Promise(resolve => setTimeout(resolve, 1200)); responseText = `I've analyzed your query: "${userText}". I recommend initiating an **OpsRemediateWorkflow** to check the status or scanning your configuration files. Let me know if you would like me to trigger that for you.`; } setClawTerminalLogs(prev => [...prev, ...logs, "[Claw] Response formulated successfully."]); setMessages(prev => [...prev, { role: "assistant", content: responseText, timestamp: "Just now" }]); setIsClawTyping(false); }; // Weather emoji helper const getWeatherEmoji = (desc) => { const d = (desc || '').toLowerCase(); if (d.includes('sunny') || d.includes('clear')) return '☀️'; if (d.includes('partly cloudy')) return '⛅'; if (d.includes('cloud') || d.includes('overcast')) return '☁️'; if (d.includes('thunder') || d.includes('storm')) return '⛈️'; if (d.includes('rain') || d.includes('drizzle')) return '🌧️'; if (d.includes('snow') || d.includes('blizzard')) return '❄️'; if (d.includes('fog') || d.includes('mist')) return '🌫️'; return '🌤️'; }; // Send weather to WhatsApp const handleSendWeatherToWhatsApp = async () => { if (!weatherCard) return; setWeatherSending(true); const wx = weatherCard; const emoji = getWeatherEmoji(wx.current.desc); const msg = [ `${emoji} *Good Morning — Daily Weather Report*`, `📍 *${wx.location}* (ZIP: ${wx.zip})`, ``, `${emoji} ${wx.current.desc}`, `🌡️ *Temp:* ${wx.current.tempF}°F (feels like ${wx.current.feelsLikeF}°F)`, `💧 *Humidity:* ${wx.current.humidity}%`, `💨 *Wind:* ${wx.current.windMph} mph ${wx.current.windDir}`, `👁️ *Visibility:* ${wx.current.visibility} mi`, `☀️ *UV Index:* ${wx.current.uvIndex}`, ``, `📊 *Today:* ${wx.today.minF}°F – ${wx.today.maxF}°F`, `🌅 Sunrise: ${wx.today.sunrise} 🌇 Sunset: ${wx.today.sunset}`, wx.tomorrow ? `🔮 *Tomorrow:* ${wx.tomorrow.minF}°F – ${wx.tomorrow.maxF}°F ${getWeatherEmoji(wx.tomorrow.desc)} ${wx.tomorrow.desc}` : '', ``, `_Agentic OS HQ • hq.applaude.net_ 🏠`, ].filter(Boolean).join('\n'); try { const res = await fetch('/api/send-whatsapp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: msg }) }); const data = await res.json(); if (data.success) { setWeatherSent(true); setMessages(prev => [...prev, { role: "assistant", content: "✅ Weather report sent to your WhatsApp group!", timestamp: "Just now" }]); } else { setMessages(prev => [...prev, { role: "assistant", content: `❌ Failed to send: ${data.error}`, timestamp: "Just now" }]); } } catch (err) { setMessages(prev => [...prev, { role: "assistant", content: `❌ Error: ${err.message}`, timestamp: "Just now" }]); } finally { setWeatherSending(false); } }; // Poll scheduled reminders every 30s when on claw tab useEffect(() => { if (activeTab !== 'claw') return; const fetchReminders = async () => { try { const res = await fetch('/api/reminders?status=pending'); if (res.ok) { const data = await res.json(); if (Array.isArray(data)) setScheduledReminders(data); } } catch { /* reminder service may not be up yet */ } }; fetchReminders(); const interval = setInterval(fetchReminders, 30000); return () => clearInterval(interval); }, [activeTab]); // ── Natural-language date/time parser ──────────────────────────────────────── const parseScheduleDateTime = (text) => { const t = text.toLowerCase(); const now = new Date(); // "in X hours/minutes" const inMatch = t.match(/\bin\s+(\d+)\s+(hour|hr|minute|min)s?\b/); if (inMatch) { const n = parseInt(inMatch[1]); const ms = inMatch[2].startsWith('h') ? n * 3600000 : n * 60000; return new Date(now.getTime() + ms); } // Extract time component: "3pm", "6:30am", "14:00" let hours = null, minutes = 0; const ampm = t.match(/(\d{1,2})(?::(\d{2}))?\s*(am|pm)/); const h24 = t.match(/(\d{2}):(\d{2})(?!\s*(am|pm))/); if (ampm) { hours = parseInt(ampm[1]); minutes = ampm[2] ? parseInt(ampm[2]) : 0; if (ampm[3] === 'pm' && hours !== 12) hours += 12; if (ampm[3] === 'am' && hours === 12) hours = 0; } else if (h24) { hours = parseInt(h24[1]); minutes = parseInt(h24[2]); } // Build date let date = new Date(now); let explicitDate = false; if (t.includes('tomorrow')) { date.setDate(date.getDate() + 1); explicitDate = true; } else { const days = ['sunday','monday','tuesday','wednesday','thursday','friday','saturday']; const dayIdx = days.findIndex(d => t.includes(d)); if (dayIdx !== -1) { const diff = ((dayIdx - now.getDay()) + 7) % 7 || 7; // next occurrence date.setDate(date.getDate() + diff); explicitDate = true; } else { // Named month: "May 30", "June 1" const months = ['january','february','march','april','may','june','july','august','september','october','november','december']; const shortM = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec']; let mIdx = months.findIndex(m => t.includes(m)); if (mIdx === -1) mIdx = shortM.findIndex(m => t.match(new RegExp('\\b' + m + '\\b'))); if (mIdx !== -1) { const dayNum = t.match(/(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\w*\s+(\d{1,2})/i); if (dayNum) { date.setMonth(mIdx, parseInt(dayNum[1])); if (date < now) date.setFullYear(date.getFullYear() + 1); explicitDate = true; } } } } if (hours === null) return null; // no time found date.setHours(hours, minutes, 0, 0); // If the computed time is in the past and no explicit date was given, push to tomorrow if (date <= now && !explicitDate) date.setDate(date.getDate() + 1); return date; }; // ── Format a Date nicely for display ───────────────────────────────────────── const formatReminderTime = (isoStr) => { const d = new Date(isoStr); return d.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true }); }; // ── Cancel a reminder ───────────────────────────────────────────────────────── const handleCancelReminder = async (id) => { try { const res = await fetch(`/api/reminders?id=${id}`, { method: 'DELETE' }); if (res.ok) setScheduledReminders(prev => prev.filter(r => r.id !== id)); } catch { /* silent */ } }; const handleApprove = async (id, action, target) => { setPendingApprovals(prev => prev.map(item => item.id === id ? { ...item, status: "approved" } : item)); setOpsLogs(prev => [...prev, `2026-05-29 01:14:10 [OpsAgent] RECEIVED APPROVAL SIGNAL for request ${id}`]); // Simulate execution log let execLogs = [ `[OpsAgent] Initiating execution of '${action}' on target '${target}'...`, `[OpsAgent] Sending signal to Temporal workflow...`, ]; if (action === "clean_disk") { execLogs.push( "[OpsAgent] SSH into Proxmox node VMID 102...", "[OpsAgent] running: apt-get clean && rm -rf /tmp/*", "[OpsAgent] Disk space cleared. Root filesystem usage reduced from 94% to 71%." ); } else { execLogs.push( `[OpsAgent] Running: kubectl delete pod ${target} -n default`, `[OpsAgent] Pod deleted. K8s controller successfully scheduled a replica.` ); } // Delay log write to simulate real execution for (const log of execLogs) { await new Promise(resolve => setTimeout(resolve, 800)); setOpsLogs(prev => [...prev, log]); } setPendingApprovals(prev => prev.filter(item => item.id !== id)); setWorkflows(prev => prev.map(wf => wf.target === (action === "clean_disk" ? "VMID 102" : target) ? { ...wf, status: "completed", result: "Remediated successfully" } : wf)); }; const handleReject = (id) => { setPendingApprovals(prev => prev.filter(item => item.id !== id)); setOpsLogs(prev => [...prev, `2026-05-29 01:14:30 [OpsAgent] Request ${id} REJECTED by operator. Action aborted.`]); }; // Clinical note simulation const handleProcessClinical = async () => { setIsProcessingClinical(true); setClinicalNote(null); setBillingCodes([]); await new Promise(resolve => setTimeout(resolve, 1500)); setClinicalNote({ subjective: "Patient is a 45-year-old male presenting with severe, crushing chest pain radiating to his left arm. He reports shortness of breath.", objective: "Alert and oriented. Reports pain scale 8/10.", assessment: "Acute Myocardial Infarction suspected.", plan: "Order EKG, troponin levels. Administer Aspirin 324mg immediately. Admit to Cardiac ICU." }); setBillingCodes([ { code: "I21.9", desc: "Acute myocardial infarction, unspecified" }, { code: "93000", desc: "Electrocardiogram, tracing and report" }, { code: "99223", desc: "Initial hospital care, high level severity" } ]); setIsProcessingClinical(false); }; const handleSaveTrip = async () => { try { setIsSavingTrip(true); let parsed = JSON.parse(tripEditorJson); if (selectedTripId) { await fetch(`/api/trips/${selectedTripId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(parsed) }); } else { await fetch('/api/trips', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(parsed) }); } const data = await fetch('/api/trips').then(r => r.json()); setTripsList(Array.isArray(data) ? data : []); setSelectedTripId(null); setTripEditorJson(""); } catch (e) { alert("Invalid JSON or save failed: " + e.message); } finally { setIsSavingTrip(false); } }; const handleTestTrip = async (id) => { setIsTestingTrip(true); try { const res = await fetch(`/api/trips/${id}/test`, { method: 'POST' }); const data = await res.json(); if (data.success) { alert("Test briefing fired to WhatsApp successfully!"); } else { alert("Test failed: " + JSON.stringify(data)); } } catch (e) { alert("Error triggering test: " + e.message); } finally { setIsTestingTrip(false); } }; return (
{/* Sidebar Navigation */} {/* Main Content Area */}

{activeTab.replace("curio", "Clinical Curio").replace("ops", "OpsAgent Hub")}

Namespace: ai-agents
Sysadmin Console 192.168.8.250
{/* TAB 1: DASHBOARD HOME */} {activeTab === "dashboard" && (
{/* Stat Cards */}
Total Active Agents

5 / 8

Active in namespace
Temporal Workflows

12 Active

98.8% success SLA
Diagnostic Logs

142 MB

Persisted in PostgreSQL
Action Approvals

{pendingApprovals.length} Awaiting

Require administrator override
{/* Agent Status Panel */}

Core Agent Ecosystem Status

{[ { name: "Bernard", role: "GitOps Reviewer & Workflow Monitor", status: "Idle", desc: "Awaiting PR push events on Gitea hooks.", type: "system" }, { name: "Gumbo", role: "Documentation Summarizer", status: "Active", desc: "Indexing recent technical wiki docs via MCP filesystem.", type: "assistant" }, { name: "OpsAgent", role: "SRE Diagnostics & Self-Healing", status: "Pending approval", desc: "Awaiting administrator decision for remediation action.", type: "remediator" }, { name: "Claw", role: "Local Assistant CLI (OpenClaw clone)", status: "Active", desc: "Awaiting operator prompt input.", type: "assistant" }, { name: "Curio Billing/Triage", role: "HMS AI Assist", status: "Idle", desc: "Standing by for clinical intake recording inputs.", type: "clinical" }, ].map((agent, i) => (

{agent.name}

{agent.role} — {agent.desc}

{agent.status}
))}
{/* Quick Trigger Block */}

Diagnostics & Ops Triggers

Knowledge Intake Trigger

)} {/* TAB 2: CLAW PERSONAL ASSISTANT */} {activeTab === "claw" && (
{/* Chat Panel */}
{/* Chat Header */}

Claw Personal Assistant

Runs locally. Accesses file tools & system terminal.
{/* Chat Messages */}
{messages.map((msg, i) => (
{msg.content}
{msg.timestamp}
))} {isClawTyping && (
)} {/* Weather Card */} {weatherCard && (
{/* Card Header */}
{getWeatherEmoji(weatherCard.current.desc)}
📍 {weatherCard.location}
Live conditions • ZIP {weatherCard.zip}
{weatherCard.current.tempF}°F
feels like {weatherCard.current.feelsLikeF}°F
{/* Condition */}
{weatherCard.current.desc}
{/* Stats Grid */}
{[ { icon: "💧", label: "Humidity", value: `${weatherCard.current.humidity}%` }, { icon: "💨", label: "Wind", value: `${weatherCard.current.windMph} mph ${weatherCard.current.windDir}` }, { icon: "☀️", label: `UV Index`, value: `${weatherCard.current.uvIndex}` }, { icon: "👁️", label: "Visibility", value: `${weatherCard.current.visibility} mi` }, { icon: "🔺", label: "High", value: `${weatherCard.today.maxF}°F` }, { icon: "🔻", label: "Low", value: `${weatherCard.today.minF}°F` }, ].map((stat, i) => (
{stat.icon}
{stat.value}
{stat.label}
))}
{/* Sunrise/Sunset & Tomorrow */}
🌅 {weatherCard.today.sunrise} 🌇 {weatherCard.today.sunset} {weatherCard.tomorrow && ( {getWeatherEmoji(weatherCard.tomorrow.desc)} Tomorrow: {weatherCard.tomorrow.minF}–{weatherCard.tomorrow.maxF}°F )}
{/* Send to WhatsApp CTA */}
)}
{/* Chat Input */}
setInputValue(e.target.value)} placeholder="e.g. 'weather', 'whatsapp me: call doctor at 3pm', 'check k8s pods'..." style={{ flex: 1, padding: "12px 16px", border: "1px solid var(--border-color)", borderRadius: "8px", background: "var(--bg-secondary)", color: "var(--text-primary)", outline: "none", fontSize: "14px" }} />
{/* Claw Tool & Console Log Panel */}
{/* Terminal Console */}

Claw Tool Console

{clawTerminalLogs.length === 0 ? (
Console logs will stream here as Claw calls CLI and API tools...
) : ( clawTerminalLogs.map((log, i) => (
> {log}
)) )}
{/* Scheduled Reminders Panel */}

Scheduled Reminders {scheduledReminders.length > 0 && ( {scheduledReminders.length} )}

auto-refreshes
{scheduledReminders.length === 0 ? (
No reminders scheduled.
Try: "remind me at 3pm: call doctor"
) : ( scheduledReminders.map((r) => (
{r.label}
🕐 {formatReminderTime(r.sendAt)} ET
)) )}
)} {/* TAB 3: OPSAGENT HUB */} {activeTab === "ops" && (
{/* Left Column: Diagnostics and Approvals */}
{/* Pending Actions */}

Awaiting System Approvals (Approval Gate)

{pendingApprovals.length === 0 ? (

No approvals pending

All systems are running clean and within normal parameters.

) : (
{pendingApprovals.map((req) => (
{req.action.replace("_", " ")} Target: {req.targetType.toUpperCase()} ({req.targetId})
{req.timestamp}

{req.details}

))}
)}
{/* Diagnostics Panel */}

OpsAgent Diagnostics Tools

Manually run automated checks across your container nodes.

K8s Diagnostic
Proxmox Auditor
{/* Right Column: Execution Live Terminal */}

OpsAgent Execution Terminal Logs

{opsLogs.map((log, i) => (
{log}
))}
)} {/* TAB 4: CLINICAL WORKSPACE */} {activeTab === "curio" && (
{/* Doctor Dictation Section */}

Clinical Scribe Workspace

Uses ClinicalIntakeWorkflow (Temporal Task Queue)