Lokale, private KI-Wissensdatenbank. Läuft komplett offline auf deinem Rechner. Dokumente und Web-Seiten werden in Vektoren überführt und können per Chat (lokales LLM oder optional OpenAI / Gemini / Claude) abgefragt werden.
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 Mai 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 Mai 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 |
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.
KnowSora is a self-hosted AI assistant with RAG knowledge databases, nine interchangeable LLM providers (incl. xAI Grok and OpenRouter), a skill system with built-in tools (AI image and video generation, project file access for every AI, shell execution), project directories with universal file preview and a web terminal for SSH access.
Documentation as of May 2026 — if something looks different in the app, the app is the source of truth. Current version includes:
manage.sh (UGREEN-compatible).env.example---
# 1. Get code or extract ZIP
cd /volume3/docker/knowsora
unzip -o knowsora_release.zip # if delivered as ZIP
# 2. Start — manage.sh handles .env + SECRET_KEY + Docker
./manage.sh start
# 3. In browser
http://<NAS-IP>:47822
On first start, admin / admin is created — go directly to admin area after login and set your own password.
What ./manage.sh start does automatically:
.env from .env.example (if not present).env.example are merged into yourexisting .env (old values retained)
SECRET_KEY if empty (via openssl / python3 / /dev/urandom)and persistently store in /data/.secret_key
./manage.sh logs---
without local LLM 4 GB sufficient)
/dev/dri for VAAPI acceleration withlocal LLM (Intel N100, Pentium Gold 8505, N-Series)
Get new release ZIP → simply place it in project directory and update:
cd /volume3/docker/knowsora
# Place knowsora_release.zip there (e.g. via scp/SFTP/web upload)
./manage.sh update
manage.sh update automatically:
manage.sh itself(tries unzip → python3 → python → docker run alpine, depending on what's available on host — works on UGREEN/Synology without unzip package)
.env.example to .env(existing values NEVER overwritten, only new keys added)
unprivileged_userns(NAS-typical)
For build cache issues or broken images:
docker compose down
docker rmi knowsora-backend:latest knowsora-frontend:latest
./manage.sh update
Build logs output with --progress plain — no animated spinners, each step appears once as plain text (important for SSH sessions without fully interactive TTY).
---
./manage.sh start automatically creates .env from .env.example and generates the SECRET_KEY. Only edit manually if you want to change defaults (ports, data path, timeouts, provider keys in advance).
Standard fields you might want to adjust:
| Variable | Meaning | Example / Default | |---|---|---| | SECRET_KEY | JWT signature + derivation of encryption key | Automatically generated if empty | | FRONTEND_PORT | Port of web UI | 47822 | | BACKEND_PORT | Port of API | 48823 | | LLAMA_CHAT_PORT | Port of local LLM | 48824 | | ADMIN_PASSWORD | Initial password for admin user | admin (change immediately!) |
Optional but recommended:
| Variable | Default | Purpose | |---|---|---| | HOST_UID / HOST_GID | 1000:1000 | UID/GID under which containers run — adapts file permissions to your NAS volume | | DATA_DIR | /data | In-container path for persistent data | | MEDIA_ROOT | /data/media | AI-generated images/videos | | UPLOAD_DIR | /data/uploads | Chat attachments + provider output files | | LLM_HTTP_TIMEOUT | 3600 | Seconds — for long AI responses | | CLAUDE_CLI_TIMEOUT | 3600 | Claude Code CLI hard cap per call | | CODEX_CLI_TIMEOUT | 3600 | Codex CLI hard cap per call | | GEMINI_CLI_TIMEOUT | 3600 | Gemini CLI hard cap per call | | VEO_MODEL | veo-3.0-generate-001 | Video generation model — veo-2.0-generate-001 if Veo 3 not enabled | | VEO_MAX_POLL_S | 600 | Maximum wait time for video rendering | | PROJECT_SHELL_TIMEOUT | 90 | Seconds — hard cap for project_run_shell tool | | CODEX_SANDBOX_MODE | _(empty)_ | NAS workaround: danger-full-access if kernel.unprivileged_userns_clone=0 (UGREEN/Synology). Values: read-only, workspace-write, danger-full-access |
Important about encryption: Never changeSECRET_KEYif data already exists in DB. Otherwise all encrypted API keys become unusable and all sessions must re-login. On first start, the key is automatically persisted in/data/.secret_key— both paths (.envand.secret_key) should be part of your backup. The Fernet encryption key for API keys in DB is derived fromSECRET_KEYvia PBKDF2 — there is no separateFERNET_KEYvariable.
---
manage.sh is more than just a docker compose wrapper. On each start or update, it automatically runs:
If a knowsora_release.zip is placed in project root that's newer than the last extracted version, manage.sh extracts it itself. Fallback chain for hosts without unzip package:
1. unzip Standard on Linux with zip tools
2. python3 -m zipfile everywhere Python 3 is available (e.g. UGREEN)
3. python -m zipfile Python 2 fallback
4. docker run alpine last resort — Docker is there anyway
After successful extraction, the ZIP mtime is set 24h in the past, so the auto-trigger doesn't fire endlessly. On next re-upload of a ZIP (newer mtime) it triggers again.
Log output:
[KnowSora] New knowsora_release.zip detected — auto-extracting...
[KnowSora] → 'unzip' missing, using python3 zipfile
[OK] knowsora_release.zip extracted
.env.exampleMerges missing ENV variables from .env.example into your .env without overwriting existing values. Only keys completely missing from .env are added — commented-out values (# FOO=...) are considered "deliberately disabled" and won't be activated.
Merged keys end up at the end of .env under:
# ─── Auto-merged from .env.example ───
So on updates you automatically get all new config options without losing your own values.
Automatically detects if host kernel has unprivileged_userns_clone=0 (typical for UGREEN, Synology, some Docker setups) and sets CODEX_SANDBOX_MODE=danger-full-access in .env.
Background: Codex CLI uses bubblewrap as sandbox. On kernels without unprivileged user namespaces, bwrap fails with "No permissions to create a new namespace" and Codex breaks. The container is isolated by Docker anyway, so no real security loss.
Logic: only if CODEX_SANDBOX_MODE= empty in .env AND sysctl kernel.unprivileged_userns_clone == 0. If you manually set the value (any value like danger-full-access, read-only or other), it won't be touched.
---
KnowSora supports nine providers — all usable in parallel. Selection per chat via provider pill at top left.
Runs in container knowsora-llama-chat. Model selection: place GGUF file in /data/models/, set in .env:
CHAT_MODEL_PATH=/models/qwen3-4b-q4_k_m.gguf
Restart container. Recommendation for 4 GB mode: Qwen3-4B-Q4_K_M. For 8 GB: Qwen3-7B-Instruct-Q4_K_M.
AI Models → OpenAI → API key + model ID (e.g. gpt-4o, gpt-5, o1-mini).
KnowSora automatically detects whether model needs max_completion_tokens instead of max_tokens (gpt-5, o1, o3, o4) and whether temperature is supported. On API errors retries twice with suitable fields before giving up.
AI Models → Claude → API key + model ID (e.g. claude-sonnet-4-5, claude-opus-4-7).
AI Models → Gemini → API key + model ID (gemini-2.5-pro, gemini-2.5-flash, gemini-3-pro-preview).
Note: Preview models often only enabled for specific accounts/regions. On 503 or "not found" switch to stable model.
AI Models → xAI Grok → API key (generate on console.x.ai). Model suggestions:
grok-4.3 (Default) — fast + cheap, good tool callsgrok-4.20 — flagship reasoninggrok-imagine-image-quality — image generation (callable from media generatorvia provider="grok")
grok-imagine-video — video generation (via media generator)Auth: xAI has no OAuth procedure for the API. Not even with X Premium / SuperGrok subscription. API key only. Credits must be explicitly topped up, no free tier.
AI Models → OpenRouter → API key (generate on openrouter.ai, Google/GitHub login possible, no card required for free tier).
What makes OpenRouter special: One API key, access to 300+ models from OpenAI, Anthropic, Google, xAI, Meta, DeepSeek, Mistral and many more — incl. dedicated free tier models for completely free usage (with rate limit).
Recommended model choice:
openrouter/free (Default, killer feature) — Smart routing, selectsat runtime the best free model matching active skill: - Coding assistant → Qwen3 Coder (1M context) - Knowledge research → Llama 3.3 70B / DeepSeek V4 / Gemini 2.0 Flash - Data analyst → DeepSeek V4 Flash (reasoning) - Web research → Llama 3.3 / DeepSeek - Media generator → first general-purpose free model with tool support - Coder models automatically excluded for non-coding skills (anti_hints in heuristic)
qwen/qwen3-coder:free — top coding model, 1M contextdeepseek/deepseek-v4-flash:free — reasoning, 1M contextmeta-llama/llama-3.3-70b-instruct:free — solid general-purposegoogle/gemini-2.0-flash-exp:free — multimodal, fastopenai/gpt-5 — paid, if credits loadedanthropic/claude-sonnet-4.6 — paidPer-skill override: You can pin a preferred free model per skill in Skills → Edit → "🌐 Preferred OpenRouter Free Model". Smart routing then uses this instead of heuristic. Leave empty for auto-choice.
Rate limits (May 2026):
20 req/min
KnowSora features for OpenRouter:
openrouter/smart) — selects at runtime bestfree model matching active skill (capability scoring by tool support, context size, model family)
/api/v1/models (1h cache)
purchased and used credits
automatically tries up to 2 more free models (filters for tool-calling-capable if skill active)
HTTP-Referer +X-Title headers so your usage appears on OpenRouter leaderboards
Cache refresh if new free models expected:
curl -X POST http://localhost:48823/api/openrouter/refresh-cache \
-H "Authorization: Bearer $YOUR_KNOWSORA_TOKEN"
For other hosters with OpenAI API format (Together, Groq, local APIs, etc.). AI Models → Custom → base URL + API key + model ID.
OpenRouter should be used via dedicated provider (no. 6) — otherwise you miss free tier detection, auto-fallback and credits display.
Three locally installed CLIs in backend container. Login via OAuth (free for Pro/Plus/Subscription users) or API key.
Subscription overview (no extra API costs):
| CLI | Subscription | Billing Model | |---|---|---| | Claude Code | Anthropic Pro/Team | 5-hour limits, max ~50 requests/5h | | Codex | ChatGPT Plus/Pro/Team | Included in ChatGPT plan | | Gemini CLI | Google account (free) | 1000 requests/day with Gemini 2.5 Flash free |
OAuth login workflow (all three identical):
paste code back in terminal
After successful login: KnowSora detects OAuth token automatically periodically (every 2 sec) and closes login window.
Important — CLI in container mode: Backend container automatically adds a passwd entry for container UID on startup. Otherwise node-based CLIs crash (especially Gemini's FileKeychain) with uv_os_get_passwd returned ENOENT. If issues: restart backend, then ensure_passwd_entry() runs again.
---
A skill = system prompt + tool whitelist. Selectable via skill pill at chat start. When skill is active, AI runs in tool loop and can call enabled tools.
Included default skills:
| Skill | Tools | Purpose | |---|---|---| | 🪄 Knowledge Research | search_knowledge_base, read_document, list_documents | RAG answers with sources | | 🌐 Web Research | web_search, url_fetch, datetime_tool | DuckDuckGo + read webpages | | 📊 Data Analyst | list_documents, query_table, calculate | Evaluate CSV/XLSX via SQL | | 💻 Coding Assistant | project_, python_exec, regex_test, json_tool, datetime_tool, http_request, url_fetch, web_search | Write/test code, work in project folder | | 🤖 Claude Code | project_, all coding tools + KB search | Senior engineer persona with project tools | | 🎨 Media Generator | generate_image, edit_image, generate_video | Images/videos via OpenAI + Google + Grok |
Skills are editable (Admin → Skills) — system prompt + tool list + icon + color per skill. "Reset to default" available per skill. New skills from updates are incrementally merged, your changes retained.
search_knowledge_base — Hybrid search (BM25 + vector with reciprocal rank fusion) in a knowledge base. Returns top-10 chunks with source metadata (max 20). Reliably finds proper names and exact terms, not just semantically similar content.
read_document / list_documents — Load full text of document / list files of knowledge base.
query_table — DuckDB SQL over CSV/XLSX documents in knowledge base. Ideal for "How many orders last month?" or aggregations.
calculate — Python math expressions (sandboxed).
python_exec — Full Python sandbox in separate subprocess, with output file capture. Files created under /tmp/ automatically become download buttons in chat.
web_search / url_fetch — DuckDuckGo search + read webpages as markdown (BS4 + readability).
http_request — Arbitrary HTTP calls (GET/POST/PUT/DELETE) with headers + body. Whitelist against internal IPs.
json_tool / regex_test / datetime_tool — Helper functions for parsing, pattern matching, time calculations.
These tools allow every AI (even OpenAI/Claude/Gemini API, not just CLIs) to work directly in current project directory:
project_list_dir — Show directory contents (max 500 entries, optionally recursive).
project_read_file — Read file up to 1 MB (optional max_lines). No write permissions needed.
project_write_file — Write or append to file, max 5 MB. Directories auto-created. Requires enabled write permissions in project.
project_delete — Delete file or directory (recursive for folders). Requires enabled write permissions.
project_run_shell — Run shell command in project cwd (npm install, python -m pytest, git status, etc.). Hard timeout 90 sec (PROJECT_SHELL_TIMEOUT changeable), stdout/stderr capped at 50 KB. Requires enabled write permissions.
Write permissions toggle per project — same logic as for CLIs:
list/read still work
Cross-provider workflow: So GPT-5 can check what Claude Code just built in project, or Gemini review a Python script Claude created.
generate_image — AI image generation. Parameter provider:
openai (default) — gpt-image-1, photorealistic, possibly org verificationgemini — imagen-4.0-generate-001, artistically stronggrok — grok-imagine-image-quality, photorealistic + strong text renderingedit_image — Image-to-image based on uploaded photo. Automatically uses first image attachment of current message (attachment_index=0). JPEGs server-side converted to PNG (Pillow) before sending to OpenAI's /images/edits endpoint.
openai — gpt-image-1 edits, photorealisticgemini — gemini-2.5-flash-image (Nano Banana), creativegrok — grok-imagine-image-quality edits, base64 data URI as inputgenerate_video — Video generation. Parameter provider:
gemini (default) — Google Veo 3, 4-8 sec, ca. 1-3 min wait timegrok — grok-imagine-video, 5-15 sec, ~30 sec wait timeOpenAI and Anthropic have no public video API. Sora only available in ChatGPT, not via API.
Three storage locations in parallel:
/data/media/<user_id>/<YYYY-MM-DD>/<uuid>.png # Original storage
/data/uploads/... # Provider output files
<project>/outputs/<YYYY-MM-DD>/<original_name> # If chat has project
Each generated file becomes a ChatOutput DB row — persists after tab switch and browser restart, visible in chat history with inline preview (images: <img>, videos: <video controls>).
If chat is assigned a project:
All outputs automatically copied to project directory (<project>/outputs/<date>/). On name conflicts, counter appended (image.png → image (1).png).
Project copy is completely independent from DB: delete chat, delete ChatOutput, delete original in /data/media/ — all don't affect project copy. Only deleting project itself (or manually via file browser) removes it.
Copy retroactively: Chat header has "→ Project" button (appears only if project assigned). Copies all previous chat outputs to project in one go — useful for outputs created BEFORE project assignment.
---
automatically (if skill contains search_knowledge_base)
Supported formats: PDF, DOCX, XLSX, CSV, TXT, MD, HTML, JSON, PPTX.
Indexing: runs as background worker. Status in document listing (pending → processing → ready).
Embedding model: Default nomic-embed-text-v1.5 (768-dim, ONNX, in-process via fastembed — no separate container). Changeable in admin area under "Embed Models" (triggers auto-reembed of all documents).
---
Projects are persistent work directories per user under /data/projects/<user_id>/<slug>/. Activated via project pill in chat, AI uses this directory as cwd for Claude Code, Codex, Gemini CLI and for project_* tools (every provider).
Functions per project:
- Images (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 tall) - Text/code (50+ extensions — py/js/ts/json/md/csv/sql/yaml etc.): <pre> - Office/archive/binary: info box with download button
node_modules, .git, .venv, dist, build, __pycache__ etc.) - Default: hidden files excluded - ?include_hidden=true for backups incl. .env
can only read: - 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 → clear error message
Outputs subfolder: <project>/outputs/<date>/ contains all images/videos/files generated by chat in skill mode. Auto-created on first fill, can also be filled retroactively via button in chat header for existing outputs.
---
For SSH access to NAS directly from browser. Login with NAS user SSH credentials.
Configuration: Admin → Web Shell → set SSH host, port and default user. NAS-specific SSH port (e.g. 50199 instead of 22) supported.
---
While Claude Code, Codex or Gemini CLI are actively working, user sees live what CLI is doing:
● 📖 Reading src/auth.ts
✏️ Editing schema.prisma
🔧 Running `npm install`
✅ Command complete
Works in all skill and classic modes. Box appears automatically when job runs, disappears after done. Current action highlighted with pulsing dot.
---
If provider creates file in container and mentions path in response, automatically a download button appears under assistant bubble.
Detection via:
{{download:/tmp/foo.html}} or[[download:/tmp/foo.html]]
allowed file
Allowed source directories: /tmp/, /var/tmp/, /data/.claude_home/, /data/outputs/, /home/, /data/media/
System directories (/etc/, /usr/, /proc/, /root/, /var/log/) ignored.
Limits: 50 MB per file, max 10 files per response, ~50 file extensions on whitelist.
---
Since May 2026, KnowSora supports speech-to-text (STT) and text-to-speech (TTS) with three selectable engines.
| Engine | STT | TTS | Cost | Latency | Requirement | |--------|-----|-----|------|---------|-------------| | Browser (default) | Web Speech API | Web Speech API | free | <500ms | Chrome/Safari/Edge | | OpenAI | Whisper-1 | TTS-1 (MP3 streaming) | ~$0.006/min STT, ~$0.015/1k chars TTS | 1-2s | OpenAI provider with API key | | Gemini | gemini-2.5-flash | gemini-3.1-flash-tts-preview | free tier | 3-8s | Gemini provider with API key |
Browser engine is default choice and works best on iPhone/iPad with Apple voices. Limited on Linux/Firefox — switch to OpenAI or Gemini there.
Voice is always built in — no backend config needed. Microphone icon appears in chat input line. Voice engine + voice + language configurable per browser profile in voice settings popover (gear/⋮ menu).
Important: Browsers only allow microphone access via HTTPS or localhost. With self-hosted reverse proxy, definitely set up Let's Encrypt (see "Reverse Proxy" section), otherwise voice input won't work.
KnowSora has built-in dictionary auto-pronouncing ~50 tech abbreviations correctly:
and plays sequentially)
first speaker tap per tab must be manual
---
Since May 2026, search_knowledge_base uses hybrid retrieval instead of pure vector search. No config needed — always active.
Each search runs in parallel through two engines:
content, even synonyms and paraphrases
proper names, IDs, codes
Both ranking lists merged via reciprocal rank fusion (RRF) to top list. Tokenization: lowercase, German + English stopwords removed, min length 2 chars.
BM25 index held in memory per KB filter and auto-invalidated on:
First search call after cache invalidation rebuilds index (<100ms for 10k chunks).
Additionally filename added as header to embed text: [Source: filename.pdf]\n\n<chunk>. Terms appearing only in filename get embedded and findable via vector search too.
Stored chunk text remains original — users don't see prefix in search results.
Important: Documents uploaded before May 2026 don't have filename prefix. Via KB edit → "🔄 Re-index N existing documents" all docs in KB are reprocessed with current settings.
---
Optionally enabled per KB. Based on Anthropic method anthropic.com/news/contextual-retrieval.
On indexing, per chunk an LLM generates 1-2-sentence context from entire document and prepended to chunk — but only for embedding. Stored chunk stays original.
Example:
Chunk: "The answer was 5.2M EUR in Q3."
Embed input (with contextual): "This chunk is from Q3-2024 report of ACME GmbH and describes quarterly revenue. The answer was 5.2M EUR in Q3."
Result: hit relevance 30-50% better for questions like "How high was ACME revenue Q3?".
Open KB → Edit → "🧠 Contextual Retrieval (smart chunking)" enable → choose LLM provider → save.
Provider selection per KB:
Preise