--- name: project-jarvis description: "JARVIS AI Iron Man HUD — DigitalOcean 165.22.1.228; full admin portal at /admin; network auto-scan via PVE1; GitHub: myronblair/jarvis" metadata: node_type: memory type: project originSessionId: f0b18417-cc26-4fdf-87ec-7b2d69b02c44 --- JARVIS is hosted on **PVE1 VM 211** (10.48.200.211), migrated from DO 2026-06-18. URL: https://jarvis.orbishosting.com (via NPM → VM 211). Admin: https://jarvis.orbishosting.com/admin/ **How to apply:** Files at `/var/www/jarvis/` on VM 211. SSH: `sshpass -p 'Joker1974!!!' ssh -o StrictHostKeyChecking=no root@10.48.200.211` ## Credentials - Login: myron / Joker1974!!! - DB: jarvis_db / jarvis_user / J4rv1s_Pr0t0c0l_2026! - MySQL root: b71e5c1a8c7457541b9c1db822de37adfa271926a38b6c20 - phpMyAdmin: /phpmyadmin (myron / Joker1974!!!) - HA token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJjZmQyMTYxNzdkZGY0MGQ5YjlkNjFhMTFiZmViZTNhNCIsImlhdCI6MTc3OTI0MTI2MywiZXhwIjoyMDk0NjAxMjYzfQ.wD3yYiCHh6iEuH1mZckg4dgr3zOJHLmlMj_N0OyzdR4 - Agent registration key: f846a9aaf7ce9a61742c63c87c4186052a71d2a580c65518 - Proxmox API token: root@pam!jarvis=c45b5feb-f9a9-445d-a626-14fbb959f78b ## Network Map (verified 2026-06-17) ### PVE1 VMs (10.48.200.90, orbisne.fortiddns.com) | VMID | Name | IP | Agent ID | Status | |------|------|----|----------|--------| | 100 | SynchroNet-50 | 10.48.200.50 | none | running | | 101 | HomeAssistant-97 | 10.48.200.97 | homeassistant_ha | online | | 102 | UmbrelOS | DHCP | none | running | | 104 | Windows10-DHCP | DHCP | none | running | | 105 | Frigate | DHCP | none | running — **not in use, no integration planned** | | 107 | Claude-DHCP | 10.48.200.29 | none | running — **this is the Claude Code VM** | | 112 | Jellyfin-33 | 10.48.200.33 | jellyfin_7e386833 | online (fixed 2026-06-17) | | 103 | MediaStack-35 | 10.48.200.35 | MediaStack_2c00b1b8 | online (was VM113 pre-2026-06-22 restore) | | 118 | HomeBridge-26 | 10.48.200.18 | homebridge_b57cbaea | online (fixed 2026-06-17) | | 120 | NovaCPX-110 | 10.48.200.110 | novacpx_e3b07264 | online | ### PVE2 VMs (10.48.200.91) | VMID | Name | IP | Agent ID | Status | |------|------|----|----------|--------| | 302 | NetworkBackup-99 | 10.48.200.99 | networkbackup_NetworkB | online | ### Other Agents - **JARVIS DO**: 165.22.1.228 (agent: jarvis-do_orbis) — online - **PVE1**: 10.48.200.90 (agent: claude_pve) — online - **PVE2**: 10.48.200.91 (agent: pve2_pve2) — online - **FortiGate**: 10.48.200.1 (agent: fortigate_gw) — online - **WireGuard CT**: (agent: wireguard_360460f7, no LAN IP) — online - **Yealink T48S**: 10.48.200.43 (agent: yealink_t48s) — online - **mini_it12**: 10.48.200.87 (agent: mini_it12_windows, Windows) — offline since 2026-06-12 ### Gone / No Longer Exist - Ollama VM 210 — was listed as deleted but IS running at 10.48.200.210 as VM 106 (was VM210 pre-restore). OLLAMA_HOST=0.0.0.0:11434 fixed 2026-06-24. - alien-pc_windows — not registered (Dell devices at .66/.67 exist on network but no agent) ### Agent Config Note Agents with old `server_url` config key crash on startup — must use `jarvis_url`. Fixed on homebridge and jellyfin 2026-06-17. If any other agent starts failing, copy config to /etc/jarvis-agent/config.json with `jarvis_url` key. ## Agent System - Push-based: heartbeat 10s, metrics 30s - agent.php uses CF-Connecting-IP header for real client IP (Cloudflare-aware) - Platform detection: windows/mac/linux/tablet — tablet shows view-only message - Subnet fallback match: if exact IP miss, matches same /24 - Shell commands supported with `{"allowed": true}` in command_data - Installer: `curl -sk https://jarvis.orbishosting.com/install-agent.sh | bash -s ` - For VMs needing sudo: `echo "Joker1974!" | sudo -S bash /tmp/install.sh linux` ### Agent Versions (as of 2026-06-12) - **Linux v3.1**: adds version to registration payload, fixes self_update cfg scope bug in execute_command - **Windows v3.0**: real self-update (was stub), screenshot (PIL+PS fallback), sysinfo, re-registers on startup - **macOS v3.0**: new agent — CPU via `top -l 2`, mem via `sysctl`+`vm_stat`, screenshot via `screencapture -x` - Config location (mac): `~/.jarvis-agent/config.json` | agent_type: "macos" | agent_id: "{HOSTNAME}_mac" - **Old agents with `cfg` scope bug**: shell and update commands fail with `name 'cfg' is not defined` — auto-updates within 24h via periodic check in main() where cfg IS in scope - registered_agents table has `version VARCHAR(20)` column and 'macos' in agent_type ENUM ### Workers Admin Tab (added 2026-06-12) - VERSION column shows current vs latest version with color coding (green=current, red=outdated, yellow=unknown) - Update button: cyan "⬆ UPDATE" if outdated, dim "↻ UPDATE" if current - `agentUpdateFlow()`: popup modal, polls workers_list every 4s up to 90s, updates version cell in-place on completion ## Network Scanning - PVE1 cron: `*/3 * * * * /usr/local/bin/jarvis-netscan.sh` — nmap 10.48.200.0/24, pushes to `/api/netscan` - netscan.php authenticated via X-Registration-Key header - network.php includes netscan-discovered devices (online, last 15 min) in network panel - RUN NETWORK SCAN button: queues shell command to PVE1 agent, auto-refreshes panel after 45s - DO cannot SSH to PVE1 local IP — must use orbisne.fortiddns.com or agent commands - Site monitoring updated 2026-06-09: parkerslingshot key now points to parkerslingshotrentals.com (was parkerslingshot.epictravelexpeditions.com) in facts_collector.php, alerts.php, do_server.php ## Admin Portal (/admin) - URL: https://jarvis.orbishosting.com/admin — same login as JARVIS - Tabs: Dashboard, Agents, Network, Alerts, KB Facts, KB Intents, Home Assistant, News, Proxmox VMs, Sites, Users, **Tasks, Appointments** - Network tab: shows ALL discovered devices (not just named), filter online/offline/named, Scan Now queues PVE1 command - HA tab: reads from ha_entities table (real-time); toggle calls DO→HA directly (HA_URL = orbisne.fortiddns.com:8123) - News tab: custom pinned news stored in kb_facts (category='custom_news'), merged into main news feed - Proxmox VMs tab: uses cluster API (both PVE1+PVE2), shows CPU/RAM/disk/uptime/network per VM - Tasks tab: full CRUD (add/edit/mark done/delete), filter by status/category - Appointments tab: full CRUD, upcoming 90 days view ## Proxmox API - Accessible via orbisne.fortiddns.com:8006 (FortiGate forwards port 8006) - stats_cache.php uses cluster/resources API to get ALL VMs from both nodes - PVE2 VMs only accessible via cluster API (no direct external port forward for PVE2) ## Key Files (on DO at /home/jarvis.orbishosting.com/) - public_html/index.html — Iron Man HUD UI - public_html/admin/index.php — Admin portal (single-file PHP+JS) - public_html/api.php — API router - api/config.php — all config constants - api/endpoints/agent.php — agent registration/heartbeat/metrics/commands - api/endpoints/chat.php — 4-tier chat: KB intent → action intents → Ollama → Groq → Claude - api/endpoints/network.php — network device list (agents + named + netscan) - api/endpoints/netscan.php — push endpoint for PVE1 nmap results - api/endpoints/stats_cache.php — every 5min: Proxmox (cluster API), HA, weather, news - api/endpoints/facts_collector.php — every 3min: system stats, site health, HA facts - api/endpoints/do_server.php — reads /proc directly (no SSH loopback) ## DB Schema Notes - `agent_metrics` columns: id, agent_id, metric_type, metric_data (JSON longtext), recorded_at - metric_type='system'; CPU/RAM/disk live inside metric_data JSON - Extract with: JSON_EXTRACT(metric_data,'$.cpu_percent'), JSON_EXTRACT(metric_data,'$.memory.percent') - NO cpu_pct/mem_pct/disk_pct columns — always use JSON_EXTRACT ## Chat Architecture - Tier 1b: Action intents (network_scan → returns real DB data + queues PVE1 netscan) - network_scan intent: action type, returns real device count, never fabricates - Groq model: compound-beta-mini (NOT groq/compound-beta-mini) ## Planner System (added 2026-05-31) - Tables: `tasks` (title, notes, category ENUM personal/work/todo, priority ENUM low/normal/high/urgent, status ENUM pending/in_progress/done/cancelled, due_date, due_time, completed_at) and `appointments` (title, description, category, start_at, end_at, location, all_day, reminder_min, alerted) - API endpoint: `/api/planner/{tasks|appointments|today|done}` (GET=list, POST=save, DELETE=delete) - Voice intents in chat.php Tier 0.7: "add task X", "my tasks", "mark X done", "schedule X on date", "my calendar", "daily briefing" - Home page: small top-bar badge shows "N TASKS · N APPTS" when items due today; no new panels ## Voice System (updated 2026-05-31) - Continuous SpeechRecognition — mic always open, button is mute toggle (🎤 sleep / 🟢 listen / 🔇 mute) - Wake phrase (phase 1): "wake up JARVIS" or "daddy's home" → activates; JARVIS responds once - Command trigger (phase 2): "JARVIS [command]" executes; opens 17-second free-listen window for follow-ups - After 30 min no commands → voice sleeps; after 5 min idle → page reloads silently (no greeting) - Mic paused during ElevenLabs TTS via recognition.abort() + isSpeaking flag; resumes 300ms after audio ends - ElevenLabs: voice ID JBFqnCBsd6RMkjVDRZzb (George), model eleven_turbo_v2_5, key in config.php ## Arc Reactor AI Routing (updated 2026-06-17) - **Arc Reactor daemon**: `/opt/jarvis-arc/reactor.py` (Python, port 7474); service: `jarvis-arc` - **Deploy source**: `/home/jarvis.orbishosting.com/deploy/reactor.py` → copy to `/opt/jarvis-arc/reactor.py` + `systemctl restart jarvis-arc` - **llm_call() providers**: "claude" → Claude API, "groq" → Groq, "ollama" → local Ollama; cascades groq→ollama on failure - **Guardian anomaly alerts** (line ~1025): Groq `llama-3.3-70b-versatile` — 2-3 sentence Iron Man alert when CPU/RAM/disk/service thresholds trip - **SITREP** (line ~1068): Groq by default — comprehensive text briefing across all agents - **Vision: text-only sysinfo** (line ~691): Groq — when agent returns JSON snapshot (no image) - **Vision: actual screenshot** (line ~664): Claude `claude-opus-4-8-20251101` — stays on Claude, Groq has no vision models - **Email drafting, research, tool_loop**: still Claude — complex reasoning tasks ## kb_facts Fix (2026-06-17) - `storeFact()` ON DUPLICATE KEY UPDATE now explicitly sets `updated_at=NOW()` — previously MySQL wouldn't bump the timestamp if fact_value hadn't changed, causing do_server.php's 15-min freshness check to return empty sites - `$fresh()` in facts_collector.php was querying `WHERE fact_category=?` (wrong column); fixed to `WHERE category=?` - Site health checks now hit `http://127.0.0.1` with `Host:` header instead of public HTTPS URL (avoids Cloudflare 524 timeouts on self-check) ## Known Quirks - LSAPI deadlock: session_write_close() in api.php after auth - lsphp segfaults on -l flag; use php8.3 -l for syntax checking - DO cannot reach 10.48.200.x directly — use DDNS or agent commands - Proxmox local IP in config.php (PROXMOX_HOST=10.48.200.90) but API calls use orbisne.fortiddns.com - stats_cache.php uses orbisne.fortiddns.com:8006 (not PROXMOX_HOST) for Proxmox API - HA_URL = http://orbisne.fortiddns.com:8123 (FortiGate forwards 8123→HA); service calls work from DO - ha.php entity list reads from ha_entities table (NOT api_cache) — real-time data from HA agent - When editing index.html with Python patches: always use file-based scripts (not heredocs or inline), avoid double-brace `}}` near function closings - Arc Reactor bugs fixed 2026-06-12: capabilities panel uses `s?.capabilities || s?.handlers`; Guardian ts() variable shadowing fixed (renamed evTs); Vision always fetches fresh agents_list - Arc reactor DB bugs fixed 2026-06-12: column is `metric_data` not `metrics_json`; system data is flat JSON not nested under "system" key; conversations column is `content` not `message`; disk uses `mount` key not `mountpoint`