mood
by FlorianWilk
README.md
# mood
**Gib deiner KI ein Gesicht.** `mood` ist ein physisches Stimmungs-Display fürs
Terminal: dein LLM zeigt seine aktuelle Stimmung als lebendiges, lokal mit Stable
Diffusion generiertes ASCII-Gesicht — proaktiv, während ihr zusammenarbeitet.
<img src="docs/hero.png" width="560" alt="mood — focused, ready to dig into network config">
Unter der Haube: Eine Emotion (z.B. `smiling`) wird in einen Prompt eingesetzt, auf
der GPU ein Bild generiert und als ASCII-Helligkeitsgradient im Terminal angezeigt.
Per MCP ruft die KI das Tool **`feel(emotion)`** selbst auf, wann immer sich ihre
Stimmung ändert — wie ein Mensch unwillkürlich das Gesicht verzieht.
## Schnellstart
Voraussetzung: [`uv`](https://docs.astral.sh/uv/) und eine GPU — **NVIDIA** (Linux,
CUDA) oder **Apple Silicon** (macOS, MPS). Ohne GPU läuft es auf der CPU, aber sehr
langsam. macOS-Details siehe unten.
```sh
./run.sh
```
Startet das Stimmungs-Display (Listener auf Port 8765) mit den Standard-Settings.
Beim ersten Mal wird die Umgebung eingerichtet und das Modell von HuggingFace geladen
(mit sichtbarem Fortschritt). Dann ist das Display bereit.
Damit deine KI es ansteuert, die MCP-Bridge in Claude Code registrieren (siehe
[MCP in Claude Code](#mcp-in-claude-code)):
```sh
./install-mcp.sh
```
Ab jetzt zeigt die KI ihre Stimmung von selbst auf dem Display. `feel(emotion)` gibt
im Chat nur `"ok"` zurück (das Bild geht aufs Display, nicht in die Konversation).
## Selbst ausprobieren
```sh
echo "laughing" | nc 127.0.0.1 8765 # Emotion ans laufende Display schicken
./run.sh "a red sports car" # einmaliges Bild (kein '::' -> One-Shot)
```
Weitere Stimmungen:
<img src="docs/demo.png" width="300" alt="relieved and laughing"> <img src="docs/demo2.png" width="300" alt="very happy">
## Aussehen anpassen
Das Gesicht entsteht aus einem Prompt-Template mit `::` als Platzhalter für die
Emotion. Standard ist ein Vault-Boy-Stil (Fallout). Alles per Env überschreibbar
(siehe `.env.example`, eine `.env` wird automatisch geladen):
| Variable | Default | Wirkung |
|----------|---------|---------|
| `MOOD_PROMPT` | `girl, :: face, retro poster style, …` | Prompt-Template (`::` = Emotion) |
| `MOOD_MODEL` | `sd15` | `sdxl`, `sd15`, `flux`*, `qwen`* |
| `MOOD_LORA` | `vaultboy` | LoRA-Kurzname / Pfad (`''` = keine) |
| `MOOD_RAMP` | `ink` | ASCII-Rampe: `ink`, `acid`, `blocks`, `minimal`, … |
| `MOOD_COLOR` | `green` | `mono`, Akzent (`green`/`amber`/`cyan`/`white`) oder `palette` (echte Bildfarben, auf 8 klare ANSI-Farben reduziert) |
| `MOOD_MODELS_ROOT` | – | lokale Modelle bevorzugen statt HF-Download |
Volle Optionsliste: `./run.sh --help`. CLI-Flags überschreiben Env überschreiben `.env`.
Mit `--color palette` werden statt eines Akzents echte Bildfarben gerendert (auf ein
kleines, klares Set reduziert):
<img src="docs/palette.png" width="420" alt="--color palette — happy, solved the issue">
*`--color palette` · „happy, solved the issue"*
## macOS / Apple Silicon
Läuft nativ auf M1/M2/M3 über Apples MPS-Backend — **gleiche Codebasis wie Linux**,
kein CUDA und kein Docker nötig:
```sh
# uv installieren (falls noch nicht vorhanden):
curl -LsSf https://astral.sh/uv/install.sh | sh
./run.sh
```
`uv sync` zieht automatisch das passende torch (mit MPS) von PyPI — der CUDA-Index
greift nur unter Linux. Die App erkennt das Gerät selbst (CUDA → MPS → CPU). Modelle
landen im HuggingFace-Cache (`~/.cache/huggingface`).
- Die erste Generierung lädt das Modell (mehrere GB); danach wenige Sekunden pro Bild
(je nach Chip). MPS ist langsamer als eine dedizierte NVIDIA-GPU, aber gut nutzbar.
- `nc` ist vorinstalliert; MCP-Bridge (`./install-mcp.sh`) funktioniert identisch.
- **Docker bringt auf dem Mac nichts:** Container haben dort keinen Zugriff auf die
Apple-GPU (Metal/MPS) — nur CPU, also viel zu langsam. Auf dem Mac immer `./run.sh`
nativ nutzen. Das Docker-Setup unten ist ausschließlich für Linux + NVIDIA.
## MCP in Claude Code
```sh
./install-mcp.sh
```
Registriert die Bridge (Tool `feel`) mit den richtigen Pfaden — funktioniert auf
Linux und macOS. Danach Claude Code neu starten und `./run.sh` laufen lassen.
## Per Docker
Braucht NVIDIA-Treiber + nvidia-container-toolkit. Modelle landen auf dem Host in
`./models` und bleiben erhalten.
```sh
docker compose build
docker compose up # Display/Listener auf :8765
docker compose run --rm mood "a cat" # einmaliges Bild
```
## Modi
- **Display/Listener** (Default, Prompt mit `::`): hält die Pipeline, jede gesendete
Emotion wird gerendert. CTRL-C beendet.
- **One-Shot** (Prompt ohne `::`): ein Bild, dann Ende.
- **MCP-Bridge** (`-m`): leitet `feel(emotion)` an den Listener weiter; lädt selbst
kein Modell → nur eine Pipeline im VRAM.
\* `flux`/`qwen` sind experimentell (große/gated Repos).
## Lizenz
MIT — siehe `LICENSE`.