Developer Setup on an Installed System
If you’re running JARVIS OS as your daily driver or a dev VM (not just booting a live ISO), this page covers how to get the full stack working correctly.
Prerequisites
- JARVIS OS installed from the live ISO (or kernel + daemon installed via
--host-install+--overlay) - For the default local-inference path: Ollama running (
systemctl status ollama) with at least one model pulled (ollama list). Remote Ollama instances and OpenAI-compatible APIs also work — see step 2.
1. Verify the kernel module loads at boot
The jarvis.ko module must be loaded before any service starts.
lsmod | grep jarvis # Should show: jarvis, dibs
ls -l /dev/jarvis # Should exist
If the module isn’t loading automatically at boot, create the modules-load config:
sudo tee /etc/modules-load.d/jarvis.conf << 'EOF'
jarvis
EOF
sudo systemctl restart systemd-modules-load.service
modprobe resolves the dibs dependency automatically — no separate entry needed.
2. Configure an LLM provider
Provider and model configuration lives in a provider pool (providers.json), not in
jarvis.conf. The pool is a priority-ordered failover list: the daemon tries providers in
order until one responds. Entries can be local or remote Ollama instances, or any
OpenAI-compatible API. Without at least one provider configured, jarvis, jarvis run,
and jarvis chat refuse to start with Error: No LLM configured.
Add a local Ollama provider (the daemon reads /etc/jarvis/providers.json because the
systemd unit sets JARVIS_CONFIG_DIR=/etc/jarvis):
ollama list # Find installed models
sudo JARVIS_CONFIG_DIR=/etc/jarvis jarvis providers add --type ollama --model qwen3:14b
Remote Ollama instances and OpenAI-compatible APIs are added the same way, and
jarvis providers move reorders the failover priority:
jarvis providers add --type api --model <model> --url <api-url> --key <api-key>
jarvis providers move <name> 1 # Make <name> the first provider tried
The pool can also be managed interactively from the TUI’s Settings modal (F2, Providers tab).
/etc/jarvis/jarvis.conf still holds non-provider settings:
OUTPUT_MODE=text # Use "text" if no working audio device
LLM_AUTO_PULL=false # Set true to auto-pull missing models
Apply to the running service:
sudo systemctl restart jarvis.service
jarvis providers # Pool should list your model at position [1]
3. Run the TUI
The interactive terminal UI (jarvis tui) requires the textual package in the JARVIS Python
environment:
which jarvis # Should be /usr/local/bin/jarvis
sudo /opt/jarvis-env/bin/pip install textual
jarvis tui
| Key | Action |
|---|---|
Ctrl+N |
New session |
Ctrl+D |
Delete selected session |
Ctrl+Q |
Quit |
Ctrl+L |
Focus chat log (scroll with arrows/PgUp) |
Ctrl+I |
Focus input |
F1 |
Help / keybinding reference |
F2 |
Settings (Providers tab: add/edit LLM providers) |
Enter |
Submit message |
Two unlisted bindings also exist: Ctrl+Shift+C clears the chat log and Ctrl+Shift+E
exports the transcript.
4. Send messages to the running daemon
The JARVIS systemd service listens on a Unix socket:
jarvis send "what is my CPU temperature"
# Or use text chat mode directly (bypasses the socket, runs its own event loop)
jarvis chat
5. Verify the full stack
ls /dev/jarvis && echo "kernel driver OK"
systemctl is-active jarvis.service
curl -s http://localhost:11434/api/tags | python3 -m json.tool | grep name
jarvis providers # Pool should list your model at position [1]
jarvis ask "say hello"
Runtime file layout
| Path | Purpose |
|---|---|
/usr/local/bin/jarvis |
Shell entry point (wraps /opt/jarvis-env/bin/jarvis) |
/opt/jarvis-env/ |
Python venv with JARVIS and all dependencies |
/usr/lib/jarvis/ |
JARVIS Python package source |
/etc/jarvis/jarvis.conf |
System-wide config (output mode, auto-pull, sockets — not model/provider settings) |
/etc/jarvis/providers.json |
LLM provider pool (priority-ordered failover list; managed via jarvis providers) |
/usr/lib/jarvis/.env |
Fallback config when JARVIS_CONFIG_DIR is unset |
/var/lib/jarvis/ |
Runtime data (models dir, secondary venv) |
/run/jarvis/input.sock |
Unix socket — jarvis send writes here |
/run/jarvis/output.sock |
Unix socket — subscribe to receive JSON responses |
/var/log/jarvis/ |
Logs (also in journalctl -u jarvis) |
/etc/modules-load.d/jarvis.conf |
Ensures jarvis.ko loads at boot |
/dev/jarvis |
JARVIS kernel character device |
/sys/class/misc/jarvis/sysmon/ |
Live hardware metrics from kernel |
Config precedence
JARVIS_CONFIG_DIR env var → /etc/jarvis/jarvis.conf (system install, daemon)
↓ fallback
/usr/lib/jarvis/.env (dev fallback)
The systemd unit sets JARVIS_CONFIG_DIR=/etc/jarvis via Environment=. The
/usr/local/bin/jarvis wrapper sets it the same way so CLI and daemon always agree.
Running into errors on any of these steps? See Troubleshooting.
Changelog — corrected claims
2026-07-22:
LLM_MODEL/LLM_URLinjarvis.conf→ provider pool inproviders.json, managed viajarvis providers add/edit/move/removeor the TUI Settings modal; nothing in the daemon reads those legacy keys (code:jarvis/config.py,jarvis/core/component_factory.py).jarvis modelverification steps →jarvis providers; themodelcommand was removed and now exits with an error pointing at the provider pool (code:jarvis/cli.py).- Ollama-only setup framing → priority-ordered failover pool that also accepts remote
Ollama instances and OpenAI-compatible APIs; added the missing provider-creation step,
without which the daemon,
jarvis run, andjarvis chatrefuse to start. - TUI key table: added visible
Ctrl+D(delete session) andF2(Settings/Providers) bindings, plus the hidden clear/export shortcuts (code:jarvis/tui/app.py).