Konfiguracja, Lokalny Start i Docker
Konfiguracja jest ładowana ze zmiennych środowiskowych w backend/config.py. Sekrety trzymaj lokalnie albo w secret variables CI/CD. Nie kopiuj wartości z jarvis-dev.env do dokumentacji, commitów ani logów.
Zmienne Środowiskowe
Flask
| Zmienna | Opis |
|---|---|
FLASK_ENV |
Środowisko Flask. |
FLASK_SECRET_KEY |
Secret key dla sesji Flask. |
DEBUG |
Flaga debug. |
Database
| Zmienna | Opis |
|---|---|
SQLALCHEMY_DATABASE_URI |
Connection string bazy danych. |
SQLALCHEMY_TRACK_MODIFICATIONS |
Flaga SQLAlchemy. |
SQLALCHEMY_ECHO |
Logowanie SQL. |
AUTO_CREATE_DB |
Gdy true, proces wykona db.create_all() przy starcie. W Docker Compose używa tego tylko jednorazowa usługa db-init; nie ustawiaj tego na true dla wieloprocesowego web. |
DB_SCHEMA |
Opcjonalny schema prefix dla baz typu Postgres. |
DB_MIGRATION_BOOTSTRAP |
Jednorazowy tryb dla istniejącej produkcyjnej bazy bez tabeli Alembic. |
PGVECTOR_ENABLED |
Flaga przygotowana pod obsługę pgvector i przyszłe embeddings. |
Redis, Sesje i Rate Limiting
| Zmienna | Opis |
|---|---|
REDIS_URL |
Główny Redis URL, domyślnie redis://redis:6379/0. |
SESSION_TYPE |
Typ sesji Flask, domyślnie redis. |
SESSION_REDIS_URL |
Redis dla server-side sessions. |
SESSION_PERMANENT |
Czy sesje są trwałe. |
PERMANENT_SESSION_LIFETIME |
Czas życia sesji w sekundach. |
SESSION_COOKIE_SAMESITE |
Atrybut SameSite cookie. |
SESSION_COOKIE_SECURE |
W produkcji za HTTPS powinno być true. |
RATELIMIT_ENABLED |
Włącza Flask-Limiter. |
RATELIMIT_STORAGE_URI |
Storage rate limitów. W Compose powinien wskazywać na Redis. |
OpenAI
| Zmienna | Opis |
|---|---|
OPENAI_API_KEY |
Klucz API OpenAI. |
Memory Service
| Zmienna | Opis |
|---|---|
MEMORY_SERVICE_ENABLED |
Włącza enqueue jobów pamięci po zapisaniu odpowiedzi chatu. |
MEMORY_CONTEXT_ENABLED |
Włącza dołączanie summary i memory items do promptu. |
MEMORY_EXTRACTOR_PROVIDER |
heuristic albo local_llm. |
MEMORY_LLM_BASE_URL |
OpenAI-compatible URL lokalnego LLM, domyślnie http://local-llm:11434/v1. |
MEMORY_LLM_API_KEY |
Dowolna wartość dla lokalnego OpenAI-compatible endpointu, domyślnie local. |
MEMORY_LLM_MODEL |
Domyślnie qwen2.5:3b-instruct. |
MEMORY_LLM_TIMEOUT_SECONDS |
Timeout extractora. |
MEMORY_MIN_CONFIDENCE |
Minimalna pewność zapisywanego memory item. |
MEMORY_SUMMARY_WORDS |
Maksymalna długość rolling summary. |
MEMORY_CONTEXT_ITEMS |
Maksymalna liczba memory items do promptu. |
Przykład lokalnego extractora:
MEMORY_EXTRACTOR_PROVIDER=local_llm
MEMORY_LLM_BASE_URL=http://local-llm:11434/v1
MEMORY_LLM_API_KEY=local
MEMORY_LLM_MODEL=qwen2.5:3b-instruct
MEMORY_MIN_CONFIDENCE=0.7
Jeśli lokalny LLM zwróci niepoprawny JSON albo nie odpowie, worker używa fallbacku heurystycznego.
Speaches
| Zmienna | Opis |
|---|---|
SPEECH_TTS_PROVIDER |
Aktywny backend TTS: speaches albo chatterbox. |
SPEACHES_ENABLED |
Włącza integrację z lokalnym serwisem Speaches. Domyślnie false; browserowy voice mode pozostaje fallbackiem. |
SPEACHES_BASE_URL |
OpenAI-compatible base URL Speaches, np. http://speaches:8000/v1 w Docker Compose. |
SPEACHES_STT_MODEL |
Model STT planowany dla transkrypcji audio. |
SPEACHES_STT_TIMEOUT_SECONDS |
Timeout requestu STT do Speaches oraz maksymalny czas oczekiwania na wolny slot limitera STT. |
SPEECH_STT_MAX_CONCURRENT_REQUESTS |
Maksymalna liczba równoległych transkrypcji STT w web backendzie. Domyślnie 2; na CPU 6 vCPU zwykle zaczynaj od 2. |
SPEECH_STT_DEFAULT_LANGUAGE |
Domyślny język STT przekazywany do Speaches, np. pl. |
SPEECH_STT_MAX_AUDIO_BYTES |
Maksymalny rozmiar uploadowanego audio STT. |
SPEECH_STT_PROMPT |
Prompt/kontekst dla Speaches STT, np. wake words i komendy głosowe. |
SPEACHES_TTS_MODEL |
Model TTS używany przez backendowy speech_service.py. |
SPEACHES_TTS_VOICE |
Domyślny głos TTS. |
SPEACHES_TTS_CACHE_ENABLED |
Włącza cache odpowiedzi audio w Redis. |
SPEACHES_TTS_CACHE_TTL_SECONDS |
TTL cache TTS. |
SPEACHES_TTS_CACHE_MAX_BYTES |
Maksymalny rozmiar cache'owanego audio. |
SPEACHES_TTS_MODEL_LANGUAGES |
Języki, dla których bootstrap speaches-models pobierze modele z backend/data/speaches-voices.json, np. en-us,en-gb,pl,de,es. |
Backend czyta data[].id jako dostępne modele TTS oraz data[].voices[] jako głosy. UI grupuje głosy po language; po wyborze głosu automatycznie ustawia powiązany model TTS z pola model_id.
Chatterbox TTS
Chatterbox TTS Server może działać jako alternatywny provider server-side TTS. W Compose jest dostępny jako opcjonalny profil chatterbox, więc nie startuje przy zwykłym docker compose up.
| Zmienna | Opis |
|---|---|
CHATTERBOX_TTS_ENABLED |
Włącza provider Chatterbox. |
CHATTERBOX_TTS_BASE_URL |
Base URL Chatterbox. W Docker Compose użyj http://chatterbox:4123; poza Compose może to być np. http://host.docker.internal:4123. |
CHATTERBOX_TTS_VOICE |
Głos przekazywany do OpenAI-compatible API. Domyślnie alloy, które w chatterbox-tts-api mapuje się na skonfigurowany sample voice. |
CHATTERBOX_TTS_TIMEOUT_SECONDS |
Timeout requestu do Chatterbox. |
Przykład:
SPEECH_TTS_PROVIDER=chatterbox
CHATTERBOX_TTS_ENABLED=true
CHATTERBOX_TTS_BASE_URL=http://chatterbox:4123
CHATTERBOX_TTS_VOICE=alloy
Aktualna integracja używa OpenAI-compatible endpointu /v1/audio/speech z travisvn/chatterbox-tts-api. Ten serwis ma także endpoint /v1/audio/speech/stream, więc prawdziwe streaming audio może być kolejnym krokiem po potwierdzeniu jakości i stabilności providera.
Discord
| Zmienna | Opis |
|---|---|
DISCORD_CLIENT_ID |
Discord OAuth client ID. |
DISCORD_CLIENT_SECRET |
Discord OAuth client secret. |
DISCORD_REDIRECT_URI |
Redirect URI dla OAuth callback. |
DISCORD_INVITE_URL |
Link invite Discord. |
DISCORD_BUG_REPORT_WEBHOOK |
Webhook do powiadomień o bug reportach. |
Azure Boards
| Zmienna | Opis |
|---|---|
AZURE_ORGANIZATION_URL |
URL organizacji Azure DevOps. |
AZURE_PERSONAL_ACCESS_TOKEN |
PAT do Azure DevOps. |
AZURE_PROJECT |
Nazwa projektu Azure DevOps. |
reCAPTCHA
| Zmienna | Opis |
|---|---|
CAPTCHA_SITE_KEY |
Publiczny site key. |
CAPTCHA_SECRET_KEY |
Secret key. |
CAPTCHA_VERIFY_URL |
Endpoint weryfikacji reCAPTCHA, np. https://www.google.com/recaptcha/api/siteverify. |
Observability
| Zmienna | Opis |
|---|---|
OTEL_ENDPOINT |
Bazowy endpoint OTLP collector, np. http://otel-collector:4318. |
OTEL_SERVICE_NAME |
Nazwa serwisu raportowana do OpenTelemetry; domyślnie wartość POD_NAME. |
OTEL_TRACES_ENABLED |
Włącza eksport traces przez OTLP, domyślnie true. |
OTEL_METRICS_ENABLED |
Włącza eksport metrics przez OTLP, domyślnie true. |
OTEL_LOGS_ENABLED |
Włącza eksport logs przez OTLP, domyślnie true. |
POD_NAME |
Nazwa serwisu/poda raportowana do OpenTelemetry. |
STT raportuje metryki speech.stt.* przez OpenTelemetry, jeśli OTEL_METRICS_ENABLED=true i ustawiono endpoint OTLP. Najważniejsze serie to:
speech.stt.requests- licznik requestów wedługsource,model,languageistatus,speech.stt.queue_wait_ms- czas oczekiwania na limiter STT,speech.stt.elapsed_ms- czas wywołania Speaches,speech.stt.audio_bytesispeech.stt.audio_duration_ms- rozmiar i długość audio,speech.stt.transcript_chars- długość transkryptu.
source=web oznacza web voice mode, a source=discord oznacza request z Discord bota przez internal API.
Uruchomienie Lokalne
1. Utworzenie środowiska
Windows PowerShell:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt
Linux/macOS:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -r requirements-dev.txt
2. Minimalne zmienne dla startu bez Compose
PowerShell, przykład SQLite:
$env:FLASK_APP = "app.py"
$env:FLASK_SECRET_KEY = "dev-secret"
$env:SQLALCHEMY_DATABASE_URI = "sqlite:///dev.db"
$env:SQLALCHEMY_TRACK_MODIFICATIONS = "False"
$env:AUTO_CREATE_DB = "true"
$env:OPENAI_API_KEY = "test"
$env:OTEL_ENDPOINT = ""
$env:SESSION_TYPE = "filesystem"
$env:RATELIMIT_STORAGE_URI = "memory://"
3. Start aplikacji
python -m flask run --host=0.0.0.0 --port=8000
Po starcie:
- aplikacja:
http://localhost:8000/, - healthcheck:
http://localhost:8000/livenez.
Docker
Dockerfile jest multi-stage:
builder- instaluje zależności runtime do/env,runtime- obraz aplikacyjny,tester- opcjonalny stage z zależnościami developerskimi,production- finalny domyślny obraz produkcyjny.
Build Produkcyjnego Obrazu
docker build -t voice.assistant.web:local .
Uruchomienie Produkcyjnego Obrazu
docker run --rm -p 8000:8000 \
-e SQLALCHEMY_DATABASE_URI="sqlite:////tmp/test.db" \
-e SQLALCHEMY_TRACK_MODIFICATIONS="False" \
-e FLASK_SECRET_KEY="dev-secret" \
-e OPENAI_API_KEY="test" \
-e OTEL_ENDPOINT="" \
voice.assistant.web:local
Build Stage Testowego
docker build --target tester -t voice.assistant.web:tester .
Stage tester jest przeznaczony wyłącznie do narzędzi developerskich. Finalny obraz produkcyjny nie powinien zawierać pytest, flake8, mypy, black ani pre-commit.
Docker Compose
docker-compose.yml uruchamia:
db- Postgres z pgvector,db-init- jednorazowe utworzenie tabel w świeżej lokalnej bazie,redis- sesje, rate limits, TTS cache i kolejka pamięci,web- aplikacja Flask/Gunicorn,memory-worker- worker pamięci z tego samego obrazu aplikacji,local-llm- Ollama,local-llm-models- bootstrap modeluqwen2.5:3b-instruct,speaches- lokalny serwis speech,speaches-models- bootstrap modeli TTS,chatterbox- opcjonalny lokalny serwis TTS pod profilemchatterbox,mockserver- lokalny mock reCAPTCHA.
Compose domyślnie korzysta z jarvis-dev.env. W CI template ustawia JARVIS_ENV_FILE=.ado/env/compose-integration.env, żeby testy nie wymagały lokalnego pliku ani sekretów.
Start:
docker compose up --build
Po uruchomieniu:
- aplikacja:
http://localhost:8000/, - healthcheck:
http://localhost:8000/livenez, - MockServer:
http://localhost:1080/, - Postgres:
localhost:5432, - Speaches UI/API hostowo:
http://localhost:8001/, - Chatterbox API hostowo po starcie profilu:
http://localhost:4123/, - lokalny LLM hostowo:
http://localhost:11434/.
Chatterbox TTS
Chatterbox jest zdefiniowany jako opcjonalny serwis Compose. Lokalny wrapper docker/chatterbox/Dockerfile.cpu klonuje upstreamowe repozytorium travisvn/chatterbox-tts-api podczas builda i instaluje wariant CPU. Pierwszy build może potrwać, bo Docker pobiera repozytorium, zależności i modele.
Start samego serwisu:
docker compose --profile chatterbox up --build chatterbox
Start całego stacka razem z Chatterbox:
docker compose --profile chatterbox up --build
Aby backend używał Chatterbox, ustaw w pliku wskazanym przez JARVIS_ENV_FILE:
SPEECH_TTS_PROVIDER=chatterbox
CHATTERBOX_TTS_ENABLED=true
CHATTERBOX_TTS_BASE_URL=http://chatterbox:4123
Modele, głosy i dane long-text jobs są trzymane w nazwanych wolumenach chatterbox_models, chatterbox_voices i chatterbox_longtext_data. Serwis wystawia też dokumentację API pod http://localhost:4123/docs.
Modele Lokalnego LLM
local-llm-models pobiera model przez API Ollamy. Jeśli trzeba wymusić ponowny bootstrap:
docker compose run --rm local-llm-models
Modele Speaches
Speaches nie pobiera modelu TTS automatycznie tylko dlatego, że aplikacja ma go wpisanego w konfiguracji. Bootstrap modeli:
docker compose run --rm speaches-models
Usługa speaches-models czeka na API Speaches, pobiera modele STT z katalogu backend/data/speaches-stt-models.txt używanego też przez panel web jako AVAILABLE_SPEACHES_STT_MODELS, czyta katalog backend/data/speaches-voices.json, wybiera modele TTS mające głosy w językach z SPEACHES_TTS_MODEL_LANGUAGES i uruchamia uvx speaches-cli model download dla każdego z nich. Modele są zapisywane w wolumenie speaches_cache.
Awaryjnie można nadal wymusić konkretną listę modeli przez SPEACHES_STT_MODELS lub SPEACHES_TTS_MODELS, rozdzieloną przecinkami lub średnikami. SPEACHES_STT_MODELS ma pierwszeństwo przed listą panelu dla STT, a SPEACHES_TTS_MODELS ma pierwszeństwo przed filtrem języków dla TTS.
Migracje
Migracje bazy danych są uruchamiane osobną usługą pod profilem migrations:
docker compose --profile migrations run --rm migrate
Pierwsze wdrożenie na istniejącej produkcyjnej bazie bez tabeli alembic_version powinno użyć jednorazowo:
DB_MIGRATION_BOOTSTRAP=true docker compose --profile migrations run --rm migrate
Po bootstrapie kolejne deploye powinny uruchamiać tylko standardowe flask db upgrade przez usługę migrate, bez DB_MIGRATION_BOOTSTRAP=true.