L.U.N.A. is an open-source AI engine - a local-first platform you own completely. Drop in any LLM, extend it with skills written in plain text, connect your health devices, automate your desktop, and talk to it with your voice. No subscriptions, no cloud lock-in, no data leaving your machine by default.
It ships as two modes: Personal (voice, vision, Spotify, health data, desktop automation) and Business (multi-user JWT auth, rate limiting, Telegram/Discord/Slack channels). Switch between them with a single .env change.
git clone https://github.com/Sehastrajit/Luna.git && cd Luna && npm install && npm run luna -- setupThe setup wizard picks your variant, configures your LLM provider, installs Python and Node dependencies, and pulls Ollama models. Luna opens on http://localhost:8899 in about two minutes.
Need voice, camera, and desktop automation? See Desktop install for the Electron shell.
- What it is
- Variants
- Features
- Any Model
- Skills — extend without code
- Health Platforms
- Desktop install
- Docker
- Stack
- Architecture
- Configuration
- Device Support
- Project Layout
- Testing
- Contributing
- Privacy
- License
Luna is the engine underneath. It handles:
- LLM routing — one config line switches between 8 providers. Ollama by default, any OpenAI-compatible endpoint, or every major cloud model.
- Memory — facts, personality, and conversation summaries persist in local SQLite + ChromaDB. Luna remembers across sessions.
- Skill system — extend the engine by dropping a folder into
skills/. No Python, no restarts, no wiring — just askill.jsonand a plain-textSKILL.md. Skills are loaded per-request at runtime. - Health data engine — 7 platforms, 23 metric types, normalized and stored locally. Add a new platform by writing one Python file.
- Voice + vision pipeline — wake-word detection, faster-whisper STT, edge-tts TTS, and moondream camera analysis running fully on-device.
- Tool layer — web search, page fetch, Spotify, calendar, desktop automation, workspace file ops, 3D scene generation. Every tool goes through an audit log and permission system.
- Streaming first — all responses stream over SSE. Commands embedded in the stream trigger widgets, maps, Spotify controls, 3D scenes in the UI.
| Personal | Business | |
|---|---|---|
| Best for | Individual daily use | Teams and companies |
| Auth | None required | Multi-user JWT |
| Rate limiting | Off | Sliding-window, configurable |
| Messaging channels | — | Telegram, Discord, Slack, webhook |
| Voice + vision | ✓ | — |
| Health platforms | ✓ | ✓ |
| Spotify + app launcher | ✓ | — |
| Calendar + web search | ✓ | ✓ |
| Docker | luna docker |
luna docker:business |
Switch at any time: change luna_variant=personal or luna_variant=business in .env and restart. No data is lost.
| Capability | Personal | Business |
|---|---|---|
| 🎙 Voice — wake-word, push-to-talk, faster-whisper STT, edge-tts / pyttsx3 TTS | ✓ | — |
| 🧠 Memory — persistent facts, personality state, conversation summaries (SQLite + ChromaDB) | ✓ | ✓ |
| 👁 Vision — screen and camera awareness via moondream, no raw frames stored | ✓ | — |
| ⚡ Automation — app launcher, Spotify control, audio device switcher | ✓ | — |
| 📅 Calendar + Tasks — create, list, update tasks with proactive reminders | ✓ | ✓ |
| 📊 Dashboard — live news, weather, markets, and maps widget layer | ✓ | ✓ |
| 🌐 Web Tools — DuckDuckGo search and page fetch | ✓ | ✓ |
| 🧩 Dynamic Widgets — steps, timelines, code blocks, 3D scenes (Three.js) | ✓ | ✓ |
| 💓 Health Platforms — Fitbit, Google Fit, Oura, Withings, Garmin, Apple Health, Samsung | ✓ | ✓ |
| 🧠 Skills — plain-text agent skills, auto-loaded at runtime, no restart needed | ✓ | ✓ |
| — | ✓ | |
| 🔐 JWT Auth — multi-user tokens, admin user management API | — | ✓ |
| 🚦 Rate Limiting — sliding-window per-IP, configurable burst | — | ✓ |
| 🔒 Private — inference runs locally via Ollama by default, zero telemetry | ✓ | ✓ |
One line in .env switches the provider — no code changes, no restart of anything else.
| Provider | llm_provider |
Key needed |
|---|---|---|
| Ollama (local, default) | ollama |
None |
| NVIDIA NIM | nvidia-nim |
nvidia_nim_api_key |
| Anthropic Claude | anthropic |
anthropic_api_key |
| Google Gemini | google |
google_api_key |
| Groq | groq |
groq_api_key |
| Cohere | cohere |
cohere_api_key |
| Mistral AI | mistral |
mistral_api_key |
| OpenAI / OpenRouter / LM Studio / llama.cpp | openai-compatible |
openai_api_key (optional for local) |
OpenRouter — one key, every major model, pay-as-you-go:
llm_provider=openai-compatible
openai_base_url=https://openrouter.ai/api/v1
openai_api_key=sk-or-...
openai_model=anthropic/claude-opus-4Skills teach Luna new behaviors. Drop a folder into skills/ and it's live on the next request — no Python, no restarts, no wiring.
skills/
└── my-skill/
├── skill.json ← what it does, what tools it can use
└── SKILL.md ← instructions Luna follows
Built-in skills:
| Skill | What it does |
|---|---|
research/ |
Web search with source comparison and cited answers |
coding-agent/ |
Write, edit, debug, and run code in the workspace |
desktop-agent/ |
Multi-step desktop automation with confirmation gates |
dataset-builder/ |
Fetch or generate datasets from real sources with provenance |
document-drafter/ |
Draft reports, proposals, memos, and policies |
file-builder/ |
Create and convert files of any format in the workspace |
job-application-assistant/ |
Tailor resumes, draft cover letters, prep for interviews |
resume-checker/ |
Review, score, and rewrite resumes against a job post |
workspace-suite/ |
Gmail, Calendar, Drive, Outlook, OneDrive, Teams — all in one |
See skills/README.md for a full contributor guide and skills/_template/ for a ready-to-copy starter.
Luna connects to 7 health platforms and normalizes everything into 23 metric types stored locally in SQLite. Adding a new platform takes one Python file — no changes to the router, sync dispatcher, or frontend.
| Platform | Auth | Key Metrics |
|---|---|---|
| Fitbit | OAuth2 | Steps, HR, HRV, sleep stages, SpO2, skin temp, weight, breathing rate |
| Google Fit | OAuth2 | Steps, calories, HR, weight, body fat, SpO2, sleep — all Android wearables |
| Oura Ring | API token | Sleep stages, HRV, resting HR, readiness score, stress, respiratory rate |
| Withings | OAuth2 | Weight, BMI, body fat, blood pressure, HR, sleep |
| Garmin Connect | Credentials | VO2 Max, Body Battery, stress, GPS workouts, sleep, SpO2 |
| Apple Health | Webhook | All HealthKit metrics via iOS "Health Auto Export" app |
| Samsung Health | Webhook | Galaxy Watch metrics via compatible Android exporter |
# Trigger a sync after configuring credentials in .env
curl -X POST http://localhost:8899/api/health/sync
# Ask Luna
# "How was my sleep last night?"
# "What's my HRV trend this week?"
# "Sync my Fitbit and tell me how my recovery looks"Prerequisites: Node.js 18+, Python 3.10+, Ollama installed and running.
git clone https://github.com/Sehastrajit/Luna.git && cd Luna && npm install && npm run luna -- setupThen start Luna:
luna dev # Electron + Vite + FastAPI (full desktop with voice and vision)
luna web # FastAPI + browser UI, no Electron
luna backend # FastAPI onlyRun luna doctor if something doesn't start — it checks Node, Python, Ollama, and Docker in one shot.
Windows installer:
npm run installerBuilds an NSIS Electron installer. On first launch, a setup window lets the user choose Personal or Business, pick their LLM provider, and enter credentials before the backend starts.
The CLI auto-detects the right compose file from your .env:
| Command | When to use |
|---|---|
luna docker |
Personal, CPU (default) |
luna docker:gpu |
Personal, NVIDIA GPU |
luna docker:cloud |
Personal, cloud LLM (no Ollama needed) |
luna docker:business |
Business variant |
# NVIDIA GPU
luna docker:gpu
# Cloud LLM — set llm_provider in .env first
luna docker:cloud
# Business
cp .env.business.example .env
luna docker:businessUpgrading:
git pull && luna dockerData persists in named Docker volumes (luna_data, ollama_data).
| Layer | Tech |
|---|---|
| Shell | Electron |
| UI Framework | React + Vite |
| Language | TypeScript |
| Styling | Tailwind CSS |
| State | Zustand |
| 3D | Three.js |
| Maps | MapLibre GL |
| Layer | Tech |
|---|---|
| API | FastAPI + Uvicorn |
| Database | SQLite |
| Vector store | ChromaDB |
| LLM | Ollama, Anthropic, Google, Groq, Cohere, Mistral, or any OpenAI-compatible endpoint |
| STT | faster-whisper |
| TTS | edge-tts / pyttsx3 |
| HTTP | httpx |
| Purpose | Default |
|---|---|
| Chat | qwen2.5:7b via Ollama (configurable) |
| Embeddings | nomic-embed-text |
| Vision | moondream |
| Code | qwen2.5-coder:7b (coding-agent skill) |
Three layers:
- Electron — starts the desktop shell, launches the FastAPI backend, hosts the React renderer.
- React — renders chat, voice controls, dashboard, maps, dynamic widgets, and 3D scenes.
- FastAPI — owns chat streaming, voice, memory, vision, tool execution, live data, Spotify, scheduling, messaging channels, auth, rate limiting, and all LLM calls.
User input (browser · Electron · Telegram · Discord · Slack · webhook)
│
▼
Variant check (personal | business)
│
▼
Context assembly (memory + personality + calendar + vision + conversation)
│
▼
LLM inference ←── Ollama / NVIDIA NIM / Anthropic / Google / Groq / Cohere / Mistral / OpenAI-compatible
│
▼
Tool execution (web_search · web_fetch · Spotify · calendar · widgets · maps · skills)
│
▼
Memory update (fact extraction · personality update · conversation compaction)
│
▼
Response streamed to UI (or plain-text reply to channel)
Full diagrams: architecture.svg · architecture_ai.svg
Copy .env.example to .env. Never commit .env.
# Variant
luna_variant=personal # personal | business
# Identity
user_name=friend
# LLM — Ollama (default, runs locally)
llm_provider=ollama
ollama_base_url=http://localhost:11434
ollama_model=qwen2.5:7b
# LLM — Anthropic Claude
# llm_provider=anthropic
# anthropic_api_key=sk-ant-...
# anthropic_model=claude-sonnet-4-5
# LLM — any OpenAI-compatible endpoint
# llm_provider=openai-compatible
# openai_base_url=https://openrouter.ai/api/v1
# openai_api_key=sk-or-...
# openai_model=anthropic/claude-opus-4
# LLM — NVIDIA NIM
# llm_provider=nvidia-nim
# nvidia_nim_api_key=nvapi-...
# nvidia_nim_model=meta/llama-3.1-8b-instruct
# Business — auth and rate limiting
# jwt_secret=change-me
# rate_limit_enabled=true
# rate_limit_per_minute=60
# Messaging channels (business)
# telegram_bot_token=
# discord_bot_token=
# slack_bot_token=
# Workspace integrations
# google_workspace_client_id=
# google_workspace_client_secret=
# google_workspace_refresh_token=
# microsoft_workspace_client_id=
# microsoft_workspace_client_secret=
# microsoft_workspace_tenant_id=common
# microsoft_workspace_refresh_token=
# Optional
the_news_api=
spotify_client_id=
spotify_client_secret=Run luna setup at any time to reconfigure interactively.
Any device on your LAN can connect:
# .env
host=0.0.0.0luna web:lanOpen http://YOUR-LAN-IP:5173 on any phone, tablet, or second computer. Voice, camera, and OS-level features depend on browser permissions and are fully supported on the host desktop.
Luna/
├── backend/ # FastAPI server — chat, voice, memory, tools, integrations
│ ├── routers/ # Thin API layer — logic lives in services/
│ ├── services/ # LLM, memory, personality, vision, health platforms, dashboard
│ └── processes/ # Background jobs — memory maintenance, reminders, voice runtime
├── frontend/ # React + Vite UI
│ └── src/components/ # Chat, voice, dashboard, widgets, maps, settings
├── electron/ # Desktop shell — window management, tray, preload
├── skills/ # Built-in agent skills (plain-text, auto-loaded at runtime)
│ └── _template/ # Copy this to create a new skill
├── integrations/ # Platform add-ons — Google Workspace, Office, VS Code extension
├── cli/ # luna CLI entrypoint and command handlers
├── docs-site/ # Next.js documentation site
├── utilities/ # Scripts, tests, architecture diagrams
└── .env.example
Run the smoke suite before opening a PR:
npm run test:smoke # backend syntax + CLI + tool wiring
npm run test:tools # tool-only suite
npm run build # frontend type check + bundleSmoke tests are non-destructive — they do not launch apps, type, lock the screen, switch audio devices, or start playback.
- Fork the repo and create a branch from
main. - Make your changes.
- Run
npm run test:smoke(backend/CLI changes) ornpm run build(frontend changes). - Open a pull request with a clear description of what changed and why.
Adding a skill — the easiest contribution. Copy skills/_template/, fill in skill.json and SKILL.md, and open a PR. No Python knowledge needed. See skills/README.md.
Adding a health integration — copy backend/services/health_integrations/_template.py, subclass HealthIntegration, fill in the manifest and sync() method. Auto-discovered on restart, zero other changes needed. See CONTRIBUTING.md.
- Chat inference runs through local Ollama — no tokens leave your machine by default.
- Memory, facts, and personality state are stored in local SQLite and ChromaDB.
- Vision summaries are generated locally by moondream; no raw frames are stored or transmitted.
- External APIs (news, weather, markets, Spotify) are only contacted when configured and used.
- Keep
.env,data/, and generated memory stores out of version control.
MIT — see LICENSE.