README.md gives the precise, reproducible install path (tested the two scripts against the live instance - both idempotent, correctly detect already-registered credentials/models). BEDIENUNGSANLEITUNG.md covers daily usage: notebooks/sources, the three chat context modes (and why "nur Erkenntnisse" needs a transformation run first), podcasts, voice cloning, and troubleshooting for the issues actually hit during setup (num_ctx truncation, embedding GPU contention, ufw). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
137 lines
5.4 KiB
Bash
Executable file
137 lines
5.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Registriert Ollama + OpenRouter + lokale TTS/STT-Wrapper als AI-Provider in
|
|
# Open Notebook und setzt sinnvolle Standardmodelle. Für einen frischen Stack
|
|
# gedacht (siehe README.md) — prüft vor dem Anlegen jeweils, ob Credential/
|
|
# Modell mit demselben Namen schon existiert, ist also im Wesentlichen
|
|
# wiederholbar, aber nicht für abweichende Konfigurationen gedacht.
|
|
set -euo pipefail
|
|
|
|
API="http://127.0.0.1:5055/api"
|
|
|
|
echo "Warte auf Open Notebook API..."
|
|
until curl -sf "${API}/models/providers" >/dev/null 2>&1; do sleep 2; done
|
|
|
|
# --- Hilfsfunktionen -------------------------------------------------------
|
|
|
|
credential_id_by_name() {
|
|
curl -s "${API}/credentials" | python3 -c "
|
|
import json, sys
|
|
name = sys.argv[1]
|
|
for c in json.load(sys.stdin):
|
|
if c['name'] == name:
|
|
print(c['id']); break
|
|
" "$1"
|
|
}
|
|
|
|
model_id_by_name() {
|
|
curl -s "${API}/models" | python3 -c "
|
|
import json, sys
|
|
name = sys.argv[1]
|
|
for m in json.load(sys.stdin):
|
|
if m['name'] == name:
|
|
print(m['id']); break
|
|
" "$1"
|
|
}
|
|
|
|
ensure_credential() {
|
|
# ensure_credential <name> <json-payload>
|
|
local name="$1" payload="$2" id
|
|
id=$(credential_id_by_name "$name")
|
|
if [ -n "$id" ]; then
|
|
echo "Credential '$name' existiert bereits ($id)" >&2
|
|
echo "$id"
|
|
return
|
|
fi
|
|
id=$(curl -s -X POST "${API}/credentials" -H "Content-Type: application/json" -d "$payload" \
|
|
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
|
echo "Credential '$name' angelegt ($id)" >&2
|
|
echo "$id"
|
|
}
|
|
|
|
ensure_model() {
|
|
# ensure_model <name> <provider> <type> [credential_id]
|
|
local name="$1" provider="$2" type="$3" cred="${4:-}" id
|
|
id=$(model_id_by_name "$name")
|
|
if [ -n "$id" ]; then
|
|
echo "Modell '$name' existiert bereits ($id)" >&2
|
|
echo "$id"
|
|
return
|
|
fi
|
|
local cred_json="null"
|
|
[ -n "$cred" ] && cred_json="\"$cred\""
|
|
id=$(curl -s -X POST "${API}/models" -H "Content-Type: application/json" \
|
|
-d "{\"name\": \"$name\", \"provider\": \"$provider\", \"type\": \"$type\", \"credential\": ${cred_json}}" \
|
|
| python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
|
|
echo "Modell '$name' ($type) angelegt ($id)" >&2
|
|
echo "$id"
|
|
}
|
|
|
|
# --- 1. OpenRouter: API-Key aus Environment in die DB migrieren -----------
|
|
|
|
echo "== OpenRouter =="
|
|
curl -s -X POST "${API}/credentials/migrate-from-env" >/dev/null
|
|
echo "OPENROUTER_API_KEY aus Environment migriert (falls gesetzt)"
|
|
|
|
# --- 2. Ollama-Credential (Chat/Embedding), num_ctx=98304 -----------------
|
|
# 98304 ist der größte Kontext, der bei qwen3.5:27b auf dieser Hardware noch
|
|
# vollständig auf einer GPU bleibt (100% GPU laut `ollama ps`) — 131072
|
|
# spillt auf die CPU und macht Antworten 5-6x langsamer. Ohne num_ctx
|
|
# begrenzt esperanto Ollama-Chat-Aufrufe fest auf 8192 Tokens.
|
|
echo "== Ollama (Chat + Embedding) =="
|
|
OLLAMA_CRED=$(ensure_credential "Ollama (local)" '{
|
|
"name": "Ollama (local)",
|
|
"provider": "ollama",
|
|
"modalities": ["language", "embedding"],
|
|
"base_url": "http://host.docker.internal:11434",
|
|
"num_ctx": 98304
|
|
}')
|
|
|
|
QWEN_CHAT=$(ensure_model "qwen3.5:27b" "ollama" "language" "$OLLAMA_CRED")
|
|
QWEN_CODER=$(ensure_model "qwen3-coder-30b-128k:latest" "ollama" "language" "$OLLAMA_CRED")
|
|
NOMIC_EMBED=$(ensure_model "nomic-embed-text" "ollama" "embedding" "$OLLAMA_CRED")
|
|
|
|
# --- 3. OpenRouter-Sprachmodelle (kuratiert, nicht alle ~400) --------------
|
|
echo "== OpenRouter Sprachmodelle =="
|
|
CLAUDE_SONNET=$(ensure_model "anthropic/claude-sonnet-5" "openrouter" "language")
|
|
QWEN_MAX=$(ensure_model "qwen/qwen3-max" "openrouter" "language")
|
|
GEMINI_FLASH=$(ensure_model "google/gemini-3.5-flash" "openrouter" "language")
|
|
|
|
# --- 4. Lokale TTS/STT-Wrapper (siehe services/) --------------------------
|
|
echo "== Lokales TTS (Chatterbox) =="
|
|
TTS_CRED=$(ensure_credential "Chatterbox TTS (local)" '{
|
|
"name": "Chatterbox TTS (local)",
|
|
"provider": "openai_compatible",
|
|
"modalities": ["text_to_speech"],
|
|
"base_url": "http://host.docker.internal:8901",
|
|
"api_key": "not-required"
|
|
}')
|
|
TTS_MODEL=$(ensure_model "chatterbox-tts" "openai_compatible" "text_to_speech" "$TTS_CRED")
|
|
|
|
echo "== Lokales STT (faster-whisper) =="
|
|
STT_CRED=$(ensure_credential "faster-whisper STT (local)" '{
|
|
"name": "faster-whisper STT (local)",
|
|
"provider": "openai_compatible",
|
|
"modalities": ["speech_to_text"],
|
|
"base_url": "http://host.docker.internal:8902",
|
|
"api_key": "not-required"
|
|
}')
|
|
STT_MODEL=$(ensure_model "faster-whisper-large-v3" "openai_compatible" "speech_to_text" "$STT_CRED")
|
|
|
|
# --- 5. Standardmodelle setzen ---------------------------------------------
|
|
# Alles lokal/kostenlos außer Tools-Modell optional auf ein OpenRouter-Modell
|
|
# umstellbar (siehe BEDIENUNGSANLEITUNG.md, Abschnitt "Modelle wechseln").
|
|
echo "== Standardmodelle setzen =="
|
|
curl -s -X PUT "${API}/models/defaults" -H "Content-Type: application/json" -d "{
|
|
\"default_chat_model\": \"$QWEN_CHAT\",
|
|
\"default_transformation_model\": \"$QWEN_CHAT\",
|
|
\"large_context_model\": \"$QWEN_CHAT\",
|
|
\"default_embedding_model\": \"$NOMIC_EMBED\",
|
|
\"default_tools_model\": \"$QWEN_CHAT\",
|
|
\"default_text_to_speech_model\": \"$TTS_MODEL\",
|
|
\"default_speech_to_text_model\": \"$STT_MODEL\"
|
|
}" | python3 -m json.tool
|
|
|
|
echo
|
|
echo "Fertig. Registrierte, aber nicht als Standard gesetzte Zusatzmodelle:"
|
|
echo " - qwen3-coder-30b-128k:latest ($QWEN_CODER) — für reine Coding-Aufgaben"
|
|
echo " - anthropic/claude-sonnet-5 ($CLAUDE_SONNET), qwen/qwen3-max ($QWEN_MAX), google/gemini-3.5-flash ($GEMINI_FLASH) — OpenRouter-Alternativen"
|