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.
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:
manage.sh (UGREEN-tauglich).env.example---
# 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).env.example werden in deinebestehende .env nachgepflegt (alte Werte bleiben erhalten)
SECRET_KEY generieren falls leer (via openssl / python3 / /dev/urandom)und persistent in /data/.secret_key ablegen
./manage.sh logs---
wird; ohne lokales LLM reichen 4 GB)
/dev/dri für VAAPI-Beschleunigung beimlokalen LLM (Intel N100, Pentium Gold 8505, N-Series)
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:
manage.sh selbst(versucht unzip → python3 → python → docker run alpine, je nach dem was auf dem Host verfügbar ist — funktioniert auch auf UGREEN/Synology ohne unzip-Paket)
.env.example nach .env(bestehende Werte werden NIE überschrieben, nur neue Keys ergänzt)
unprivileged_usernsblockiert (NAS-typisch)
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).
---
./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_KEYniemals ä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_keypersistiert — beide Pfade (.envund.secret_key) sollten Teil deines Backups sein. Der Fernet-Verschlüsselungs-Key für API-Keys in der DB wird per PBKDF2 ausSECRET_KEYabgeleitet — eine separateFERNET_KEY-Variable gibt es nicht.
---
manage.sh ist mehr als nur docker compose-Wrapper. Bei jedem start oder update laufen automatisch:
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
.env.examplePflegt 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.
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.
---
KnowSora unterstützt neun Provider — alle parallel nutzbar. Auswahl pro Chat via Provider-Pille oben links.
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.
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.
KI-Modelle → Claude → API-Key + Modell-ID (z.B. claude-sonnet-4-5, claude-opus-4-7).
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.
KI-Modelle → xAI Grok → API-Key (auf console.x.ai generieren). Modell-Vorschläge:
grok-4.3 (Default) — schnell + günstig, gute Tool-Callsgrok-4.20 — Flagship-Reasoninggrok-imagine-image-quality — Bildgenerierung (vom Medien-Generatorvia 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.
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ähltzur 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 Contextdeepseek/deepseek-v4-flash:free — Reasoning, 1M Contextmeta-llama/llama-3.3-70b-instruct:free — Solider Allzweckgoogle/gemini-2.0-flash-exp:free — Multimodal, schnellopenai/gpt-5 — kostenpflichtig, falls Credits aufgeladenanthropic/claude-sonnet-4.6 — kostenpflichtigPer-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):
20 req/min
KnowSora-Features für OpenRouter:
openrouter/smart) — wählt zur Laufzeit das besteFree-Modell passend zum aktiven Skill (Capability-Scoring nach Tool-Support, Context-Größe, Modell-Familie)
/api/v1/models geladen (1h Cache)
gekaufte und verbrauchte Credits
erreicht hat, probiert KnowSora automatisch bis zu 2 weitere Free-Modelle (filtert auf Tool-Calling-fähige falls Skill aktiv)
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"
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.
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):
einloggen, Code zurück ins Terminal
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.
---
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.
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.
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:
fehl, list/read funktionieren weiterhin
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.
generate_image — KI-Bildgenerierung. Parameter provider:
openai (Default) — gpt-image-1, fotorealistisch, ggf. Org-Verificationgemini — imagen-4.0-generate-001, künstlerisch starkgrok — grok-imagine-image-quality, fotorealistisch + starke Text-Wiedergabeedit_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, fotorealistischgemini — gemini-2.5-flash-image (Nano Banana), kreativgrok — grok-imagine-image-quality Edits, Base64-data-URI als Inputgenerate_video — Video-Generierung. Parameter provider:
gemini (Default) — Google Veo 3, 4-8 Sek, ca. 1-3 min Wartezeitgrok — grok-imagine-video, 5-15 Sek, ~30 Sek WartezeitOpenAI und Anthropic haben keine öffentliche Video-API. Sora ist nur in ChatGPT verfügbar, nicht via API.
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.png → bild (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.
---
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 (pending → processing → ready).
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 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:
- 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
node_modules, .git, .venv, dist, build, __pycache__ u.a.) - Standard: Hidden-Files ausgeschlossen - ?include_hidden=true für Backups inkl. .env
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.
---
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.
---
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.
---
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:
{{download:/tmp/foo.html}} oder[[download:/tmp/foo.html]]
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.
---
Seit Mai 2026 unterstützt KnowSora Speech-to-Text (STT) und Text-to-Speech (TTS) mit drei wählbaren 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.
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ü).
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.
KnowSora hat eingebautes Wörterbuch das ~50 Tech-Abkürzungen automatisch korrekt ausspricht:
automatisch und spielt sie nacheinander ab)
erlaubt — der erste Lautsprecher-Tap pro Tab muss manuell sein
---
Seit Mai 2026 nutzt search_knowledge_base Hybrid-Retrieval statt reiner Vektor-Suche. Keine Konfiguration nötig — ist immer aktiv.
Jede Suche läuft parallel über zwei Engines:
Inhalte, auch bei Synonymen und Umschreibungen
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.
BM25-Index wird pro KB-Filter im Speicher gehalten und automatisch invalidiert bei:
Erster Search-Call nach Cache-Invalidierung baut den Index neu auf (<100ms bei 10k Chunks).
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.
---
Optional pro KB aktivierbar. Basiert auf der Anthropic-Methode anthropic.com/news/contextual-retrieval.
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?".
KB öffnen → Bearbeiten → "🧠 Contextual Retrieval (smart chunking)" einschalten → LLM-Provider wählen → Speichern.
Provider-Auswahl pro KB:
Ü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.
5s → 15s → 30s → 60s (max 5 Versuche pro Chunk)
DOC_PROCESS_TIMEOUT_MAX in .env
| 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.
---
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.
---
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.
---
Render-Fehler im Frontend werden abgefangen — statt blank-screen siehst du eine Fallback-UI mit:
<details>Globale window.error + unhandledrejection Listener loggen zusätzlich in localStorage["knowsora-errors"] (letzte 30 Events) für Post-Mortem-Diagnose.
Bei OpenAI 400-Fehler:
temperatureumgestelltem Feld
Bei Gemini 400:
Klare Übersetzung von 404/503-Fehlern in deutsche User-Meldungen mit Hinweis welches Modell stattdessen funktioniert.
Chat-Anfragen laufen als Background-Job:
/api/chat/job/{id} → liest Status +Activity-Events live
localStorage["kh-job-<chat_id>"] gecached → Tabschließen + wieder aufmachen verbindet sich nahtlos wieder
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.
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).
---
| 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.
---
┌──────────────┐
│ 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-DBchroma/ — Vektor-Storemodels/ — GGUF-Dateienuploads/ — Chat-Attachments + Provider-Output-Filesmedia/<user>/<datum>/ — KI-Bilder/Videos (persistent unabhängig vom Chat)projects/<user>/<slug>/ — Coding-Projekteprojects/<user>/<slug>/outputs/<datum>/ — automatische Backup-Kopien aller Chat-Outputs für diesen Chat.claude_home/, .codex/, .gemini/ — CLI-OAuth-TokensBackup-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.
---
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":
veo-3.0-generate-001 (Premium) oderveo-3.0-fast-generate-001 (günstiger) oder veo-2.0-generate-001 (Fallback)
model: "veo-2.0-generate-001" als OverrideBilder/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:
docker exec knowsora_frontend sh -c 'ls /usr/share/nginx/html/assets/index-*.js'
Hash sollte sich nach Update ändern.
unzip -o knowsora_release.zip && ./manage.sh update
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_.
---
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:
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.
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):
Admin-Rechte: https://id.atlassian.com/manage-profile/security/api-tokens → „Create API token". Derselbe Token gilt für Jira und Confluence.
Site-URL (z. B. https://frederix-hotspot.atlassian.net), E-Mail des Kontos und API-Token eintragen.
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):
(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.
Tickets oder Wiki-Inhalten fragen.
Hinweise:
Integration ist auf Atlassian fokussiert.
abgeschaltet. KnowSora nutzt den aktuellen /rest/api/3/search/jql-Endpunkt mit Token-Pagination.
KnowSora wird von localeye.shop entwickelt und verkauft. Lizenzfragen, Support, Custom-Anpassungen: https://localeye.shop oder Mail an den Anbieter.
---
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).
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.
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:
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.
durchsucht, Y Fakten insgesamt") sowie die aktuelle Runde, und ist optisch deutlich als aktiv erkennbar (gefüllter „primary"-Button statt schwer erkennbarem Default-Zustand).
chat.facts_upto_msg_id gemerkt — einerneuter Klick zu einem späteren Zeitpunkt durchsucht nur, was seither neu dazugekommen ist.
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.
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.
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.
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.
---
Neuer Default-Skill Dokumenten-Generator (generate_document, convert_document):
Anschreiben als PDF und/oder Word (Titel, Intro-Zeilen, Abschnitte mit Fließtext/Bullets, Positionstabelle mit Summenzeile, Footer).
zwischen PDF und Word. pdf_to_word läuft rein in Python (pdf2docx), word_to_pdf nutzt LibreOffice headless im Container.
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.
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.
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).
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:
openssl rand -hex 24).POSTGRES_PASSWORD, DATABASE_URL (User knowsora) undCOMPOSE_PROFILES=postgres in .env eintragen.
healthy warten.Skills, KB-Metadaten; Sequenzen werden korrekt fortgesetzt) — bevor das Backend gegen Postgres startet, damit kein doppelter admin-User entsteht.
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):
.env: POSTGRES_PASSWORD setzen, COMPOSE_PROFILES=postgresaktivieren, DATABASE_URL=postgresql+asyncpg://knowsora:<PASSWORT>@127.0.0.1:<POSTGRES_PORT>/knowsora eintragen (Beispielzeilen dazu bereits in .env.example).
./manage.sh updateDetails:
postgres-Container startet nur wenn COMPOSE_PROFILES=postgresgesetzt 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.
${DATA_DIR}/data/postgres.DB_POOL_SIZE/DB_MAX_OVERFLOW, Default 10/20) in .enveinstellbar — höher für sehr viele gleichzeitige Nutzer.
./manage.sh reembed / embed-reset funktionieren mit Postgres genausowie mit SQLite (nutzen intern die normale DB-Engine, kein fest verdrahteter SQLite-Zugriff mehr).
./manage.sh migrate-to-postgres bleibt als manueller Einzelbefehlverfügbar (z.B. für eine erneute/manuelle Migration) — im Normalfall übernimmt ./manage.sh update das automatisch, siehe oben.
./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.
POSTGRES_PASSWORD/DATABASE_URL in einer bestehenden .envobwohl 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.
manuell zurückexportieren.
---
Im aktiven Chat zeigt das Badge neben dem KI-Provider-Selector jetzt klar an welcher Modus genutzt wird:
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.
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).
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.
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.
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.
Backend und Frontend zeigen Nachrichten-Zeitstempel jetzt konsistent in der lokalen Zeitzone des Browsers an. Fix betrifft Chat-Verlauf und Projekt- Dateilisten.
---
In den KI-Anbieter-Einstellungen wählbar:
automatischer Fallback bei Fehler/Limit.
Gerätecode für Codex" aktivieren.
localhost:1455) — das ist normal.?code=…) in KnowSora insFeld „Adresse der Fehlerseite einfügen" kopieren → „Abschließen".
docker exec knowsora_backend ls -la /data/.claude_home/.codex/auth.jsonKI-Anbieter → Claude Code → „Neu einloggen" → /login im Terminal → URL im Browser anmelden → Code zurück einfügen.
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.
Installation auf jedem System — ZIP-Namen, Port und IP-Beispiele unten je Produkt anpassen.
DSM → Paketzentrum → Container Manager suchen und installieren.
DSM → Systemsteuerung → Terminal & SNMP → SSH aktivieren.
ssh admin@SYNOLOGY-IP
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
./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.
Preis zzgl. 19% MwSt. Einmalzahlung, keine Abo-Kosten, self-hosted.