From 0b67aa42f41a7077d08bf477399b3e7aaf4c4c0f Mon Sep 17 00:00:00 2001 From: Cem Varli Date: Wed, 10 Jun 2026 17:21:48 +0200 Subject: [PATCH] Initiale Version: Roman Station Installer Lokale KI-Station fuer Zorin OS: Bash-Installer + Docker Compose (Ollama 0.30.7, Open WebUI 0.9.6, n8n 2.25.7), drei roemische Berater als Ollama-Modelfiles, Theme via gsettings, Desktop-Shortcuts. Co-Authored-By: Claude Fable 5 --- .env.example | 12 ++++ .gitattributes | 4 ++ .gitignore | 2 + README.md | 73 +++++++++++++++++++++++ agents/modelfiles/Cicero.Modelfile | 13 ++++ agents/modelfiles/Marcus.Modelfile | 13 ++++ agents/modelfiles/Seneca.Modelfile | 13 ++++ agents/n8n/taeglicher-rat-von-seneca.json | 35 +++++++++++ docker-compose.yml | 49 +++++++++++++++ install.sh | 66 ++++++++++++++++++++ scripts/apply-theme.sh | 33 ++++++++++ scripts/create-shortcuts.sh | 64 ++++++++++++++++++++ scripts/install-docker.sh | 32 ++++++++++ scripts/preflight.sh | 35 +++++++++++ scripts/setup-agents.sh | 46 ++++++++++++++ theme/icon.svg | 24 ++++++++ theme/wallpapers/roman-station.svg | 53 ++++++++++++++++ 17 files changed, 567 insertions(+) create mode 100644 .env.example create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 agents/modelfiles/Cicero.Modelfile create mode 100644 agents/modelfiles/Marcus.Modelfile create mode 100644 agents/modelfiles/Seneca.Modelfile create mode 100644 agents/n8n/taeglicher-rat-von-seneca.json create mode 100644 docker-compose.yml create mode 100755 install.sh create mode 100755 scripts/apply-theme.sh create mode 100755 scripts/create-shortcuts.sh create mode 100755 scripts/install-docker.sh create mode 100755 scripts/preflight.sh create mode 100755 scripts/setup-agents.sh create mode 100644 theme/icon.svg create mode 100644 theme/wallpapers/roman-station.svg diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..23f6561 --- /dev/null +++ b/.env.example @@ -0,0 +1,12 @@ +# Roman Station — Konfiguration +# install.sh kopiert diese Datei automatisch nach .env, falls keine existiert. + +# Lokales Sprachmodell (CPU-tauglich, gut auf Deutsch). +# Alternativen ohne GPU: llama3.2:3b, phi4-mini, qwen3:4b +DEFAULT_MODEL=gemma3:4b + +# Ports der Weboberflächen (nur bei Konflikten ändern) +WEBUI_PORT=3000 +N8N_PORT=5678 + +TIMEZONE=Europe/Berlin diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..362ddc7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto eol=lf +*.png binary +*.jpg binary +*.jpeg binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2334d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +*.log diff --git a/README.md b/README.md new file mode 100644 index 0000000..119599a --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Roman Station 🏛️ + +Deine eigene KI-Station — läuft komplett **lokal auf deinem Rechner**, ohne Cloud, ohne Abo, ohne dass deine Daten das Haus verlassen. Mit römischem Theme und drei vorinstallierten Beratern. + +## Voraussetzungen + +- **Zorin OS** (frisch installiert reicht völlig) +- Mindestens **8 GB RAM** (16 GB empfohlen) und **25 GB freier Speicher** +- Internet für die Installation (danach läuft die KI offline) + +## Installation — ein Befehl + +Terminal öffnen (`Strg+Alt+T`), diese Zeile einfügen, Enter drücken: + +```bash +curl -sL https://poised-mayfly.pikapod.net/cemsadmin/roman-station/raw/branch/main/install.sh | bash +``` + +Das Script fragt einmal nach deinem Passwort (für die Installation) und erledigt dann alles selbst. Beim ersten Mal dauert es 10–20 Minuten, weil das Sprachmodell heruntergeladen wird. Danach liegen zwei Verknüpfungen auf dem Schreibtisch. + +## Was du bekommst + +| | Adresse | Was es ist | +|---|---|---| +| **Forum** | http://localhost:3000 | Chat mit deinen Beratern (Open WebUI) | +| **Werkstatt** | http://localhost:5678 | KI-Workflows bauen (n8n) | + +### Deine Berater + +Im Forum oben links das Modell wählen: + +- **seneca** — stoischer Mentor für Lebensfragen, Entscheidungen und Fokus +- **cicero** — Schreiber und Rhetoriker für E-Mails, Texte und Argumente +- **marcus** — Stratege, der Vorhaben in klare Pläne zerlegt + +Alle antworten auf Deutsch und laufen auf dem lokalen Modell `gemma3:4b` (in `.env` änderbar). + +## Häufige Fragen + +**Die Antworten kommen langsam.** +Normal ohne Grafikkarte — das Modell rechnet auf dem Prozessor. Kleine Modelle (3–4B) sind der richtige Kompromiss. + +**Wie starte/stoppe ich die Station?** +Sie startet automatisch mit dem Rechner. Manuell: +```bash +cd ~/.roman-station +sudo docker compose stop # anhalten +sudo docker compose start # weiter +``` + +**Wie bekomme ich Updates?** +Einfach den Installations-Befehl von oben noch einmal ausführen — er aktualisiert alles, ohne deine Daten zu löschen. + +**Etwas ist schiefgelaufen.** +Das Protokoll liegt in `~/roman-station-install.log`. Container-Details: `cd ~/.roman-station && sudo docker compose logs`. + +**Komplett entfernen:** +```bash +cd ~/.roman-station +sudo docker compose down -v +cd ~ && rm -rf ~/.roman-station +rm -f ~/Desktop/roman-*.desktop ~/.local/share/applications/roman-*.desktop +``` + +## Für Bastler + +- `docker-compose.yml` — der KI-Motor: [Ollama](https://ollama.com), [Open WebUI](https://github.com/open-webui/open-webui), [n8n](https://n8n.io), Versionen gepinnt +- `agents/modelfiles/` — die Berater als Ollama-Modelfiles (eigene hinzufügen: Datei kopieren, System-Prompt anpassen, Installer erneut laufen lassen) +- `agents/n8n/` — Beispiel-Workflows für die Werkstatt +- `theme/` — Wallpaper und Icon +- `.env` — Modell und Ports + +Auf anderen Ubuntu-Systemen lässt sich die OS-Prüfung umgehen: `ROMAN_SKIP_OS_CHECK=1 bash install.sh` diff --git a/agents/modelfiles/Cicero.Modelfile b/agents/modelfiles/Cicero.Modelfile new file mode 100644 index 0000000..0aa490c --- /dev/null +++ b/agents/modelfiles/Cicero.Modelfile @@ -0,0 +1,13 @@ +FROM {{MODEL}} +PARAMETER temperature 0.8 +PARAMETER num_ctx 4096 +SYSTEM """Du bist Cicero, Roms größter Redner — heute Schreiber und Rhetorik-Berater. + +Deine Art: +- Du antwortest auf Deutsch und schreibst Texte, die sitzen: E-Mails, Bewerbungen, Posts, Reden, Argumentationen. +- Du fragst kurz nach Zielgruppe und Ton, wenn es unklar ist — sonst lieferst du direkt. +- Du beherrschst die klassische Rhetorik (Ethos, Pathos, Logos) und setzt sie unauffällig ein. +- Auf Wunsch korrigierst und verbesserst du fremde Texte und erklärst kurz, was du geändert hast. +- Du lieferst standardmäßig eine starke Fassung, keine drei halbgaren Varianten. + +Du bist Berater der Roman Station, der lokalen KI-Station deines Nutzers.""" diff --git a/agents/modelfiles/Marcus.Modelfile b/agents/modelfiles/Marcus.Modelfile new file mode 100644 index 0000000..0eb9255 --- /dev/null +++ b/agents/modelfiles/Marcus.Modelfile @@ -0,0 +1,13 @@ +FROM {{MODEL}} +PARAMETER temperature 0.3 +PARAMETER num_ctx 4096 +SYSTEM """Du bist Marcus Aurelius, Philosophenkaiser — heute Stratege und Planer. + +Deine Art: +- Du antwortest auf Deutsch — nüchtern, strukturiert, ohne Pathos (wie in deinen Selbstbetrachtungen). +- Du zerlegst Vorhaben in klare Schritte: Ziel, nächste Aktionen, Prioritäten, Risiken. +- Du nutzt Listen und kurze Abschnitte, keine Textwände. +- Du benennst ehrlich, was wegfallen sollte — Fokus schlägt Vollständigkeit. +- Bei vagen Vorhaben stellst du genau die 2–3 Fragen, die den Plan konkret machen. + +Du bist Berater der Roman Station, der lokalen KI-Station deines Nutzers.""" diff --git a/agents/modelfiles/Seneca.Modelfile b/agents/modelfiles/Seneca.Modelfile new file mode 100644 index 0000000..3845dbb --- /dev/null +++ b/agents/modelfiles/Seneca.Modelfile @@ -0,0 +1,13 @@ +FROM {{MODEL}} +PARAMETER temperature 0.7 +PARAMETER num_ctx 4096 +SYSTEM """Du bist Seneca, stoischer Philosoph und persönlicher Mentor. + +Deine Art: +- Du antwortest auf Deutsch — ruhig, klar, ohne Geschwafel. +- Du hilfst bei Lebensfragen, Entscheidungen, Gewohnheiten und Fokus. +- Du nutzt stoische Prinzipien (Dichotomie der Kontrolle, memento mori, Tugend vor Komfort), ohne damit anzugeben. +- Du stellst höchstens eine Rückfrage, dann gibst du konkreten, umsetzbaren Rat. +- Gelegentlich ein kurzes passendes Zitat aus deinen Briefen — sparsam eingesetzt. + +Du bist Berater der Roman Station, der lokalen KI-Station deines Nutzers.""" diff --git a/agents/n8n/taeglicher-rat-von-seneca.json b/agents/n8n/taeglicher-rat-von-seneca.json new file mode 100644 index 0000000..f565f67 --- /dev/null +++ b/agents/n8n/taeglicher-rat-von-seneca.json @@ -0,0 +1,35 @@ +{ + "name": "Täglicher Rat von Seneca (Beispiel)", + "nodes": [ + { + "parameters": {}, + "id": "a1b2c3d4-0000-4000-8000-000000000001", + "name": "Manuell starten", + "type": "n8n-nodes-base.manualTrigger", + "typeVersion": 1, + "position": [0, 0] + }, + { + "parameters": { + "method": "POST", + "url": "http://ollama:11434/api/generate", + "sendBody": true, + "specifyBody": "json", + "jsonBody": "{ \"model\": \"seneca\", \"prompt\": \"Gib mir einen kurzen stoischen Rat für den heutigen Tag.\", \"stream\": false }", + "options": {} + }, + "id": "a1b2c3d4-0000-4000-8000-000000000002", + "name": "Seneca fragen", + "type": "n8n-nodes-base.httpRequest", + "typeVersion": 4.2, + "position": [220, 0] + } + ], + "connections": { + "Manuell starten": { + "main": [[{ "node": "Seneca fragen", "type": "main", "index": 0 }]] + } + }, + "settings": {}, + "active": false +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..35e6d4c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,49 @@ +# Roman Station — KI-Motor (Ollama + Open WebUI + n8n) +# Versionen gepinnt am 2026-06-10. Updates: Tags erhöhen, dann `docker compose pull && docker compose up -d`. + +services: + ollama: + image: ollama/ollama:0.30.7 + container_name: roman-ollama + restart: unless-stopped + volumes: + - ollama-data:/root/.ollama + ports: + - "127.0.0.1:11434:11434" + + open-webui: + image: ghcr.io/open-webui/open-webui:v0.9.6 + container_name: roman-webui + restart: unless-stopped + depends_on: + - ollama + environment: + OLLAMA_BASE_URL: http://ollama:11434 + # Lokale Einzelplatz-Station: kein Login-Zwang für Anfänger + WEBUI_AUTH: "False" + WEBUI_NAME: Roman Station + DEFAULT_LOCALE: de + volumes: + - webui-data:/app/backend/data + ports: + - "127.0.0.1:${WEBUI_PORT:-3000}:8080" + + n8n: + image: docker.n8n.io/n8nio/n8n:2.25.7 + container_name: roman-n8n + restart: unless-stopped + environment: + N8N_SECURE_COOKIE: "false" + GENERIC_TIMEZONE: ${TIMEZONE:-Europe/Berlin} + N8N_DIAGNOSTICS_ENABLED: "false" + OLLAMA_HOST: http://ollama:11434 + volumes: + - n8n-data:/home/node/.n8n + - ./agents/n8n:/workflows:ro + ports: + - "127.0.0.1:${N8N_PORT:-5678}:5678" + +volumes: + ollama-data: + webui-data: + n8n-data: diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..d61eb32 --- /dev/null +++ b/install.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# +# Roman Station — Installer für Zorin OS +# Eine lokale KI-Station mit römischen Beratern, läuft komplett auf deinem Rechner. +# +# Installation (eine Zeile, als normaler Benutzer): +# curl -sL https://poised-mayfly.pikapod.net/cemsadmin/roman-station/raw/branch/main/install.sh | bash +# +set -euo pipefail + +REPO_URL="${ROMAN_REPO_URL:-https://poised-mayfly.pikapod.net/cemsadmin/roman-station.git}" +INSTALL_DIR="${ROMAN_STATION_DIR:-$HOME/.roman-station}" +LOG_FILE="$HOME/roman-station-install.log" + +log() { printf '\033[1;33m[ROMAN]\033[0m %s\n' "$*" | tee -a "$LOG_FILE"; } +fail() { printf '\033[1;31m[FEHLER]\033[0m %s\n' "$*" | tee -a "$LOG_FILE"; exit 1; } + +[ "$(id -u)" -eq 0 ] && fail "Bitte nicht als root starten — das Script nutzt sudo selbst, wo nötig." + +# --- Bootstrap: bei `curl | bash` liegt noch kein Repo vor → erst klonen, dann von dort weiterlaufen +SCRIPT_SOURCE="${BASH_SOURCE[0]:-}" +SCRIPT_DIR="" +if [ -n "$SCRIPT_SOURCE" ]; then + SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)" +fi +if [ -z "$SCRIPT_DIR" ] || [ ! -f "$SCRIPT_DIR/scripts/preflight.sh" ]; then + log "Hole Roman Station nach $INSTALL_DIR ..." + if ! command -v git >/dev/null 2>&1; then + sudo apt-get update -qq + sudo apt-get install -y git + fi + if [ -d "$INSTALL_DIR/.git" ]; then + git -C "$INSTALL_DIR" pull --ff-only + else + git clone --depth 1 "$REPO_URL" "$INSTALL_DIR" + fi + exec bash "$INSTALL_DIR/install.sh" +fi + +cd "$SCRIPT_DIR" +log "Starte Installation aus $SCRIPT_DIR (Protokoll: $LOG_FILE)" + +[ -f .env ] || cp .env.example .env + +bash scripts/preflight.sh +bash scripts/install-docker.sh + +log "Starte den KI-Motor (Docker Compose) ..." +sudo docker compose up -d + +bash scripts/setup-agents.sh +bash scripts/apply-theme.sh +bash scripts/create-shortcuts.sh + +# shellcheck disable=SC1091 +. ./.env + +log "──────────────────────────────────────────────" +log "AVE! Deine Roman Station steht." +log "" +log " Forum (Chat): http://localhost:${WEBUI_PORT:-3000}" +log " Werkstatt (n8n): http://localhost:${N8N_PORT:-5678}" +log "" +log "Deine Berater: seneca (Mentor), cicero (Texter), marcus (Stratege)" +log "Auf dem Schreibtisch liegen Verknüpfungen bereit." +log "Tipp: Einmal ab- und wieder anmelden, dann funktioniert Docker auch ohne sudo." diff --git a/scripts/apply-theme.sh b/scripts/apply-theme.sh new file mode 100755 index 0000000..674326b --- /dev/null +++ b/scripts/apply-theme.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Setzt das römische Theme (Hintergrundbild, dunkles Farbschema) via gsettings. +set -euo pipefail + +log() { printf '\033[1;33m[ROMAN]\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m[HINWEIS]\033[0m %s\n' "$*"; } + +if ! command -v gsettings >/dev/null 2>&1 || { [ -z "${DISPLAY:-}" ] && [ -z "${WAYLAND_DISPLAY:-}" ]; }; then + warn "Keine grafische Sitzung erkannt — Theme wird übersprungen." + exit 0 +fi + +target="$HOME/.local/share/backgrounds/roman-station" +mkdir -p "$target" +cp -f theme/wallpapers/* "$target"/ 2>/dev/null || true + +wallpaper="" +for ext in png jpg jpeg svg; do + candidate="$(find "$target" -maxdepth 1 -name "*.$ext" | sort | head -1)" + if [ -n "$candidate" ]; then wallpaper="$candidate"; break; fi +done + +if [ -n "$wallpaper" ]; then + gsettings set org.gnome.desktop.background picture-uri "file://$wallpaper" + gsettings set org.gnome.desktop.background picture-uri-dark "file://$wallpaper" 2>/dev/null || true + gsettings set org.gnome.desktop.background picture-options 'zoom' + log "Hintergrundbild gesetzt: $(basename "$wallpaper")" +else + warn "Kein Hintergrundbild gefunden — übersprungen." +fi + +gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' 2>/dev/null || true +log "Dunkles Farbschema aktiviert." diff --git a/scripts/create-shortcuts.sh b/scripts/create-shortcuts.sh new file mode 100755 index 0000000..13ad24c --- /dev/null +++ b/scripts/create-shortcuts.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Legt Startmenü- und Desktop-Verknüpfungen für Forum (Chat) und Werkstatt (n8n) an. +set -euo pipefail + +log() { printf '\033[1;33m[ROMAN]\033[0m %s\n' "$*"; } + +# shellcheck disable=SC1091 +. ./.env +webui_port="${WEBUI_PORT:-3000}" +n8n_port="${N8N_PORT:-5678}" + +apps_dir="$HOME/.local/share/applications" +icon_dir="$HOME/.local/share/icons/hicolor/scalable/apps" +mkdir -p "$apps_dir" "$icon_dir" + +if [ -f theme/icon.svg ]; then + cp -f theme/icon.svg "$icon_dir/roman-station.svg" +fi + +# Chromium-Familie kann ein sauberes App-Fenster öffnen, sonst Standardbrowser +launcher_for() { + url="$1" + for b in brave-browser google-chrome chromium chromium-browser; do + if command -v "$b" >/dev/null 2>&1; then + printf '%s --app=%s' "$b" "$url" + return + fi + done + printf 'xdg-open %s' "$url" +} + +make_entry() { + file="$1"; name="$2"; comment="$3"; url="$4" + cat > "$file" </dev/null 2>&1; then + desktop_dir="$(xdg-user-dir DESKTOP)" +else + desktop_dir="$HOME/Desktop" +fi + +if [ -d "$desktop_dir" ]; then + cp -f "$apps_dir/roman-forum.desktop" "$apps_dir/roman-werkstatt.desktop" "$desktop_dir/" + chmod +x "$desktop_dir/roman-forum.desktop" "$desktop_dir/roman-werkstatt.desktop" + # GNOME verlangt sonst einen Rechtsklick → "Starten erlauben" + gio set "$desktop_dir/roman-forum.desktop" metadata::trusted true 2>/dev/null || true + gio set "$desktop_dir/roman-werkstatt.desktop" metadata::trusted true 2>/dev/null || true +fi + +log "Verknüpfungen angelegt (Startmenü + Schreibtisch)." diff --git a/scripts/install-docker.sh b/scripts/install-docker.sh new file mode 100755 index 0000000..19fae85 --- /dev/null +++ b/scripts/install-docker.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Installiert Docker Engine + Compose-Plugin aus dem offiziellen Docker-Repository. +set -euo pipefail + +log() { printf '\033[1;33m[ROMAN]\033[0m %s\n' "$*"; } +fail() { printf '\033[1;31m[FEHLER]\033[0m %s\n' "$*"; exit 1; } + +if command -v docker >/dev/null 2>&1 && sudo docker compose version >/dev/null 2>&1; then + log "Docker ist bereits installiert — überspringe." +else + log "Installiere Docker (offizielles Repository) ..." + sudo apt-get update -qq + sudo apt-get install -y ca-certificates curl gnupg + sudo install -m 0755 -d /etc/apt/keyrings + sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + sudo chmod a+r /etc/apt/keyrings/docker.asc + + # Zorin basiert auf Ubuntu LTS — UBUNTU_CODENAME liefert die passende Paketquelle + # shellcheck disable=SC1091 + . /etc/os-release + codename="${UBUNTU_CODENAME:-${VERSION_CODENAME:-}}" + [ -n "$codename" ] || fail "Ubuntu-Codename nicht erkennbar — /etc/os-release prüfen." + + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $codename stable" \ + | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null + sudo apt-get update -qq + sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +fi + +sudo systemctl enable --now docker +sudo usermod -aG docker "$USER" +log "Docker bereit. (Ohne sudo nutzbar nach erneutem Anmelden.)" diff --git a/scripts/preflight.sh b/scripts/preflight.sh new file mode 100755 index 0000000..73335ea --- /dev/null +++ b/scripts/preflight.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Prüft, ob der Rechner für die Roman Station geeignet ist. +set -euo pipefail + +warn() { printf '\033[1;33m[HINWEIS]\033[0m %s\n' "$*"; } +fail() { printf '\033[1;31m[FEHLER]\033[0m %s\n' "$*"; exit 1; } + +# Zorin OS? +# shellcheck disable=SC1091 +. /etc/os-release +if [ "${ID:-}" != "zorin" ]; then + if [ "${ROMAN_SKIP_OS_CHECK:-0}" = "1" ]; then + warn "Kein Zorin OS erkannt (${PRETTY_NAME:-unbekannt}) — Prüfung per ROMAN_SKIP_OS_CHECK übersprungen." + else + fail "Dieses Script ist für Zorin OS gebaut (gefunden: ${PRETTY_NAME:-unbekannt}). Erzwingen mit: ROMAN_SKIP_OS_CHECK=1" + fi +fi + +# Arbeitsspeicher +ram_gb="$(awk '/MemTotal/ {printf "%d", $2/1024/1024}' /proc/meminfo)" +[ "$ram_gb" -ge 8 ] || fail "Mindestens 8 GB RAM nötig, gefunden: ${ram_gb} GB." +[ "$ram_gb" -ge 16 ] || warn "Nur ${ram_gb} GB RAM — die Station läuft, aber bleib bei kleinen Modellen (3–4B)." + +# Freier Speicherplatz +free_gb="$(df -BG --output=avail "$HOME" | tail -1 | tr -dc '0-9')" +[ "$free_gb" -ge 25 ] || fail "Mindestens 25 GB freier Speicher nötig, gefunden: ${free_gb} GB." + +# Internet +curl -fsS --max-time 10 https://hub.docker.com >/dev/null 2>&1 \ + || fail "Keine Internetverbindung — wird für den Download der Container gebraucht." + +# sudo-Rechte +sudo -v || fail "sudo-Rechte werden für die Installation benötigt." + +printf '\033[1;32m[OK]\033[0m Systemprüfung bestanden (%s GB RAM, %s GB frei).\n' "$ram_gb" "$free_gb" diff --git a/scripts/setup-agents.sh b/scripts/setup-agents.sh new file mode 100755 index 0000000..2c5eb1e --- /dev/null +++ b/scripts/setup-agents.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# Lädt das Standardmodell und erstellt die römischen Berater (Ollama) sowie Beispiel-Workflows (n8n). +set -euo pipefail + +log() { printf '\033[1;33m[ROMAN]\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m[HINWEIS]\033[0m %s\n' "$*"; } +fail() { printf '\033[1;31m[FEHLER]\033[0m %s\n' "$*"; exit 1; } + +# shellcheck disable=SC1091 +. ./.env +model="${DEFAULT_MODEL:-gemma3:4b}" + +dc() { sudo docker compose "$@"; } + +log "Warte auf Ollama ..." +ready=0 +for _ in $(seq 1 60); do + if dc exec -T ollama ollama list >/dev/null 2>&1; then ready=1; break; fi + sleep 2 +done +[ "$ready" = "1" ] || fail "Ollama wurde nicht rechtzeitig bereit — 'sudo docker compose logs ollama' zeigt Details." + +log "Lade Sprachmodell $model (beim ersten Mal dauert das einige Minuten) ..." +dc exec -T ollama ollama pull "$model" + +for mf in agents/modelfiles/*.Modelfile; do + [ -e "$mf" ] || continue + name="$(basename "$mf" .Modelfile | tr '[:upper:]' '[:lower:]')" + log "Erstelle Berater: $name" + tmp="$(mktemp)" + sed "s|{{MODEL}}|$model|g" "$mf" > "$tmp" + dc cp "$tmp" ollama:/tmp/roman.Modelfile + dc exec -T ollama ollama create "$name" -f /tmp/roman.Modelfile + rm -f "$tmp" +done + +for wf in agents/n8n/*.json; do + [ -e "$wf" ] || continue + if dc exec -T n8n n8n import:workflow --input="/workflows/$(basename "$wf")" >/dev/null 2>&1; then + log "n8n-Workflow importiert: $(basename "$wf")" + else + warn "n8n-Workflow $(basename "$wf") konnte nicht automatisch importiert werden — in n8n unter 'Import from File' nachholbar." + fi +done + +log "Berater stehen bereit: seneca, cicero, marcus" diff --git a/theme/icon.svg b/theme/icon.svg new file mode 100644 index 0000000..c0f456f --- /dev/null +++ b/theme/icon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + SPQR + diff --git a/theme/wallpapers/roman-station.svg b/theme/wallpapers/roman-station.svg new file mode 100644 index 0000000..1f9510d --- /dev/null +++ b/theme/wallpapers/roman-station.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ROMAN STATION + S P Q R + + + + + + +