DEEN

KnowSora

Lokale, private KI-Wissensdatenbank — läuft standardmäßig komplett offline auf deinem Rechner. Dokumente und Web-Seiten werden in Vektoren überführt und lassen sich per Chat mit einem lokalen LLM oder optional OpenAI / Gemini / Claude abfragen.

Installation

KnowSora — Installation & Betrieb

KnowSora ist ein selbst-gehosteter KI-Assistent mit RAG-Wissensdatenbanken, neun austauschbaren LLM-Providern (inkl. xAI Grok und OpenRouter), einem Skill-System mit eingebauten Tools (KI-Bild- und Video-Generierung, Projekt-Datei- Zugriff für jede KI, Shell-Ausführung), Projekt-Verzeichnissen mit universellem File-Preview und einem Web-Terminal für SSH-Zugriff.

Dokumentation Stand Juli 2026 — wenn etwas in der App anders aussieht, gilt die App. Aktuelle Version enthält:

  • Auto-Entpacken von Release-ZIPs in manage.sh (UGREEN-tauglich)
  • Auto-Merge fehlender ENV-Variablen aus .env.example
  • NAS-Sandbox-Auto-Detection für Codex CLI
  • Header-Toggle auf Mobile für mehr Chat-Fläche

---

Schnellstart

# 1. Code holen oder ZIP entpacken
cd /volume3/docker/knowsora
unzip -o knowsora_release.zip   # falls als ZIP geliefert

# 2. Starten — manage.sh erledigt .env + SECRET_KEY + Docker
./manage.sh start

# 3. Im Browser
http://<NAS-IP>:47822

Beim ersten Start wird admin / admin angelegt — direkt nach dem Login in den Admin-Bereich, eigenes Passwort setzen.

Was ./manage.sh start automatisch macht:

  • .env aus .env.example anlegen (falls noch nicht da)
  • Bei späteren Updates: neue Variablen aus .env.example werden in deine

bestehende .env nachgepflegt (alte Werte bleiben erhalten)

  • SECRET_KEY generieren falls leer (via openssl / python3 / /dev/urandom)

und persistent in /data/.secret_key ablegen

  • Docker-Images bauen + Container starten
  • Logs anschauen: ./manage.sh logs

---

Voraussetzungen

  • Docker + Docker Compose v2
  • Linux-Host mit min. 8 GB RAM (16 GB empfohlen wenn lokales LLM genutzt

wird; ohne lokales LLM reichen 4 GB)

  • 20 GB freier Plattenplatz (Docker-Images + Modelle + Daten + KI-Medien)
  • Optional: Intel iGPU mit /dev/dri für VAAPI-Beschleunigung beim

lokalen LLM (Intel N100, Pentium Gold 8505, N-Series)

Update-Workflow

Neue Release-ZIP bekommen → einfach ins Projektverzeichnis legen und updaten:

cd /volume3/docker/knowsora
# knowsora_release.zip dort ablegen (z.B. per scp/SFTP/Web-Upload)
./manage.sh update

manage.sh update macht automatisch:

  1. Auto-Entpacken der ZIP wenn sie neuer ist als manage.sh selbst

(versucht unzippython3pythondocker run alpine, je nach dem was auf dem Host verfügbar ist — funktioniert auch auf UGREEN/Synology ohne unzip-Paket)

  1. Merge fehlender ENV-Variablen aus .env.example nach .env

(bestehende Werte werden NIE überschrieben, nur neue Keys ergänzt)

  1. Codex-Sandbox-Auto-Setup falls Host-Kernel unprivileged_userns

blockiert (NAS-typisch)

  1. Docker build und Container-Recreate

Bei Build-Cache-Problemen oder kaputten Images:

docker compose down
docker rmi knowsora-backend:latest knowsora-frontend:latest
./manage.sh update

Build-Logs werden mit --progress plain ausgegeben — keine animierten Spinner mehr, jeder Step erscheint einmal als reine Textzeile (wichtig für SSH-Sessions ohne voll-interaktives TTY).

---

.env-Konfiguration

./manage.sh start legt die .env automatisch aus .env.example an und generiert den SECRET_KEY. Manuell bearbeiten nur wenn du Defaults ändern willst (Ports, Daten-Pfad, Timeouts, Provider-Keys vorab).

Standard-Felder die du eventuell anpassen willst:

| Variable | Bedeutung | Beispiel / Default | |---|---|---| | SECRET_KEY | JWT-Signatur + Ableitung des Verschlüsselungs-Keys | Wird automatisch generiert wenn leer | | FRONTEND_PORT | Port der Web-UI | 47822 | | BACKEND_PORT | Port der API | 48823 | | LLAMA_CHAT_PORT | Port des lokalen LLM | 48824 | | ADMIN_PASSWORD | Initial-PW für Admin-User | admin (sofort ändern!) |

Optional aber empfohlen:

| Variable | Default | Zweck | |---|---|---| | HOST_UID / HOST_GID | 1000:1000 | UID/GID unter der die Container laufen — passt File-Permissions auf dein NAS-Volume an | | DATA_DIR | /data | Im-Container-Pfad für persistente Daten | | MEDIA_ROOT | /data/media | KI-generierte Bilder/Videos | | UPLOAD_DIR | /data/uploads | Chat-Attachments + Provider-Output-Files | | LLM_HTTP_TIMEOUT | 3600 | Sekunden — für lange KI-Antworten | | CLAUDE_CLI_TIMEOUT | 3600 | Claude Code CLI Hardcap pro Call | | CODEX_CLI_TIMEOUT | 3600 | Codex CLI Hardcap pro Call | | GEMINI_CLI_TIMEOUT | 3600 | Gemini CLI Hardcap pro Call | | VEO_MODEL | veo-3.0-generate-001 | Video-Gen-Modell — veo-2.0-generate-001 falls Veo 3 nicht freigeschaltet | | VEO_MAX_POLL_S | 600 | Maximale Wartezeit für Video-Rendering | | PROJECT_SHELL_TIMEOUT | 90 | Sekunden — Hardcap für project_run_shell-Tool | | CODEX_SANDBOX_MODE | _(leer)_ | NAS-Workaround: danger-full-access wenn kernel.unprivileged_userns_clone=0 (UGREEN/Synology). Werte: read-only, workspace-write, danger-full-access |

Wichtig zur Verschlüsselung: SECRET_KEY niemals ändern wenn schon Daten in der DB sind. Sonst sind alle verschlüsselten API-Keys unbrauchbar und alle Sessions müssen neu eingeloggt werden. Beim ersten Start wird der Key automatisch in /data/.secret_key persistiert — beide Pfade (.env und .secret_key) sollten Teil deines Backups sein. Der Fernet-Verschlüsselungs-Key für API-Keys in der DB wird per PBKDF2 aus SECRET_KEY abgeleitet — eine separate FERNET_KEY-Variable gibt es nicht.

---

manage.sh — Auto-Features

manage.sh ist mehr als nur docker compose-Wrapper. Bei jedem start oder update laufen automatisch:

1. Auto-Entpacken neuer Release-ZIPs

Wird eine knowsora_release.zip im Projekt-Root abgelegt die neuer ist als die letzte ausgepackte Version, entpackt manage.sh sie selbst. Fallback-Kette für Hosts ohne unzip-Paket:

1. unzip                  Standard auf Linux mit zip-Tools
2. python3 -m zipfile     überall wo Python 3 vorhanden ist (z.B. UGREEN)
3. python -m zipfile      Python 2 Fallback
4. docker run alpine      letzter Notnagel — Docker ist sowieso da

Nach erfolgreicher Extraktion wird der ZIP-mtime 24h in die Vergangenheit gesetzt, damit der Auto-Trigger nicht endlos feuert. Beim nächsten Re-Upload einer ZIP (neuer mtime) greift er wieder.

Log-Ausgabe:

[KnowSora] Neue knowsora_release.zip erkannt — entpacke automatisch...
[KnowSora]   → 'unzip' fehlt, verwende python3 zipfile
[OK] knowsora_release.zip entpackt

2. ENV-Merge aus .env.example

Pflegt fehlende ENV-Variablen aus .env.example in deine .env nach ohne bestehende Werte zu überschreiben. Nur Keys die in .env komplett fehlen werden angehängt — auskommentierte Werte (# FOO=...) gelten als "bewusst deaktiviert" und werden nicht aktiviert.

Nachgepflegte Keys landen am Ende der .env unter:

# ─── Automatisch nachgepflegt aus .env.example ───

Damit bekommst du bei Updates automatisch alle neuen Konfig-Optionen ohne deine eigenen Werte zu verlieren.

3. Codex-Sandbox-Auto-Setup

Erkennt automatisch wenn der Host-Kernel unprivileged_userns_clone=0 hat (typisch für UGREEN, Synology, manche Docker-Setups) und setzt CODEX_SANDBOX_MODE=danger-full-access in der .env.

Hintergrund: Codex CLI nutzt bubblewrap als Sandbox. Auf Kerneln ohne unprivileged user namespaces scheitert bwrap mit "No permissions to create a new namespace" und Codex bricht ab. Der Container ist sowieso durch Docker isoliert, also kein realer Sicherheitsverlust.

Logik: nur wenn CODEX_SANDBOX_MODE= leer in .env UND sysctl kernel.unprivileged_userns_clone == 0. Hast du den Wert manuell gesetzt (egal ob danger-full-access, read-only oder etwas anderes), wird er nicht angetastet.

---

Provider-Setup

KnowSora unterstützt neun Provider — alle parallel nutzbar. Auswahl pro Chat via Provider-Pille oben links.

1. Lokales LLM (llama.cpp)

Läuft im Container knowsora-llama-chat. Modell-Auswahl: GGUF-Datei in /data/models/ ablegen, in .env setzen:

CHAT_MODEL_PATH=/models/qwen3-4b-q4_k_m.gguf

Container neu starten. Empfehlung für 4-GB-Mode: Qwen3-4B-Q4_K_M. Für 8 GB: Qwen3-7B-Instruct-Q4_K_M.

2. OpenAI (GPT-4o, GPT-5, o-Modelle)

KI-Modelle → OpenAI → API-Key + Modell-ID (z.B. gpt-4o, gpt-5, o1-mini).

KnowSora erkennt automatisch ob das Modell max_completion_tokens statt max_tokens braucht (gpt-5, o1, o3, o4) und ob temperature unterstützt wird. Bei API-Fehlern wird zweimal retried mit passenden Feldern bevor aufgegeben wird.

3. Anthropic Claude (API)

KI-Modelle → Claude → API-Key + Modell-ID (z.B. claude-sonnet-4-5, claude-opus-4-7).

4. Google Gemini (API)

KI-Modelle → Gemini → API-Key + Modell-ID (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview).

Hinweis: Preview-Modelle sind oft nur für bestimmte Accounts/Regionen freigeschaltet. Bei 503 oder "not found" auf ein Stable-Modell wechseln.

5. xAI Grok

KI-Modelle → xAI Grok → API-Key (auf console.x.ai generieren). Modell-Vorschläge:

  • grok-4.3 (Default) — schnell + günstig, gute Tool-Calls
  • grok-4.20 — Flagship-Reasoning
  • grok-imagine-image-quality — Bildgenerierung (vom Medien-Generator

via provider="grok" aufrufbar)

  • grok-imagine-video — Videogenerierung (via Medien-Generator)

Auth: xAI hat kein OAuth-Verfahren für die API. Auch nicht mit X Premium / SuperGrok-Abo. Ausschließlich API-Key. Credits müssen explizit aufgeladen werden, Free-Tier gibt es nicht.

6. OpenRouter (300+ Modelle, Free-Tier)

KI-Modelle → OpenRouter → API-Key (auf openrouter.ai generieren, Google-/GitHub-Login möglich, kein Karten-Hinterlegen für Free-Tier nötig).

Was OpenRouter besonders macht: Ein API-Key, Zugang zu 300+ Modellen von OpenAI, Anthropic, Google, xAI, Meta, DeepSeek, Mistral u.v.m. — inkl. dedizierter Free-Tier-Modelle für komplett kostenlose Nutzung (mit Rate-Limit).

Empfohlene Modell-Wahl:

  • openrouter/free (Default, Killer-Feature) — Smart-Routing, wählt

zur Laufzeit das beste Free-Modell passend zum aktiven Skill: - Coding-Assistent → Qwen3 Coder (1M Context) - Wissens-Recherche → Llama 3.3 70B / DeepSeek V4 / Gemini 2.0 Flash - Daten-Analyst → DeepSeek V4 Flash (Reasoning) - Web-Recherche → Llama 3.3 / DeepSeek - Medien-Generator → erstes Allzweck-Free-Modell mit Tool-Support - Coder-Modelle werden bei Nicht-Coding-Skills automatisch ausgeschlossen (anti_hints in der Heuristik)

  • qwen/qwen3-coder:free — Top-Coding-Modell, 1M Context
  • deepseek/deepseek-v4-flash:free — Reasoning, 1M Context
  • meta-llama/llama-3.3-70b-instruct:free — Solider Allzweck
  • google/gemini-2.0-flash-exp:free — Multimodal, schnell
  • openai/gpt-5 — kostenpflichtig, falls Credits aufgeladen
  • anthropic/claude-sonnet-4.6 — kostenpflichtig

Per-Skill-Override: Du kannst pro Skill ein bevorzugtes Free-Modell in Skills → Bearbeiten → "🌐 Bevorzugtes OpenRouter Free-Modell" pinnen. Smart-Routing nutzt dann dieses statt der Heuristik. Leer lassen für Auto-Wahl.

Rate-Limits (Stand Juli 2026):

  • Ohne Credits: 50 Anfragen/Tag total über alle Free-Modelle,

20 req/min

  • Mit ≥10 USD Credits: 1000 Anfragen/Tag auf Free-Modelle
  • Paid-Modelle: keine OpenRouter-Limits, nur Upstream-Limits

KnowSora-Features für OpenRouter:

  • 🌐 Smart-Routing (openrouter/smart) — wählt zur Laufzeit das beste

Free-Modell passend zum aktiven Skill (Capability-Scoring nach Tool-Support, Context-Größe, Modell-Familie)

  • Per-Skill-Override — pro Skill ein Lieblings-Free-Modell pinnen
  • Live Free-Models-Liste im Modell-Dropdown — wird dynamisch via

/api/v1/models geladen (1h Cache)

  • Live Credits-Anzeige in der Provider-Karte: aktuelles Guthaben,

gekaufte und verbrauchte Credits

  • Auto-Fallback bei 429 — wenn ein Free-Modell sein Tageslimit

erreicht hat, probiert KnowSora automatisch bis zu 2 weitere Free-Modelle (filtert auf Tool-Calling-fähige falls Skill aktiv)

  • App-Attribution — KnowSora sendet HTTP-Referer +

X-Title-Header damit deine Nutzung auf den OpenRouter-Leaderboards erscheint

Cache-Refresh falls neue Free-Modelle erwartet werden:

curl -X POST http://localhost:48823/api/openrouter/refresh-cache \
  -H "Authorization: Bearer $YOUR_KNOWSORA_TOKEN"

7. Custom OpenAI-kompatibel

Für andere Hoster mit OpenAI-API-Format (Together, Groq, lokale APIs, etc.). KI-Modelle → Custom → Base-URL + API-Key + Modell-ID.

OpenRouter sollte über den dedizierten Provider (Nr. 6) genutzt werden — sonst entgehen dir Free-Tier-Detection, Auto-Fallback und Credits- Anzeige.

8./9./10. CLI-Provider (Claude Code, Codex, Gemini CLI)

Drei lokal in den Backend-Container installierte CLIs. Login per OAuth (kostenlos für Pro/Plus/Subscription-User) oder API-Key.

Subscription-Übersicht (ohne extra API-Kosten):

| CLI | Subscription | Kostenmodell | |---|---|---| | Claude Code | Anthropic Pro/Team | 5 Std-Limits, max ~50 Anfragen/5h | | Codex | ChatGPT Plus/Pro/Team | Im ChatGPT-Plan inklusive | | Gemini CLI | Google-Account (Free) | 1000 Anfragen/Tag mit Gemini 2.5 Flash gratis |

OAuth-Login-Workflow (alle drei gleich):

  1. KI-Modelle → CLI-Provider → CLI Login
  2. Im modalen Terminal-Fenster Anweisungen folgen
  3. Bei Claude Code & Codex: Device-Auth — URL kopieren, im Browser

einloggen, Code zurück ins Terminal

  1. Bei Gemini CLI: localhost-OAuth-Workaround (Anleitung im Modal)

Nach erfolgreichem Login: KnowSora erkennt OAuth-Token automatisch periodisch (alle 2 Sek) und schließt das Login-Fenster.

Wichtig — CLI im Container-Mode: Der Backend-Container fügt beim Start automatisch einen passwd-Eintrag für die Container-UID ein. Sonst crashen Node-basierte CLIs (insbesondere Gemini's FileKeychain) mit uv_os_get_passwd returned ENOENT. Falls Probleme: Backend neu starten, dann läuft ensure_passwd_entry() erneut.

---

Skills (vordefinierte Workflows)

Ein Skill = System-Prompt + Tool-Whitelist. Beim Chat-Start in der Skill- Pille auswählbar. Wenn ein Skill aktiv ist, läuft die KI in einer Tool- Loop und kann die freigeschalteten Tools aufrufen.

Mitgelieferte Default-Skills:

| Skill | Tools | Zweck | |---|---|---| | 🪄 Wissens-Recherche | search_knowledge_base, read_document, list_documents | RAG-Antworten mit Quellenangabe | | 🌐 Web-Recherche | web_search, url_fetch, datetime_tool | DuckDuckGo + Webseiten lesen | | 📊 Daten-Analyst | list_documents, query_table, calculate | CSV/XLSX per SQL auswerten | | 💻 Coding-Assistent | project_, python_exec, regex_test, json_tool, datetime_tool, http_request, url_fetch, web_search | Code schreiben/testen, im Projekt-Ordner arbeiten | | 🤖 Claude Code | project_, alle Coding-Tools + KB-Suche | Senior-Engineer-Persona mit Projekt-Tools | | 🎨 Medien-Generator | generate_image, edit_image, generate_video | Bilder/Videos via OpenAI + Google + Grok | | 📄 Dokumenten-Generator | generate_document, convert_document | Angebote/Rechnungen/Berichte als PDF+Word, PDF↔Word-Konvertierung |

Skills sind editierbar (Admin → Skills) — System-Prompt + Tool-Liste + Icon + Farbe pro Skill. "Standard zurücksetzen" pro Skill verfügbar. Neue Skills aus Updates werden inkrementell nachgepflegt, deine Anpassungen bleiben erhalten.

Skill-Tools im Detail

search_knowledge_base — Hybrid-Suche (BM25 + Vektor mit Reciprocal Rank Fusion) in einer KB. Liefert Top-10-Chunks mit Quellen-Metadaten (Max 20). Findet auch Eigennamen und exakte Begriffe zuverlässig, nicht nur semantisch ähnliche Inhalte.

read_document / list_documents — Volltext eines Dokuments laden / Dateien einer KB auflisten.

query_table — DuckDB-SQL über CSV/XLSX-Dokumente einer KB. Ideal für "Wie viele Bestellungen letzten Monat?" oder Aggregationen.

calculate — Python-Math-Ausdrücke (sandboxed).

python_exec — Voll-Python-Sandbox in eigenem Subprocess, mit Output-File-Capture. Dateien die unter /tmp/ erzeugt werden, landen automatisch als Download-Button im Chat.

web_search / url_fetch — DuckDuckGo-Suche + Webseiten als Markdown lesen (BS4 + Readability).

http_request — Beliebige HTTP-Calls (GET/POST/PUT/DELETE) mit Headers + Body. Whitelist gegen interne IPs.

json_tool / regex_test / datetime_tool — Hilfsfunktionen zum Parsen, Pattern-Matchen, Zeit-Berechnungen.

Projekt-Tools (NEU — verfügbar für JEDEN Provider)

Diese Tools erlauben es jeder KI (auch OpenAI/Claude/Gemini-API, nicht nur CLIs), direkt im aktuellen Projekt-Verzeichnis zu arbeiten:

project_list_dir — Verzeichnis-Inhalt anzeigen (max 500 Einträge, optional rekursiv).

project_read_file — Datei lesen bis 1 MB (optional max_lines). Keine Schreibrechte nötig.

project_write_file — Datei schreiben oder anhängen, max 5 MB. Verzeichnisse werden auto-erstellt. Braucht aktivierte Schreibrechte im Projekt.

project_delete — Datei oder Verzeichnis löschen (rekursiv bei Ordnern). Braucht aktivierte Schreibrechte.

project_run_shell — Shell-Befehl im Projekt-cwd ausführen (npm install, python -m pytest, git status, etc.). Hartes Timeout 90 Sek (PROJECT_SHELL_TIMEOUT änderbar), stdout/stderr auf 50 KB gekappt. Braucht aktivierte Schreibrechte.

Schreibrechte-Toggle pro Projekt — gleiche Logik wie für die CLIs:

  • Toggle AUS → write/delete/shell schlagen mit klarer Fehlermeldung

fehl, list/read funktionieren weiterhin

  • Toggle AN → volle Zugriffsrechte im Projekt-Ordner

Cross-Provider-Workflow: Damit kann GPT-5 prüfen was Claude Code gerade im Projekt gebaut hat, oder Gemini ein von Claude erzeugtes Python-Script auf Bugs durchsehen.

Medien-Tools

generate_image — KI-Bildgenerierung. Parameter provider:

  • openai (Default) — gpt-image-1, fotorealistisch, ggf. Org-Verification
  • gemini — imagen-4.0-generate-001, künstlerisch stark
  • grok — grok-imagine-image-quality, fotorealistisch + starke Text-Wiedergabe

edit_image — Bild-zu-Bild auf Basis eines hochgeladenen Fotos. Nutzt automatisch das erste Image-Attachment der aktuellen Nachricht (attachment_index=0). JPEGs werden serverseitig zu PNG konvertiert (Pillow), bevor sie an OpenAI's /images/edits-Endpoint gehen.

  • openai — gpt-image-1 Edits, fotorealistisch
  • gemini — gemini-2.5-flash-image (Nano Banana), kreativ
  • grok — grok-imagine-image-quality Edits, Base64-data-URI als Input

generate_video — Video-Generierung. Parameter provider:

  • gemini (Default) — Google Veo 3, 4-8 Sek, ca. 1-3 min Wartezeit
  • grok — grok-imagine-video, 5-15 Sek, ~30 Sek Wartezeit

OpenAI und Anthropic haben keine öffentliche Video-API. Sora ist nur in ChatGPT verfügbar, nicht via API.

Wo landen generierte Medien?

Drei Speicherorte parallel:

/data/media/<user_id>/<YYYY-MM-DD>/<uuid>.png       # Original-Ablage
/data/uploads/...                                    # Provider-Output-Files
<projekt>/outputs/<YYYY-MM-DD>/<original_name>      # Wenn Chat ein Projekt hat

Jedes generierte File wird als ChatOutput-DB-Row persistiert — bleibt nach Tab-Wechsel und Browser-Neustart in der Chat-Historie sichtbar mit Inline-Preview (Bilder: <img>, Videos: <video controls>).

Wenn der Chat ein Projekt zugewiesen hat:

Alle Outputs werden zusätzlich automatisch als Kopie ins Projekt- Verzeichnis abgelegt (<projekt>/outputs/<datum>/). Bei Namens- konflikten wird ein Counter angehängt (bild.pngbild (1).png).

Die Projekt-Kopie ist komplett unabhängig von der DB: Chat löschen, ChatOutput löschen, Original in /data/media/ löschen — alles beeinflusst die Projekt-Kopie nicht. Nur das Löschen des Projekts selbst (oder manuell per Datei-Browser) entfernt sie.

Nachträglich kopieren: Im Chat-Header gibts einen Button „→ Projekt" (erscheint nur wenn Projekt zugewiesen). Damit werden alle bisherigen Outputs des Chats in einem Rutsch ins Projekt kopiert — nützlich für Outputs die VOR der Projekt-Zuweisung entstanden sind.

---

Wissens-Datenbanken (RAG)

  1. Wissens-DBs → Neue KB anlegen (Name, Icon, Farbe)
  2. Dokumente → Dateien hochladen, KB zuweisen
  3. Im Chat-Pill KB auswählen → ab jetzt nutzt der Skill diese KB

automatisch (sofern der Skill search_knowledge_base enthält)

Unterstützte Formate: PDF, DOCX, XLSX, CSV, TXT, MD, HTML, JSON, PPTX.

Indexierung: läuft als Background-Worker. Status im Dokumenten- Listing (pendingprocessingready).

Embedding-Modell: Default nomic-embed-text-v1.5 (768-dim, ONNX, in-process via fastembed — kein separater Container). Im Admin-Bereich unter "Embed-Modelle" wechselbar (löst Auto-Reembed aller Dokumente aus).

---

Projekte (Cross-Provider-Workspaces)

Projekte sind persistente Arbeitsverzeichnisse pro User unter /data/projects/<user_id>/<slug>/. Beim Chat als Projekt-Pill aktiviert, nutzt die KI dieses Verzeichnis als cwd für Claude Code, Codex, Gemini CLI und für die project_*-Tools (jeder Provider).

Funktionen pro Projekt:

  • Datei-Browser mit Universal-Preview:

- Bilder (png/jpg/gif/webp/svg/avif/bmp): <img> inline - Videos (mp4/webm/mov/mkv/avi): <video controls> - Audio (mp3/wav/ogg/flac/m4a/aac): <audio controls> - PDF: <iframe> (75vh hoch) - Text/Code (50+ Endungen — py/js/ts/json/md/csv/sql/yaml etc.): <pre> - Office/Archive/Binär: Info-Box mit Download-Button

  • Datei-Download pro File (Bearer-Auth via Blob + object-URL)
  • ZIP-Upload entpackt automatisch in das Projekt-Verzeichnis
  • ZIP-Download lädt das ganze Projekt herunter (mit Auto-Excludes:

node_modules, .git, .venv, dist, build, __pycache__ u.a.) - Standard: Hidden-Files ausgeschlossen - ?include_hidden=true für Backups inkl. .env

  • Schreibrechte-Toggle — wenn AUS, dürfen alle CLIs und project_*-Tools

nur lesen: - Claude Code CLI: --permission-mode=default + disallowed-tools - Codex CLI: --sandbox=read-only - Gemini CLI: --approval-mode=plan + allowed-tools-Whitelist - project_*-Tools: write/delete/shell → klare Fehlermeldung

Outputs-Unterordner: <projekt>/outputs/<datum>/ enthält alle vom Chat im Skill-Mode generierten Bilder/Videos/Files. Wird automatisch beim Erstellen befüllt, kann per Button im Chat-Header auch nachträglich für bestehende Outputs befüllt werden.

---

Web-Terminal (Wetty)

Für SSH-Zugriff auf den NAS direkt aus dem Browser. Login mit den SSH-Credentials des NAS-Users.

Konfiguration: Admin → Web-Shell → SSH-Host, Port und Default-User setzen. NAS-spezifischer SSH-Port (z.B. 50199 statt 22) wird unterstützt.

---

Live-Activity-Box (CLI-Sichtbarkeit)

Während Claude Code, Codex oder Gemini CLI aktiv arbeiten, sieht der User live was der CLI tut:

●  📖 Lese src/auth.ts
   ✏️ Bearbeite schema.prisma
   🔧 Führe `npm install` aus
   ✅ Befehl fertig

Funktioniert in allen Skill- und Klassik-Modes. Die Box erscheint automatisch wenn der Job läuft, verschwindet nach Done. Aktuelle Aktion wird mit pulsierendem Punkt hervorgehoben.

---

Provider-Output-Files (Download direkt im Chat)

Wenn ein Provider eine Datei im Container erzeugt und in der Antwort einen Pfad nennt, erscheint automatisch ein Download-Button unter der Assistant-Bubble.

Erkennung via:

  • Expliziter Marker: {{download:/tmp/foo.html}} oder

[[download:/tmp/foo.html]]

  • Auto-Detection: absolute Pfade in Codeblöcken oder Text die auf

eine erlaubte Datei verweisen

Erlaubte Quell-Verzeichnisse: /tmp/, /var/tmp/, /data/.claude_home/, /data/outputs/, /home/, /data/media/

System-Verzeichnisse (/etc/, /usr/, /proc/, /root/, /var/log/) werden ignoriert.

Limits: 50 MB pro File, max 10 Files pro Antwort, ~50 Datei- Endungen auf Whitelist.

---

Voice (Sprach-Eingabe und -Ausgabe)

Seit Mai 2026 unterstützt KnowSora Speech-to-Text (STT) und Text-to-Speech (TTS) mit drei wählbaren Engines.

Engines

| Engine | STT | TTS | Kosten | Latenz | Voraussetzung | |--------|-----|-----|--------|--------|---------------| | Browser (Default) | Web Speech API | Web Speech API | gratis | <500ms | Chrome/Safari/Edge | | OpenAI | Whisper-1 | TTS-1 (MP3-Streaming) | ~0.006 USD/Min STT, ~0.015 USD/1k chars TTS | 1-2s | OpenAI-Provider mit API-Key | | Gemini | gemini-2.5-flash | gemini-3.1-flash-tts-preview | Free-Tier | 3-8s | Gemini-Provider mit API-Key |

Browser-Engine ist die Default-Wahl und funktioniert am besten auf iPhone/iPad mit Apple-Stimmen. Unter Linux/Firefox eingeschränkt — dort auf OpenAI oder Gemini umstellen.

Stimmen

  • OpenAI: alloy, echo, fable, onyx, nova, shimmer
  • Gemini: Kore, Puck, Charon, Fenrir, Aoede, Leda, Orus, Zephyr
  • Browser: alle System-installierten Stimmen

Aktivierung

Voice ist immer eingebaut — keine Backend-Konfiguration nötig. In der Chat-Eingabezeile erscheint ein Mikrofon-Symbol. Voice-Engine + Stimme + Sprache lassen sich pro Browser-Profil im Voice-Settings-Popover einstellen (Zahnrad/⋮-Menü).

HTTPS-Anforderung

Wichtig: Browser erlauben Mikrofon-Zugriff nur über HTTPS oder localhost. Bei Selfhost-Setups mit Reverse-Proxy unbedingt Let's Encrypt einrichten (siehe Sektion "Reverse-Proxy"), sonst geht Spracheingabe nicht.

IT-Begriffe-Aussprache-Wörterbuch

KnowSora hat eingebautes Wörterbuch das ~50 Tech-Abkürzungen automatisch korrekt ausspricht:

  • VLAN → "V Lan", DHCP → "D H C P", WLAN → "We Lan"
  • JSON → "Jason", NAS → "Nas", RAID → "Reid", NAT → "Nat", MAC → "Mac"
  • IP-Adressen werden Punkt-getrennt vorgelesen
  • MAC-Adressen Hex-Paar-weise
  • URLs werden zu "Link" zusammengefasst, Code-Blöcke übersprungen

TTS-Limits

  • Max 4096 Zeichen pro TTS-Request (KnowSora chunked längere Texte

automatisch und spielt sie nacheinander ab)

  • iOS-Safari: Audio-Wiedergabe nur direkt im User-Gesture-Kontext

erlaubt — der erste Lautsprecher-Tap pro Tab muss manuell sein

---

Hybrid-Suche (BM25 + Vektor)

Seit Mai 2026 nutzt search_knowledge_base Hybrid-Retrieval statt reiner Vektor-Suche. Keine Konfiguration nötig — ist immer aktiv.

Was passiert?

Jede Suche läuft parallel über zwei Engines:

  1. Vektor-Suche (Chroma + fastembed) — findet semantisch verwandte

Inhalte, auch bei Synonymen und Umschreibungen

  1. BM25 In-Memory — findet exakte Wort-Übereinstimmungen,

Eigennamen, IDs, Codes

Die beiden Ranglisten werden über Reciprocal Rank Fusion (RRF) zu einer Top-Liste fusioniert. Tokenisierung: lowercase, deutsche + englische Stoppwörter raus, Mindestlänge 2 Zeichen.

Cache-Verhalten

BM25-Index wird pro KB-Filter im Speicher gehalten und automatisch invalidiert bei:

  • Neue Chunks (Doc-Upload, Reindex)
  • Doc-Delete
  • KB-Delete

Erster Search-Call nach Cache-Invalidierung baut den Index neu auf (<100ms bei 10k Chunks).

Filename-Prefix beim Embedding

Zusätzlich wird der Dateiname als Header in den Embed-Text eingebaut: [Quelle: filename.pdf]\n\n<chunk>. Dadurch werden Begriffe die nur im Dateinamen vorkommen mit-embedded und finden auch über Vektor-Suche die richtige Datei.

Der gespeicherte Chunk-Text bleibt original — User sehen den Prefix nicht in den Recherche-Ergebnissen.

Wichtig: Dokumente die VOR Mai 2026 hochgeladen wurden, haben den Filename-Prefix nicht. Über KB-Edit → "🔄 N bestehende Dokumente neu indizieren" lassen sich alle Docs einer KB mit aktuellen Einstellungen neu verarbeiten.

---

Contextual Retrieval (Smart Chunking)

Optional pro KB aktivierbar. Basiert auf der Anthropic-Methode anthropic.com/news/contextual-retrieval.

Wie funktioniert es?

Beim Indexieren wird pro Chunk per LLM ein 1-2-Satz-Kontext aus dem Gesamtdokument generiert und VOR den Chunk gehängt — aber nur fürs Embedding. Der gespeicherte Chunk bleibt original.

Beispiel:

Chunk: "Die Antwort betrug 5,2 Mio. EUR im Q3."

Embed-Input (mit Contextual): "Dieser Chunk stammt aus dem Q3-2024- Bericht der ACME GmbH und beschreibt den Quartalsumsatz. Die Antwort betrug 5,2 Mio. EUR im Q3."

Resultat: Treffer-Relevanz um 30-50% besser für Fragen wie "Wie hoch war der ACME-Umsatz Q3?".

Aktivierung

KB öffnen → Bearbeiten → "🧠 Contextual Retrieval (smart chunking)" einschalten → LLM-Provider wählen → Speichern.

Provider-Auswahl pro KB:

  • OpenRouter (Default, kostenlos, ~3-15 Min für 100 Chunks)
  • OpenAI gpt-4o-mini (~0.50 USD für 500 Chunks, sehr schnell)
  • Groq Llama 3.3 70B (kostenlos, sehr schnell)
  • Gemini Flash (kostenlos im Free-Tier)
  • DeepSeek

Reindex bestehender Dokumente

Über Button "🔄 N bestehende Dokumente neu indizieren" im KB-Edit- Modal. Alle Docs werden auf pending gesetzt und vom Worker neu verarbeitet — diesmal mit Contextual Retrieval.

Robustheit

  • Retry-Logik bei Rate-Limits (429) mit exponentialem Backoff:

5s → 15s → 30s → 60s (max 5 Versuche pro Chunk)

  • Parallelität auf 4 LLM-Calls gleichzeitig begrenzt
  • Fallback auf normales Embedding wenn Kontext-LLM dauerhaft scheitert
  • Worker-Timeout auf 2h erhöht (Default), Override via

DOC_PROCESS_TIMEOUT_MAX in .env

Performance

| Dok-Größe | Zeit mit Contextual (OpenRouter Free) | |-----------|---------------------------------------| | 5 Chunks | ~30-40s | | 20 Chunks | ~2-3 min | | 100 Chunks | ~10-15 min | | 500 Chunks | ~45-60 min |

Mit OpenAI gpt-4o-mini etwa 5-10x schneller.

---

Mobile-Optimierungen

KnowSora ist responsive ausgelegt und nutzt unter 768px Viewport-Breite ein angepasstes Layout:

Header zusammenklappbar. Auf Mobile sind die Selektoren-Zeile (Provider/Skill/Projekt/KB) und die Anhang-Bar per Default eingeklappt — nur Titel und Action-Buttons sind sichtbar. Maximaler Platz für den Chat. Der Chevron-Button rechts neben "Leeren" schaltet die Optionen ein und aus.

Selektoren mobile-safe. Provider/Skill/Projekt/KB-Dropdowns nutzen min(280-360px, calc(100vw - 24px)) als Breite mit maxHeight: 70vh und Scroll — kein Überlaufen am Bildschirmrand.

Admin User-Liste als Karten. Statt der Desktop-Tabelle erscheint auf Mobile pro User eine kompakte Karte mit Avatar, Username, Email, Rolle/Status-Badges und Edit/Delete-Buttons in einer Reihe.

Provider-Karten gestapelt. Lange Provider-Namen (z.B. "OpenAI (GPT-4o, etc.)") werden nicht abgeschnitten — auf Mobile stehen Titel und Konfig-Buttons untereinander statt nebeneinander.

KI-Modelle-Menü nur für Admins sichtbar. Endkunden-User sehen den Eintrag nicht. Sie wählen Provider direkt im Chat-Dropdown — die Liste zeigt nur Provider mit usable=true (API-Key vorhanden oder OAuth aktiv). API-Keys werden nie ans Frontend zurückgegeben.

Voice auf Mobile. Mikrofon-Symbol bleibt prominent in der Hauptzeile. Weitere Voice-Optionen (Auto-Vorlesen, Sprach-Einstellungen, Projekt- Anhang) liegen im Overflow-Menü (⋮) damit das Eingabefeld groß bleibt. Voice-Settings als Bottom-Sheet mit großen Touch-Targets statt Popover.

---

Reverse-Proxy (Nginx Proxy Manager)

Wenn KnowSora hinter NPM oder einem anderen Proxy läuft, müssen folgende Timeouts erhöht werden, sonst werden lange KI-Anfragen gekillt:

NPM → Proxy Host → Advanced → Custom Nginx Configuration:

# Timeouts für lange KI-/CLI-Anfragen (bis 1 Stunde)
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 60s;

# Uploads bis 200 MB
client_max_body_size 200M;

# WebSocket für CLI-Login Terminal
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

# Standard-Header
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# Streaming nicht puffern
proxy_buffering off;
proxy_cache off;

Frontend-Polling-Logik macht automatisch exponential-backoff (800ms → 1.6s → 3.2s → 6.4s → max 8s) bei wiederholten Netzwerkfehlern, damit die Browser-Console nicht spamt während Let's-Encrypt-Cert-Renewals.

---

Robustheit & Fehlerbehandlung

ErrorBoundary

Render-Fehler im Frontend werden abgefangen — statt blank-screen siehst du eine Fallback-UI mit:

  • "Weiter versuchen"-Button (resettet Component-Tree)
  • "Seite neu laden"-Button
  • Stack-Trace in aufklappbarem <details>

Globale window.error + unhandledrejection Listener loggen zusätzlich in localStorage["knowsora-errors"] (letzte 30 Events) für Post-Mortem-Diagnose.

Auto-Retry für LLM-API-Quirks

Bei OpenAI 400-Fehler:

  • "temperature does not support 0" → retry ohne temperature
  • "max_tokens not supported, use max_completion_tokens" → retry mit

umgestelltem Feld

Bei Gemini 400:

  • "temperature not supported" → retry ohne temperature

Klare Übersetzung von 404/503-Fehlern in deutsche User-Meldungen mit Hinweis welches Modell stattdessen funktioniert.

Background-Job-System

Chat-Anfragen laufen als Background-Job:

  • Frontend pollt alle 800ms /api/chat/job/{id} → liest Status +

Activity-Events live

  • Job-IDs werden in localStorage["kh-job-<chat_id>"] gecached → Tab

schließen + wieder aufmachen verbindet sich nahtlos wieder

  • Cancel-Button bricht laufenden CLI-Subprocess hart ab

Mobiler Edit-Bug

Behoben in dieser Version: User-Nachrichten werden optimistisch mit id: Date.now() angezeigt. Echte Backend-ID wird via .then() in den State zurückgepatched. Bei sehr schnellem Edit unmittelbar nach Senden gibt es einen 404-Fallback der die Message neu speichert + lokal weitermacht.

Soft-Auth-Expiry

Bei JWT-Expiration (HTTP 401) wird nicht hart per window.location.href navigiert — stattdessen Custom-Event knowsora-auth-expired → React-Router macht den Redirect zu /login ohne Page-Reload (kein temporärer Blank-Screen).

---

API-Endpunkte (für Eigenentwicklungen)

| Endpoint | Methode | Zweck | |---|---|---| | /api/auth/login | POST | Login (form-encoded), liefert JWT | | /api/auth/me | GET | Aktueller User | | /api/chats/ | GET/POST | Chat-Liste / neuen Chat anlegen | | /api/chats/{id} | PUT/DELETE | Chat ändern / löschen | | /api/chats/{id}/messages | GET | Messages eines Chats laden | | /api/chats/{id}/messages/{msg_id} | PUT | User-Message editieren + nachfolgende löschen | | /api/chats/{id}/copy-outputs-to-project | POST | Bestehende Chat-Outputs ins Projekt kopieren | | /api/chat/start | POST | KI-Anfrage als Background-Job starten | | /api/chat/job/{job_id} | GET | Job-Status + Activity-Events pollen | | /api/chat/job/{job_id}/cancel | POST | Laufenden Job abbrechen | | /api/skills/ | GET / POST / PUT / DELETE | Skill-Verwaltung | | /api/skills/tools | GET | Tool-Katalog | | /api/knowledge-bases/ | GET/POST/PUT/DELETE | KB-Verwaltung | | /api/documents/ | GET/POST | Dokument-Liste / Upload | | /api/projects/ | GET/POST | Projekt-Liste / anlegen | | /api/projects/{id}/browse | GET | Verzeichnis-Inhalt | | /api/projects/{id}/file | GET/DELETE | File lesen / löschen, ?download=1 für FileResponse | | /api/projects/{id}/upload | POST | Einzelne Datei hochladen | | /api/projects/{id}/upload-zip | POST | ZIP-Archiv hochladen + entpacken | | /api/projects/{id}/download-zip | GET | Ganzes Projekt als ZIP runterladen | | /api/projects/{id}/mkdir | POST | Verzeichnis anlegen | | /api/message-attachments/upload | POST | Bild/File für nächste Nachricht hochladen | | /api/message-attachments/{id} | DELETE | Anhang löschen | | /api/chat-outputs/{id}/download | GET | Provider-erzeugtes File runterladen | | /api/media/{user_id}/{path} | GET | KI-generiertes Medium (auth + owner-check) | | /api/ai-providers/ | GET/POST/PUT/DELETE | Provider-Verwaltung | | /api/ai-providers/{id}/test | POST | Test-Call an Provider | | /api/cli-login/start/{cli} | POST | OAuth-Login-Session starten | | /api/cli-login/ws/{cli} | WS | Terminal-Stream für CLI-Login | | /api/cli-login/status/{cli} | GET | Aktueller OAuth-Status | | /api/embed-models/catalog | GET | Verfügbare Embedding-Modelle | | /api/embed-models/activate | POST | Embedding-Modell wechseln | | /api/admin/users | GET/POST/PUT/DELETE | User-Verwaltung |

JWT-Token als Authorization: Bearer <token> Header.

---

Architektur

                 ┌──────────────┐
                 │ Nginx Proxy  │
                 │   Manager    │
                 │  (optional)  │
                 └──────┬───────┘
                        │
       ┌────────────────┼────────────────┐
       │                │                │
┌──────▼───────┐ ┌──────▼───────┐ ┌──────▼───────┐
│  Frontend    │ │   Backend    │ │  llama-chat  │
│ Vite+React   │ │  FastAPI     │ │  llama.cpp   │
│ Port 47822   │ │  Port 48823  │ │  Port 48824  │
└──────────────┘ └──────┬───────┘ └──────────────┘
                        │
              ┌─────────┼─────────┐
              │         │         │
       ┌──────▼──┐ ┌────▼────┐ ┌──▼───────┐
       │fastembed│ │ChromaDB │ │ DuckDB   │
       │ (ONNX,  │ │persist  │ │:memory:  │
       │in-proc) │ │         │ │query_tbl │
       └─────────┘ └─────────┘ └──────────┘
                        │
                ┌───────┴────────┐
                │   SQLite       │
                │ /data/         │
                │  knowsora.db   │
                └────────────────┘

Alle Container im Host-Network-Modus — kein Port-Mapping, direkter LAN-Zugriff.

Daten-Persistenz — alles unter /data/ (oder dem Pfad aus DATA_DIR):

  • knowsora.db — Haupt-DB
  • chroma/ — Vektor-Store
  • models/ — GGUF-Dateien
  • uploads/ — Chat-Attachments + Provider-Output-Files
  • media/<user>/<datum>/ — KI-Bilder/Videos (persistent unabhängig vom Chat)
  • projects/<user>/<slug>/ — Coding-Projekte
  • projects/<user>/<slug>/outputs/<datum>/ — automatische Backup-Kopien aller Chat-Outputs für diesen Chat
  • .claude_home/, .codex/, .gemini/ — CLI-OAuth-Tokens

Backup-Empfehlung: Den ganzen /data-Pfad sichern PLUS die .env (enthält SECRET_KEY) PLUS /data/.secret_key (Persistenz-Kopie des Keys). Bei Wiederherstellung muss der SECRET_KEY identisch zur ursprünglichen Installation sein, sonst sind verschlüsselte API-Keys und Sessions unbrauchbar.

---

Troubleshooting

Backend startet nicht, Logs zeigen "permission denied" auf /data: HOST_UID/HOST_GID in .env passen nicht zum Volume-Owner. Fix:

chown -R 1000:1000 /volume3/docker/knowsora/data

Gemini CLI: "uv_os_get_passwd returned ENOENT": Container-UID hat keinen passwd-Eintrag. Sollte automatisch beim Backend-Start gefixt werden. Falls nicht: docker compose down && docker compose up -d --build (kein --no-cache nötig — Dockerfile hat chmod 666 /etc/passwd /etc/group).

Gemini CLI: "folder is not trusted": Automatisches Eintragen in trustedFolders.json schlägt fehl. Logs prüfen. Workaround: Backend-Container neu starten — beim nächsten Tool-Call wird der Eintrag neu geschrieben.

OpenAI: "max_tokens is not supported, use max_completion_tokens": Sollte automatisch retried werden. Falls weiterhin: KI-Modelle → OpenAI → schauen welches Modell konfiguriert ist. Für gpt-5, o1, o3, o4 ist max_completion_tokens zwingend.

Veo Video: "Modell nicht gefunden / 503":

  • Modell-Name prüfen: veo-3.0-generate-001 (Premium) oder

veo-3.0-fast-generate-001 (günstiger) oder veo-2.0-generate-001 (Fallback)

  • API-Key für Google AI Studio braucht Veo-Freischaltung
  • Tool-Parameter model: "veo-2.0-generate-001" als Override

Bilder/Videos verschwinden nach Tab-Wechsel: Sollte mit aktueller Version nicht mehr passieren — Media-Outputs werden als ChatOutput-DB-Rows persistiert. Falls doch: alte Bilder (vor Update) sind nicht migriert; neue Generierungen bleiben.

Projekt-Tools "Kein Projekt zugewiesen": Bei den project_*-Tools muss in der Projekt-Pille oben im Chat explizit ein Projekt gewählt sein. Wechsel zu einem Chat ohne Projekt deaktiviert die Tools (sie geben klare Fehlermeldungen zurück).

Project_run_shell schlägt fehl mit "Schreibrechte deaktiviert": Im Projekt-Editor "Schreibrechte" einschalten. Gleicher Toggle wie für die CLI-Provider (Claude Code, Codex, Gemini CLI).

Codex CLI: "bwrap: No permissions to create a new namespace": Host-Kernel hat kernel.unprivileged_userns_clone=0. Typisch für UGREEN, Synology, manche Embedded-Linuxes. manage.sh update setzt das automatisch über CODEX_SANDBOX_MODE=danger-full-access in der .env. Falls die Detection nicht greift, manuell:

echo "CODEX_SANDBOX_MODE=danger-full-access" >> .env
docker compose up -d --force-recreate backend
docker exec knowsora_backend env | grep CODEX_SANDBOX_MODE

Codex CLI: "Reading additional input from stdin..." (exit 1): Behoben in aktueller Version — Codex' Argument-Parser kann durch führende -/-- im Prompt verwirrt werden und fällt in den interaktiven stdin-Modus. Fix: -- als Separator vor dem Prompt (codex exec ... -- "<prompt>").

Update gemacht aber Frontend zeigt alte Version:

  • Erst auf NAS verifizieren ob neuer Code im Container ist:

  docker exec knowsora_frontend sh -c 'ls /usr/share/nginx/html/assets/index-*.js'
  
Hash sollte sich nach Update ändern.

  • Falls Hash gleich: ZIP wurde nicht entpackt → manuell:

unzip -o knowsora_release.zip && ./manage.sh update

  • Falls Hash anders: Browser-Cache. Mobile Safari: App schließen +

neu öffnen oder iOS → Safari → Erweitert → Website-Daten löschen

Backend-Logs:

./manage.sh logs            # alle Container, live
docker logs -f knowsora_backend
docker logs -f knowsora_frontend

Filter im Backend-Log: [worker], Job <id>, Skill '<name>', OpenAI, Gemini, Claude, Grok, project_.

---

Atlassian-Integration (Jira + Confluence)

KnowSora kann sich mit Atlassian Jira und Confluence verbinden — vollständig über die WebGUI, ohne Docker-/.env-Eingriff und ohne Atlassian-Admin-Rechte. Beide nutzen denselben API-Token und greifen ausschließlich lesend zu — in Atlassian wird nichts geändert oder gelöscht.

Zwei Nutzungsarten:

  1. Live-Tools im Chat — der verbundene Zugang stellt die Such-Tools

jira_search (JQL), confluence_search (Wiki-Volltext) und confluence_get_page bereit. In einem Skill aktivieren (Admin → Skills → Tools), dann durchsucht die KI Jira/Confluence live.

  1. RAG-Sync — unter „Integrationen → Wissens-Synchronisierung" eine Quelle

anlegen: ein Jira-Projekt (per Projekt-Key, z. B. HOTSPOT) oder einen Confluence-Space (per Space-Key, z. B. ENZY aus der URL …/wiki/spaces/ENZY/…). Die Inhalte werden periodisch in eine Wissensbasis indexiert und sind dann über die normale Wissens-Suche durchsuchbar.

Einrichtung (einmalig, durch einen KnowSora-Admin):

  1. API-Token bei Atlassian erstellen — das kann jeder normale Nutzer ohne

Admin-Rechte: https://id.atlassian.com/manage-profile/security/api-tokens → „Create API token". Derselbe Token gilt für Jira und Confluence.

  1. In KnowSora: Menü „Integrationen" → Block „Jira-Verbindung (Admin)":

Site-URL (z. B. https://frederix-hotspot.atlassian.net), E-Mail des Kontos und API-Token eintragen.

  1. „Speichern", dann „Verbindung testen".

Der Token wird verschlüsselt in der Datenbank abgelegt (kein Klartext) und gilt als gemeinsamer Lesezugang für alle Nutzer der Instanz.

Nutzung (durch jeden Anwender):

  • Unter „Wissens-Synchronisierung" → „Quelle hinzufügen" Quellentyp wählen

(Jira-Projekt oder Confluence-Space), Schlüssel und Ziel-Wissensbasis angeben, Intervall wählen (manuell bis wöchentlich). Refresh-Button löst einen Sync sofort aus.

  • Im Chat (mit einem Skill, der die Atlassian-Tools aktiviert hat) direkt nach

Tickets oder Wiki-Inhalten fragen.

Hinweise:

  • Microsoft/SharePoint, GitLab und GitHub sind nicht enthalten — die

Integration ist auf Atlassian fokussiert.

  • Hintergrund: Atlassian hat den alten Jira-Such-Endpunkt zum 1. Mai 2025

abgeschaltet. KnowSora nutzt den aktuellen /rest/api/3/search/jql-Endpunkt mit Token-Pagination.

Lizenz & Kontakt

KnowSora wird von localeye.shop entwickelt und verkauft. Lizenzfragen, Support, Custom-Anpassungen: https://localeye.shop oder Mail an den Anbieter.

---

NACHTRAG (2026-07-03): Gedächtnis (persistentes Nutzer-Gedächtnis)

Neuer Menüpunkt Gedächtnis (🧠) — dauerhafte Fakten über den Nutzer, die in jedem Chat und bei jedem KI-Modell automatisch als Kontext mitgegeben werden (Provider-/Modellwechsel-übergreifend).

Automatische Extraktion

Nach jeder gespeicherten KI-Antwort prüft das Backend, ob seit dem letzten Check mindestens 6 neue Nachrichten in diesem Chat dazugekommen sind (FACTS_TRIGGER_MSGS). Ist das der Fall, wird der neue Gesprächsausschnitt an ein LLM geschickt, das daraus dauerhafte Fakten extrahiert und dabei gleich eine Kategorie vergibt: fakt / präferenz / projekt / person. Der Fortschritt wird pro Chat gemerkt (chat.facts_upto_msg_id), damit derselbe Abschnitt nicht wiederholt analysiert wird.

Autosync-Button (rückwirkende Extraktion über alle Chats)

Der laufende Auto-Trigger erfasst nur den aktuell offenen Chat. Ältere oder sehr kurze Chats (nie über die 6-Nachrichten-Schwelle gekommen) werden dabei nie erfasst. Der Autosync-Button auf der Gedächtnis-Seite holt das rückwirkend über alle Chats des Nutzers nach:

  • Läuft in Chunks (24 Nachrichten je LLM-Aufruf, max. 25 Aufrufe pro

Backend-Request), damit ein einzelner Request nicht unbegrenzt lange läuft. Das Frontend ruft den Endpoint automatisch in mehreren Runden erneut auf, bis complete: true zurückkommt — kein manuelles Mehrfach- Klicken nötig.

  • Während des Laufs zeigt der Button eine Live-Statuszeile („X Chat(s)

durchsucht, Y Fakten insgesamt") sowie die aktuelle Runde, und ist optisch deutlich als aktiv erkennbar (gefüllter „primary"-Button statt schwer erkennbarem Default-Zustand).

  • Fortschritt wird ebenfalls über chat.facts_upto_msg_id gemerkt — ein

erneuter Klick zu einem späteren Zeitpunkt durchsucht nur, was seither neu dazugekommen ist.

Kategorien & Darstellung

Fakten werden auf der Seite nach Kategorie gruppiert mit farbiger Abschnitts-Überschrift dargestellt (fakt=grau, präferenz=blau, projekt=grün, person=orange) statt als eine einzige, gleich aussehende Liste. Jeder Eintrag zeigt zusätzlich per Icon, ob er automatisch (✨) oder manuell (👤) angelegt wurde, und lässt sich bearbeiten, ausblenden („weiches Vergessen") oder löschen.

Re-Kategorisierung (einmaliger Nachlauf)

Fakten, die vor diesem Feature-Ausbau automatisch extrahiert wurden, waren alle hart auf die Kategorie „fakt" gesetzt. Der Button Neu einordnen (erscheint sobald mindestens ein Fakt existiert) schickt alle bestehenden Fakten einmalig ans LLM und ordnet jedem die passende Kategorie neu zu — beliebig oft wiederholbar, ohne Doppelverarbeitung.

„Alle löschen" / „Sync zurücksetzen"

Der Löschen-Button hat zwei Zustände: Sind Fakten vorhanden, löscht er alle und setzt zugleich den Sync-Fortschritt aller Chats zurück (facts_upto_msg_id = NULL), damit Autosync danach wieder bei null anfängt. Sind keine Fakten vorhanden, bleibt der Button trotzdem sichtbar (Label „Sync zurücksetzen") und setzt nur die Fortschritts-Zeiger zurück — ohne das wäre ein leeres Gedächtnis mit weit fortgeschrittenem Sync-Zeiger ein Deadlock: Autosync würde für immer 0 neue Nachrichten finden, und es gäbe keine Möglichkeit mehr, das über die UI zu beheben.

API-Endpunkte

GET    /api/user-memory/             — eigene Fakten (neueste zuerst)
POST   /api/user-memory/             — Fakt manuell anlegen
PUT    /api/user-memory/{id}         — Fakt bearbeiten / (de)aktivieren
DELETE /api/user-memory/{id}         — Fakt löschen
DELETE /api/user-memory/             — alle eigenen Fakten löschen + Sync-Zeiger zurücksetzen
POST   /api/user-memory/sync         — Autosync (rückwirkende Extraktion über alle Chats)
POST   /api/user-memory/recategorize — einmaliger Re-Kategorisierungs-Lauf

Obergrenze: max. 80 Fakten pro Nutzer (älteste müssen manuell gelöscht werden, um Platz zu schaffen), max. 400 Zeichen pro Fakt.

---

NACHTRAG (2026-07-02): Dokumenten-Generator, Auto-Scroll & SQLite-WAL

📄 Dokumenten-Generator (Skill)

Neuer Default-Skill Dokumenten-Generator (generate_document, convert_document):

  • generate_document — erstellt Angebote, Rechnungen, Berichte und

Anschreiben als PDF und/oder Word (Titel, Intro-Zeilen, Abschnitte mit Fließtext/Bullets, Positionstabelle mit Summenzeile, Footer).

  • convert_document — konvertiert eine im Chat hochgeladene Datei

zwischen PDF und Word. pdf_to_word läuft rein in Python (pdf2docx), word_to_pdf nutzt LibreOffice headless im Container.

  • Will der User ein Angebot/eine Rechnung per Mail versenden, schreibt die

KI zusätzlich automatisch einen fertigen, copy-paste-fähigen E-Mail-Text (Betreff, Anrede, Fließtext, Grußformel) direkt in die Antwort.

Voraussetzung: Das Systempaket libreoffice-writer wird im Image installiert (Dockerfile ARG INSTALL_LIBREOFFICE=true). Ohne dieses Paket liefert word_to_pdf eine klare Fehlermeldung statt eines Absturzes; auf INSTALL_LIBREOFFICE=false bauen spart ca. 350–450 MB Image-Größe, dann ist nur noch pdf_to_word verfügbar.

Chat-Auto-Scroll

Der Chat scrollt während einer laufenden KI-Antwort jetzt automatisch smooth nach unten mit — kein manuelles Scrollen mehr nötig. Scrollt der Nutzer währenddessen selbst nach oben, pausiert der Auto-Scroll (kein Wegreißen aus dem Verlauf) und ein „Zum Ende springen"-Button erscheint unten rechts.

SQLite WAL-Modus (Stabilität)

Die Datenbank läuft jetzt im WAL-Journal-Modus mit busy_timeout=30000 statt im Standard-DELETE-Modus. Reduziert sporadische „database is locked"-Fehler bei mehreren gleichzeitigen Hintergrund-Jobs (Polling, Streaming, Attachments).

Enterprise / Mehrbenutzerbetrieb (PostgreSQL, optional)

Problem mit SQLite: SQLite serialisiert Schreibzugriffe — auch mit WAL-Modus (siehe oben) bleibt es der Flaschenhals, sobald viele Mitarbeiter gleichzeitig aktiv chatten, Dokumente hochladen oder KBs bearbeiten (reger paralleler Schreibzugriff). Für einzelne Nutzer bis kleine Teams ist SQLite weiterhin völlig ausreichend und bleibt der Standard — es ändert sich für bestehende Installationen nichts, solange nichts konfiguriert wird.

Lösung: KnowSora unterstützt jetzt optional PostgreSQL als Datenbank-Backend. Postgres nutzt Zeilen- statt DB-weites Locking und skaliert damit deutlich weiter für parallele Mehrbenutzer-Last. Der Wechsel ist rein konfigurativ — die SQLAlchemy-Modelle sind unverändert DB-agnostisch.

Bestehende Installation → automatisch (Standardfall, kein manuelles Eintragen nötig): ./manage.sh update prüft bei jedem Lauf selbst, ob noch die alte SQLite-Datei (${DATA_DIR}/data/knowsora.db) mit echten Daten existiert und DATABASE_URL noch nicht auf Postgres zeigt. Trifft das zu, macht es ohne Rückfrage:

  1. Ein zufälliges, sicheres Passwort generieren (openssl rand -hex 24).
  2. POSTGRES_PASSWORD, DATABASE_URL (User knowsora) und

COMPOSE_PROFILES=postgres in .env eintragen.

  1. Postgres-Container starten, auf healthy warten.
  2. Alle Tabellen einmalig aus der SQLite-Datei übernehmen (Nutzer, Chats,

Skills, KB-Metadaten; Sequenzen werden korrekt fortgesetzt) — bevor das Backend gegen Postgres startet, damit kein doppelter admin-User entsteht.

  1. Danach normal weiterbauen und starten — ab jetzt läuft die Installation

dauerhaft auf Postgres.

Das eigene, generierte Postgres-Passwort steht danach in .env unter POSTGRES_PASSWORD (nicht identisch mit dem Admin-Login der WebGUI).

Neue Installation manuell aktivieren (nur relevant, wenn von Anfang an Postgres statt SQLite gewünscht ist, ohne existierende SQLite-Daten):

  1. In .env: POSTGRES_PASSWORD setzen, COMPOSE_PROFILES=postgres

aktivieren, DATABASE_URL=postgresql+asyncpg://knowsora:<PASSWORT>@127.0.0.1:<POSTGRES_PORT>/knowsora eintragen (Beispielzeilen dazu bereits in .env.example).

  1. ./manage.sh update

Details:

  • Der postgres-Container startet nur wenn COMPOSE_PROFILES=postgres

gesetzt ist — ohne diese Zeile (bzw. solange keine alte SQLite-Installation mit Daten erkannt wird) bleibt alles beim SQLite-Standard, kein zusätzlicher Container, kein Risiko für bestehende Setups.

  • Postgres-Daten liegen persistent unter ${DATA_DIR}/data/postgres.
  • Pool-Größe (DB_POOL_SIZE/DB_MAX_OVERFLOW, Default 10/20) in .env

einstellbar — höher für sehr viele gleichzeitige Nutzer.

  • ./manage.sh reembed / embed-reset funktionieren mit Postgres genauso

wie mit SQLite (nutzen intern die normale DB-Engine, kein fest verdrahteter SQLite-Zugriff mehr).

  • ./manage.sh migrate-to-postgres bleibt als manueller Einzelbefehl

verfügbar (z.B. für eine erneute/manuelle Migration) — im Normalfall übernimmt ./manage.sh update das automatisch, siehe oben.

  • Robust gegen Abbrüche: Ob wirklich noch migriert werden muss, prüft

./manage.sh update bei jedem Lauf neu anhand von zwei Dingen — COMPOSE_PROFILES=postgres aktiv und kein Marker ${DATA_DIR}/data/.postgres_migrated vorhanden. War ein vorheriger update-Lauf schon so weit, .env auf Postgres umzustellen, aber die eigentliche Datenübernahme wurde unterbrochen (Absturz, Neustart mitten im Deploy o.ä.), holt der nächste update-Lauf das automatisch nach — der Marker wird erst nach erfolgreichem Abschluss gesetzt. Der Migrationslauf selbst ist idempotent (leert die Ziel-Tabellen vor jedem (Re-)Import), ein Retry führt also nicht zu doppelten Daten.

  • Fehlen POSTGRES_PASSWORD/DATABASE_URL in einer bestehenden .env

obwohl COMPOSE_PROFILES=postgres schon gesetzt ist (z.B. unvollständiges manuelles Setup), ergänzt ./manage.sh update sie automatisch mit einem neu generierten Passwort — auch hier ohne manuelles Eintragen.

  • Rückweg (Postgres → SQLite) ist nicht automatisiert — bei Bedarf Daten

manuell zurückexportieren.

---

NACHTRAG (2026-06-14): Neue Features & Fixes

Billing-Anzeige im Chat (OAuth = gratis / API = Kosten)

Im aktiven Chat zeigt das Badge neben dem KI-Provider-Selector jetzt klar an welcher Modus genutzt wird:

  • Gratis (grünes Label) — OAuth-Token aktiv, kein Tokensverbrauch
  • Token (oranges Label) — API-Key wird genutzt, Kosten entstehen

Sichtbar direkt neben der Provider-Pille oben links im Chat — ohne in die Einstellungen zu müssen. Gilt für Claude Code, Codex und Gemini CLI in allen Auth-Modi.

Auf der KI-Modelle-Seite (Admin-Bereich) erscheint ebenfalls pro CLI- Provider eine Billing-Statuszeile: "OAuth aktiv (kostenlos)" oder "API-Key aktiv (kostenpflichtig)".

Live-Update bei automatischem Fallback (Auth-Modus „Automatisch"): Wenn während eines laufenden Chats das OAuth-Session-Limit erreicht wird (oder der Token abgelaufen/ungültig ist), schaltet KnowSora mitten in der Antwort automatisch auf den hinterlegten API-Key um — und das Badge springt im selben Moment von "Gratis" auf "Token", ohne Reload oder Chat-Wechsel. Backend meldet pro Antwort actual_billing (was tatsächlich genutzt wurde), das Frontend übernimmt diesen Wert sofort ins Badge. Betrifft nur den Auth-Modus „Automatisch" — bei „Nur OAuth"/„Nur API-Key" bleibt das Badge naturgemäß fix, da dort kein Fallback stattfindet.

OpenRouter 429 → Klare deutsche Fehlermeldung

Wenn ein OpenRouter-Modell sein Tageslimit erreicht hat (HTTP 429), erscheint jetzt eine verständliche Meldung statt roher JSON:

OpenRouter-Limit erreicht (429): Dieses Modell ist für heute ausgereizt.
KnowSora versucht automatisch ein Fallback-Modell …

KnowSora versucht danach automatisch bis zu 2 weitere Free-Modelle (mit Tool-Calling-Support wenn ein Skill aktiv ist).

Codex bwrap → Auto-Retry

Wenn Codex mit "bwrap: No permissions to create a new namespace" scheitert, startet KnowSora den Aufruf automatisch mit --sandbox danger-full-access neu — ohne Neustart und ohne manuelle .env-Änderung. Der bisherige manage.sh-Mechanismus (CODEX_SANDBOX_MODE) bleibt als persistente Standardeinstellung erhalten, der Auto-Retry fängt daneben noch alle Runtime-Ausnahmen ab.

Limit-Meldung ohne rohe JSON-Details

Provider-Fehlermeldungen (Rate-Limits, Kontingente, Auth-Fehler) werden jetzt grundsätzlich bereinigt bevor sie dem User angezeigt werden. Kein roher JSON-Body mehr in der Chat-UI — nur die relevante Kerninformation.

Text-Insert-Chips bei Chat-Wechsel geleert

Beim Wechsel zu einem anderen Chat werden offene "Text-einfügen"-Snippets (pasteBlocks) automatisch zurückgesetzt. Kein versehentliches Absenden von aus einem anderen Chat kopierten Text-Bausteinen mehr.

Datum-Anzeige-Fix

Backend und Frontend zeigen Nachrichten-Zeitstempel jetzt konsistent in der lokalen Zeitzone des Browsers an. Fix betrifft Chat-Verlauf und Projekt- Dateilisten.

---

NACHTRAG (2026-06-11): CLI-Auth & Fallbacks

Auth-Modi pro CLI-Provider

In den KI-Anbieter-Einstellungen wählbar:

  • Automatisch (empfohlen): OAuth bevorzugt (kostenlos), API-Key als

automatischer Fallback bei Fehler/Limit.

  • Nur OAuth: keine Token-Kosten, kein Fallback.
  • Nur API-Key: zuverlässig, kostet Tokens.

Codex per OAuth einloggen (kostenlos, CLI 0.139+)

  1. Im OpenAI-/ChatGPT-Account: Einstellungen → Sicherheit → „Autorisierung per

Gerätecode für Codex" aktivieren.

  1. In KnowSora: KI-Anbieter → Codex → „Neu einloggen".
  2. Login-URL kopieren, im Browser öffnen, mit ChatGPT anmelden.
  3. Der Browser zeigt eine Fehlerseite (localhost:1455) — das ist normal.
  4. Die komplette Adresse dieser Fehlerseite (mit ?code=…) in KnowSora ins

Feld „Adresse der Fehlerseite einfügen" kopieren → „Abschließen".

  1. Prüfen: docker exec knowsora_backend ls -la /data/.claude_home/.codex/auth.json

Claude Code per OAuth

KI-Anbieter → Claude Code → „Neu einloggen" → /login im Terminal → URL im Browser anmelden → Code zurück einfügen.

CLI reparieren

Bei „exit 1" oder hängenden Aufrufen: „Reparieren"-Button beim jeweiligen CLI-Provider. Leert Session/Cache, Token bleibt erhalten.

Vollständige Auth-Doku & Changelog: siehe CHANGELOG-AUTH.md.

Setup Guide

Installation auf jedem System — ZIP-Namen, Port und IP-Beispiele unten je Produkt anpassen.

  1. Container Manager installieren

DSM → Paketzentrum → Container Manager suchen und installieren.

  1. SSH aktivieren

DSM → Systemsteuerung → Terminal & SNMP → SSH aktivieren.

ssh admin@SYNOLOGY-IP
  1. ZIP hochladen & entpacken
scp produktname_release.zip admin@SYNOLOGY-IP:/volume1/docker/
ssh admin@SYNOLOGY-IP
cd /volume1/docker
unzip produktname_release.zip -d produktname
cd produktname
cp .env.example .env
  1. Starten
./manage.sh update

WebUI: http://SYNOLOGY-IP:PORT — Login: admin / admin

💡 Synology DSM 7.2+ mit Container Manager 20.10+ empfohlen. Pfad /volume1/docker/ ggf. anpassen.
KnowSora

Preis zzgl. 19% MwSt. Einmalzahlung, keine Abo-Kosten, self-hosted.

  • 🔒 Verschlüsselte API-Key-Speicherung (Fernet, AES-128 + HMAC)
  • 🧠 Contextual Retrieval (Anthropic-Methode) für präzisere KB-Trefferqualität statt simplem Chunk-Embedding
  • 🌐 Web-Seiten per Crawler direkt in die Wissensdatenbank aufnehmen
  • 📎 Bilder + Dateien pro Chat-Nachricht mit Vision-Support
  • 🎙️ Sprachein-/ausgabe (STT + TTS) via OpenAI oder Gemini
  • 💾 Automatische Download-Buttons für vom KI erzeugte Files
  • 🎯 Projektordner-Integration für CLI-Provider (direkte File-Bearbeitung)
  • 🧩 Persistentes User-Memory: KI merkt sich Fakten chat- und anbieterübergreifend
  • 🔌 Skills-System: eigene Tools/Skills anlegen oder importieren
  • 📊 Verbrauchs-Dashboard mit Kostenübersicht pro Provider
  • 🆓 OpenRouter-Anbindung inkl. kostenloser Modelle
  • 🔄 Background-Jobs für lange Anfragen (Chat blockiert nicht)
  • 🌐 Embed über Reverse-Proxy für eigene Subdomain möglich
  • 👥 Multi-User mit Admin-Rolle und User-Management
Jetzt kaufen