Metadata-Version: 2.5
Name: nixorb
Version: 0.3.3
Summary: Floating AI assistant orb for Arch Linux — KDE Plasma 6 Wayland
Project-URL: Homepage, https://github.com/minerofthesoal/nixorb
Project-URL: Repository, https://github.com/minerofthesoal/nixorb
Project-URL: Issues, https://github.com/minerofthesoal/nixorb/issues
Author: NixOrb Contributors
License: MIT
License-File: LICENSE
Keywords: ai,asr,assistant,kde,llm,local,tts,wayland
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Desktop Environment
Requires-Python: >=3.12
Requires-Dist: aiohttp>=3.9.5
Requires-Dist: chromadb>=0.5.3
Requires-Dist: cryptography>=42.0
Requires-Dist: faster-whisper>=1.0.3
Requires-Dist: numpy>=1.26.0
Requires-Dist: pydantic-settings>=2.3.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: pynput>=1.7.6
Requires-Dist: pyside6>=6.7.0
Requires-Dist: qasync>=0.27.1
Requires-Dist: sounddevice>=0.4.7
Requires-Dist: soundfile>=0.12.1
Requires-Dist: tomli-w>=1.0.0
Requires-Dist: typer[all]>=0.12.3
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-aiohttp>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-qt>=4.2; extra == 'dev'
Requires-Dist: pytest>=8.2; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: huggingface
Requires-Dist: accelerate>=0.33.0; extra == 'huggingface'
Requires-Dist: huggingface-hub>=0.24.0; extra == 'huggingface'
Requires-Dist: transformers>=4.44.0; extra == 'huggingface'
Provides-Extra: llama-cpp
Requires-Dist: llama-cpp-python>=0.2.90; extra == 'llama-cpp'
Provides-Extra: openai
Requires-Dist: openai>=1.40.0; extra == 'openai'
Provides-Extra: wakeword
Requires-Dist: openwakeword>=0.6.0; extra == 'wakeword'
Description-Content-Type: text/markdown

# NixOrb v2.0 🌐

**Floating AI assistant orb for Arch Linux — KDE Plasma 6 Wayland — Local-Only**

A complete ground-up remake of NixOrb with a focus on local AI, rock-solid Qt6 stability, and clean modular architecture.

---

## What's New in v2.0

- **Local-only AI** — Ollama backend, no API keys needed
- **Fixed Qt errors** — Proper qasync integration, QSocketNotifier fixes, accessibility bridge disabled
- **Simplified architecture** — Removed broken backends, focused on what works
- **Better VRAM management** — Priority eviction keeps GTX 1080 from OOM
- **Offline TTS** — Piper + espeak-ng fallback
- **Improved settings** — GUI settings editor with live updates

## Architecture Overview

![NixOrb Architecture Pipeline](docs/architecture_pipeline.png)

## Quick Start

### Install (Arch Linux)

```bash
git clone https://github.com/minerofthesoal/nixorb.git
cd nixorb
chmod +x install.sh
./install.sh
```

### Start NixOrb

```bash
nixorb start          # Launch the floating orb
nixorb trigger        # Activate the running orb (bind to a KDE shortcut)
nixorb status         # Check system status
nixorb quit           # Shut the running orb down
nixorb ask "What is 2+2?"   # One-shot query
nixorb check          # Check dependencies
```

`nixorb trigger` talks to the running instance over a Unix socket in
`$XDG_RUNTIME_DIR`, so it works the same under Wayland, X11, or a bare TTY —
which is what makes it usable as a KDE global shortcut.

## Pipeline Flow

```
Trigger (Hotkey/WakeWord/Click)
  → Record Audio (sounddevice + VAD)
  → Transcribe (faster-whisper INT8, ~2.1GB VRAM)
  → Think (Ollama LLM stream, localhost:11434)
  → Speak (Piper TTS, offline)
  → Execute (<ACTION> sandboxed bash)
```

## VRAM Budget (GTX 1080 8GB)

| Component | VRAM | Priority |
|-----------|------|----------|
| Whisper Large v3 INT8 | ~2.1 GB | LOW — evicted first |
| Ollama LLM (loaded by Ollama) | ~4.0 GB | HIGH |
| Piper TTS | ~0.1 GB | MEDIUM |
| System + KDE | ~0.5 GB | reserved |
| Safety buffer | 0.25 GB | reserved |

## Configuration

Edit `~/.config/nixorb/config.toml` or use the GUI (right-click orb → Settings):

```toml
hotkey = "Ctrl+Alt+Space"
orb_size = 88
llm_model = "llama3.2"
ollama_host = "http://localhost:11434"
tts_backend = "piper"

# Requires the optional extra: pip install 'nixorb[wakeword]'
wake_word_enabled = false

# Ask before running every command the model emits.
require_action_confirmation = true
```

See `config/default.toml` for every option with comments.

## Orb States

The orb has no caption — its colour is the state, and the tray tooltip spells
it out in words.

| State | Colour | Meaning |
|-------|--------|---------|
| Idle | Clay `#C96442` | Waiting for you |
| Listening | Sage `#5E9C7E` | Recording; the ring tracks your voice |
| Thinking | Amber `#D9A441` | Querying the model |
| Speaking | Lit clay `#E08A62` | Talking back |
| Error | Rust `#B3453E` | Something failed — check the log |

## Keyboard Shortcuts

| Action | Default | Notes |
|--------|---------|-------|
| Activate | `Ctrl+Alt+Space` | Global hotkey (via pynput/XWayland) |
| KDE Shortcut | Custom | System Settings → Shortcuts, running `nixorb trigger` |
| Orb double-click | Double-click | Direct activation |
| Orb right-click | Right-click | Menu: Activate / Settings / Quit |
| Opacity | Scroll wheel | While hovering over orb |
| Drag | Click+drag | Reposition the orb |

## Project Structure

```
nixorb/
├── core/           # Event bus, VRAM manager
├── asr/            # Whisper speech-to-text + wake word
├── llm/            # Ollama local LLM backend
├── tts/            # Piper text-to-speech
├── ui/             # Qt6 UI (orb, tray, settings, hotkey)
├── action/         # Sandboxed command execution + clipboard
├── memory/         # ChromaDB vector memory
├── plugins/        # Plugin loader
├── utils/          # Paths, logging, web search
├── vision/         # Screen capture
├── main.py         # Entry point
├── cli.py          # CLI interface
└── settings.py     # Configuration
```

## Dependencies

- **System**: `python 3.12+`, `qt6-base`, `qt6-declarative`, `qt6-wayland`, `portaudio`, `wl-clipboard`, `grim`, `ollama`
- **AUR**: `piper-tts` (speech). Note its binary is `piper-tts` — Arch's
  `piper` package is the unrelated gaming-mouse tool. `espeak-ng` is the
  fallback if Piper is missing.
- **Python**: See `requirements.txt` / `pyproject.toml`

## Troubleshooting

NixOrb writes everything it does to `~/.local/share/nixorb/logs/nixorb.log`.
Start with `nixorb status` — it reports whether Ollama is actually reachable
and whether the configured model is installed.

| Symptom | Check |
|---|---|
| Orb never appears | `qt6-declarative` and `qt6-wayland` installed? The log prints any QML error. |
| `nixorb: command not found` | `~/.local/bin` on your `PATH` (the installer links it there). |
| Orb appears, nothing happens on activate | `nixorb status` — Ollama unreachable, or the model isn't pulled. |
| It speaks no audio | `yay -S piper-tts` (AUR), or install `espeak-ng`; the log says which is missing. |
| `nixorb trigger` says not running | Start the orb first; `nixorb status` shows the control socket. |
| Commands are always denied | Approve the confirmation dialog, or set `require_action_confirmation = false`. |
| Actions do nothing when run as root | NixOrb disables command execution as root — run it as your normal user. |

## Testing

```bash
pip install -e ".[dev]"
pytest tests/ -v
```

## License

MIT © NixOrb Contributors
