# ============================================================================= # Transcription Connector Configuration # ============================================================================= # # Speakr supports multiple transcription providers through a connector-based # architecture. This file documents all available configuration options. # # Quick Start (Simplified): # 1. For OpenAI with diarization: Set TRANSCRIPTION_MODEL=gpt-4o-transcribe-diarize # 2. For self-hosted ASR: Set ASR_BASE_URL=http://your-asr:9000 # 3. For legacy Whisper: Set TRANSCRIPTION_API_KEY and optionally TRANSCRIPTION_MODEL # # Auto-Detection Priority: # 1. TRANSCRIPTION_CONNECTOR - explicit connector name (if you need full control) # 2. ASR_BASE_URL - if set, uses ASR endpoint connector # 3. TRANSCRIPTION_MODEL contains 'gpt-4o' - uses OpenAI Transcribe connector # 4. Default - uses OpenAI Whisper connector with TRANSCRIPTION_MODEL or whisper-1 # ============================================================================= # TEXT GENERATION MODEL (REQUIRED for summaries, titles, chat) # ============================================================================= # Speakr uses a text/LLM model for generating summaries, titles, and chat. # This is separate from the transcription model (STT). # # You can use OpenRouter (recommended - access to many models) or direct OpenAI API. # OpenRouter example (recommended - supports many models): TEXT_MODEL_BASE_URL=https://openrouter.ai/api/v1 TEXT_MODEL_API_KEY=your_openrouter_api_key TEXT_MODEL_NAME=openai/gpt-4o-mini # OpenAI direct example: # TEXT_MODEL_BASE_URL=https://api.openai.com/v1 # TEXT_MODEL_API_KEY=sk-your_openai_api_key # TEXT_MODEL_NAME=gpt-4o-mini # --- Prefix-Cache-Friendly Prompts (Optional, default: false) --- # Opt-in. Only useful on self-hosted text backends with automatic prefix # caching (vLLM APC, llama.cpp/Ollama, SGLang, TGI). When true, the title and # summary calls share a byte-identical system message + transcript-first prefix # so the backend prefills the transcript once and reuses it on the second call. # Leave false for hosted APIs (OpenRouter/OpenAI) or to keep upstream prompts. # NOTE: the caching must also be enabled on the server itself, e.g. start vLLM # with --enable-prefix-caching (add --enable-prompt-tokens-details to see the # cache hits in the admin Token Usage dashboard). See # docs/admin-guide/model-configuration.md for details. # PREFIX_CACHE_OPTIMIZED_PROMPTS=false # --- GPT-5 Specific Settings (only used with OpenAI API and GPT-5 models) --- # By default GPT-5 parameter handling (reasoning_effort/verbosity, # max_completion_tokens) activates only for GPT-5 model names on the official # OpenAI API. Set this to force it on for GPT-5 models served through Azure AI # Foundry or other gateways the URL check cannot detect: # GPT5_FORCE_MODE=true # Same, for a separately configured chat model (not inherited from the above): # CHAT_GPT5_FORCE_MODE=true # # Reasoning effort: minimal, low, medium, high (default: medium) GPT5_REASONING_EFFORT=medium # Verbosity: low, medium, high (default: medium) GPT5_VERBOSITY=medium # --- Chat Model Configuration (Optional) --- # Configure a separate model for real-time chat interactions. # If not set, chat will use the TEXT_MODEL_* settings above. # CHAT_MODEL_API_KEY=your_chat_api_key # CHAT_MODEL_BASE_URL=https://openrouter.ai/api/v1 # CHAT_MODEL_NAME=openai/gpt-4o # ============================================================================= # CONNECTOR SELECTION (Auto-detected if not set) # ============================================================================= # Options: openai_whisper, openai_transcribe, asr_endpoint, mistral, vibevoice, funasr, mossland, assemblyai, openasr # Leave empty to auto-detect based on other settings # TRANSCRIPTION_CONNECTOR= # Feature flag to enable/disable new connector architecture (default: true) # Set to false to use legacy code path for troubleshooting # USE_NEW_TRANSCRIPTION_ARCHITECTURE=true # ============================================================================= # OPENAI CONFIGURATION (Required for openai_whisper and openai_transcribe) # ============================================================================= TRANSCRIPTION_API_KEY=your_openai_api_key TRANSCRIPTION_BASE_URL=https://api.openai.com/v1 # Model Selection - determines which connector is used: # # whisper-1 - Legacy Whisper model, no diarization, $0.006/min # Supports: srt, vtt, json, verbose_json output formats # # gpt-4o-transcribe - High quality transcription, no diarization, $0.006/min # Better accuracy than whisper-1, accepts prompts # # gpt-4o-mini-transcribe - Cost-effective option, no diarization, $0.003/min # Good for high-volume, budget-conscious use # # gpt-4o-transcribe-diarize - Speaker diarization!, $0.006/min # Identifies speakers as A, B, C, D... # Requires chunking_strategy for audio >30s # TRANSCRIPTION_MODEL=gpt-4o-transcribe-diarize # Legacy Whisper model name (used when TRANSCRIPTION_MODEL is not set) # WHISPER_MODEL=whisper-1 # Comma-separated list of transcription model names offered in the per-upload # model dropdown. Leave empty to hide the dropdown and always use the model # configured above. Example: whisper-1,gpt-4o-transcribe,gpt-4o-transcribe-diarize # TRANSCRIPTION_MODELS_AVAILABLE= # ============================================================================= # ASR ENDPOINT CONFIGURATION (For self-hosted whisper services) # ============================================================================= # Note: USE_ASR_ENDPOINT is deprecated. Just set ASR_BASE_URL instead. # The connector will auto-detect ASR mode when ASR_BASE_URL is set. # USE_ASR_ENDPOINT=true # Deprecated - kept for backwards compatibility # Base URL of your ASR service (required if USE_ASR_ENDPOINT=true) # Supports: whisper-asr-webservice, WhisperX, and compatible services # ASR_BASE_URL=http://whisper-asr:9000 # Request timeout in seconds (default: 1800 = 30 minutes) # Increase for very long audio files # ASR_TIMEOUT=1800 # Enable speaker diarization (default: true) # ASR_DIARIZE=true # Speaker count hints (optional, helps with diarization accuracy) # ASR_MIN_SPEAKERS=1 # ASR_MAX_SPEAKERS=5 # Return speaker embeddings for speaker identification (WhisperX only) # Enables automatic speaker matching across recordings # ASR_RETURN_SPEAKER_EMBEDDINGS=false # ============================================================================= # MISTRAL / VOXTRAL CONFIGURATION # ============================================================================= # Mistral's Voxtral model provides cloud-based transcription with built-in # speaker diarization and language detection. Requires a Mistral API key. # # TRANSCRIPTION_CONNECTOR=mistral # TRANSCRIPTION_API_KEY=your_mistral_api_key # TRANSCRIPTION_MODEL=voxtral-mini-latest # # To use a custom Mistral-compatible endpoint: # TRANSCRIPTION_BASE_URL=https://api.mistral.ai # # Enable app-level chunking for the Mistral connector (default: false). # MISTRAL_ENABLE_CHUNKING=false # ============================================================================= # VIBEVOICE CONFIGURATION (Self-hosted via vLLM) # ============================================================================= # Microsoft's VibeVoice ASR model provides transcription with speaker # diarization, timestamps, and language detection for 50+ languages. It runs # on your own hardware via vLLM and handles up to 60 minutes per request. # Longer files are automatically chunked by the app. # # Requirements: # - vLLM server with the VibeVoice model loaded # - GPU(s) with enough VRAM (bf16 needs ~18GB, fits on 2x consumer GPUs) # # TRANSCRIPTION_CONNECTOR=vibevoice # TRANSCRIPTION_BASE_URL=http://your-vllm-server:8000 # TRANSCRIPTION_MODEL=vibevoice # # If your vLLM server requires authentication: # TRANSCRIPTION_API_KEY=your_api_key # ============================================================================= # FUNASR CONFIGURATION (Alibaba Cloud) # ============================================================================= # Alibaba Cloud FunASR (DAMO Academy speech recognition) provides high-accuracy # transcription with speaker diarization at very low cost. Requires S3-compatible # storage for passing pre-signed audio URLs to the API. # # Docs: https://help.aliyun.com/zh/model-studio/fun-asr-recorded-speech-recognition-restful-api # # TRANSCRIPTION_CONNECTOR=funasr # ASR_BASE_URL=https://dashscope.aliyuncs.com/api/v1 # ASR_API_KEY=sk-your-aliyun-key # ASR_MODEL=paraformer-v2 # 'paraformer-v2' (low cost) or 'fun-asr' # ASR_TIMEOUT=1800 # Transcription timeout in seconds (default 30min) # ASR_DIARIZE=false # Speaker diarization (default false) # ASR_LANGUAGE_HINTS=zh,en # Language hints, comma-separated (default zh,en) # # --- S3 Storage (Required for FunASR) --- # FunASR requires audio files to be available through pre-signed S3 URLs. # S3_ENDPOINT_URL is the endpoint Speakr uses for storage and for signed URLs by # default. Speakr creates signed URLs per transcription task and does not persist # them in the database. # S3_BUCKET_NAME=your-bucket # S3_ENDPOINT_URL=https://oss-cn-shanghai.aliyuncs.com # Optional: use an Aliyun internal endpoint only for URLs sent to DashScope. # The URL is signed directly for this host, so do not use a bucket-qualified URL. # S3_INTRANET_ENDPOINT_URL=https://oss-cn-shanghai-internal.aliyuncs.com # S3_REGION=cn-shanghai # S3_ACCESS_KEY_ID=your-access-key-id # S3_SECRET_ACCESS_KEY=your-secret-access-key # --- FunASR-specific parameters (FUNASR_* prefix) --- # FUNASR_POLL_INTERVAL=10 # Seconds between status polls (default 10s) # FUNASR_DISFLUENCY_REMOVAL=false # Filter filler words (default false) # FUNASR_TIMESTAMP_ALIGNMENT=false # Timestamp alignment (default false) # FUNASR_SPEAKER_COUNT=2 # Speaker count hint, 2-100 # FUNASR_CHANNEL_ID=0 # Audio channel indices, comma-separated # FUNASR_VOCABULARY_ID= # Hot-word vocabulary ID # ============================================================================= # MOSI / MOSSLAND MOSS CONFIGURATION (Hosted Cloud API) # ============================================================================= # MOSS provides single-speaker transcription and multi-speaker diarization. # Diarized audio stays in one provider task so speaker identities remain stable; # Speakr app-level chunking is disabled for this connector. The connector uses # SSE first, then resumes a stalled SSE task through the documented task API. # It sends one fixed 131072-token output ceiling for long-form transcription. # # Privacy: recordings are uploaded to the third-party MOSI/Mossland service at # api.mosi.cn. They are not processed entirely on your self-hosted Speakr host. # Create an API key at https://studio.mosi.cn/app/api-keys. # # TRANSCRIPTION_CONNECTOR=mossland # TRANSCRIPTION_API_KEY=your_mosi_api_key # TRANSCRIPTION_MODEL=moss-transcribe-diarize # Available transcription models are read on demand from GET /v1/models; the # two documented model IDs remain available if model discovery is offline. # # Optional API-compatible proxy or alternate endpoint: # TRANSCRIPTION_BASE_URL=https://api.mosi.cn # ============================================================================= # ASSEMBLYAI CONFIGURATION (Cloud) # ============================================================================= # AssemblyAI is a cloud transcription provider with strong speaker diarization # on long, multi-speaker recordings. It is NOT OpenAI-compatible (it uses its # own async upload/poll API), so it has its own connector. It ingests files up # to 10 hours in a single job, so the app does not chunk for it. # # New accounts get free credits and no credit card is required to get a key # (sign up at https://www.assemblyai.com and create an API key). # # TRANSCRIPTION_CONNECTOR=assemblyai # TRANSCRIPTION_API_KEY=your_assemblyai_api_key # # The endpoint is fixed at https://api.assemblyai.com, so the shared # TRANSCRIPTION_BASE_URL is intentionally ignored for this connector (a leftover # value from another connector won't misroute uploads). Set ASSEMBLYAI_BASE_URL # only if you front the API with a proxy. # ASSEMBLYAI_BASE_URL= # # Optional: pin a speech model (omit to use your account default). Uses a # dedicated var, NOT the shared TRANSCRIPTION_MODEL (a leftover model name from # another connector would be rejected by AssemblyAI). Comma-separated values # become an ordered fallback list (AssemblyAI's speech_models). # ASSEMBLYAI_SPEECH_MODEL=universal-3-pro,universal-2 # # Diarization, language, and hotwords come from each user's settings (or tag / # folder defaults). Hotwords are sent as AssemblyAI word_boost; min/max speaker # counts map to speaker_options. Times are returned in milliseconds and stored # as seconds. # ============================================================================= # CHUNKING CONFIGURATION (For large files) # ============================================================================= # Chunking is now connector-aware with this priority: # 1. Connector handles internally (openai_transcribe, asr_endpoint, mistral) → No app chunking # 2. ENABLE_CHUNKING=false → Disable chunking (only affects openai_whisper) # 3. CHUNK_LIMIT set → Use your settings # 4. Connector defaults → Use connector's recommended limits # 5. App default → 20MB size-based # # For openai_transcribe/asr_endpoint/mistral: These settings are IGNORED (connector handles it) # For openai_whisper: These settings control chunking behavior # For vibevoice: App chunks files >58 min into ~50 min pieces automatically # For mossland: App chunking is disabled to preserve speaker identity across long audio # ENABLE_CHUNKING=false # Uncomment to disable chunking for openai_whisper # Chunk limit - supports size (20MB) or duration (600s, 10m) CHUNK_LIMIT=20MB # Overlap between chunks in seconds (helps with transcription accuracy at boundaries) CHUNK_OVERLAP_SECONDS=3 # ============================================================================= # EXAMPLE CONFIGURATIONS (Simplified) # ============================================================================= # # --- OpenAI with Speaker Diarization (Recommended) --- # Just two environment variables needed: # TRANSCRIPTION_API_KEY=sk-xxx # TRANSCRIPTION_MODEL=gpt-4o-transcribe-diarize # # --- Self-hosted WhisperX (Best for privacy) --- # Just one environment variable needed (auto-detects ASR mode): # ASR_BASE_URL=http://whisper-asr:9000 # Optional: # ASR_DIARIZE=true # ASR_RETURN_SPEAKER_EMBEDDINGS=true # # --- OpenAI Whisper (Legacy, no diarization) --- # TRANSCRIPTION_API_KEY=sk-xxx # TRANSCRIPTION_MODEL=whisper-1 # # --- Custom Whisper model (local or compatible endpoint) --- # TRANSCRIPTION_API_KEY=not-needed # TRANSCRIPTION_BASE_URL=http://localhost:8080/v1 # TRANSCRIPTION_MODEL=Systran/faster-distil-whisper-large-v3 # # --- Mistral Voxtral (cloud diarization) --- # TRANSCRIPTION_CONNECTOR=mistral # TRANSCRIPTION_API_KEY=your-mistral-key # TRANSCRIPTION_MODEL=voxtral-mini-latest # # --- VibeVoice ASR (self-hosted diarization) --- # TRANSCRIPTION_CONNECTOR=vibevoice # TRANSCRIPTION_BASE_URL=http://your-vllm-server:8000 # TRANSCRIPTION_MODEL=vibevoice # # --- MOSI/Mossland MOSS (hosted diarization) --- # TRANSCRIPTION_CONNECTOR=mossland # TRANSCRIPTION_API_KEY=your_mosi_api_key # TRANSCRIPTION_MODEL=moss-transcribe-diarize # ============================================================================= # APPLICATION SETTINGS # ============================================================================= # --- Admin User (created on first run) --- ADMIN_USERNAME=admin ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=changeme # --- Registration & Access --- ALLOW_REGISTRATION=false # Comma-separated list of allowed email domains for registration. # Leave empty to allow all domains. Example: company.com,subsidiary.org REGISTRATION_ALLOWED_DOMAINS= # --- Session Security --- # Flask secret key: signs session cookies and email/password-reset tokens. It # does NOT encrypt stored data, so a lost key means a one-time re-login for # everyone, never data loss. If unset, the app auto-generates a strong key and # persists it under the instance directory (captured by a normal data-volume # backup); the old publicly-known built-in default is refused at startup. Set # this explicitly for multi-host deployments or to control key rotation: # `python -c "import secrets; print(secrets.token_hex(32))"`. # SECRET_KEY=change-me-to-a-long-random-string # Only send the session cookie over HTTPS. STRONGLY recommended (true) for any # HTTPS deployment. Default: false so plain-HTTP LAN setups keep working. # SESSION_COOKIE_SECURE=false # --- Security headers --- # The app sets X-Frame-Options, X-Content-Type-Options, Referrer-Policy, # Permissions-Policy, a Content-Security-Policy, and (over HTTPS) HSTS, so a # deployment without a hardening proxy is still protected. Set # SECURITY_HEADERS_ENABLED=false only if your proxy already sets all of these. # Override the CSP wholesale with CONTENT_SECURITY_POLICY, or tune HSTS with # HSTS_HEADER (empty disables it, e.g. if your proxy already sends HSTS). # SECURITY_HEADERS_ENABLED=true # CONTENT_SECURITY_POLICY= # HSTS_HEADER=max-age=63072000; includeSubDomains # Number of trusted reverse-proxy hops in front of the app (X-Forwarded-For/ # Proto). Default: 1 (one proxy, e.g. nginx/Traefik). Increase if you chain # additional proxies/load balancers so client IPs and HTTPS detection are read # from the correct forwarded header. # TRUSTED_PROXY_HOPS=1 # --- Token Limits --- SUMMARY_MAX_TOKENS=8000 CHAT_MAX_TOKENS=5000 # Max tokens for auto title generation (default: 5000) # TITLE_MAX_TOKENS=5000 # Max tokens for event extraction (default: 3000) # EVENT_MAX_TOKENS=3000 # --- Logging --- LOG_LEVEL="INFO" # ============================================================================= # AUDIO PROCESSING # ============================================================================= # --- Audio Compression --- # Automatically compress lossless uploads (WAV, AIFF) to save storage AUDIO_COMPRESS_UPLOADS=true # Target codec: mp3 (lossy, smallest), flac (lossless), opus (lossy, efficient) AUDIO_CODEC=mp3 # Bitrate for lossy codecs (ignored for FLAC) AUDIO_BITRATE=128k # Unsupported codecs - comma-separated list of codecs to exclude # Example: AUDIO_UNSUPPORTED_CODECS=opus,vorbis # AUDIO_UNSUPPORTED_CODECS= # ============================================================================= # OPTIONAL FEATURES # ============================================================================= # --- Help Center Link (optional) --- # Adds a link to your own help/FAQ/tutorial page in the user menu. # Label defaults to "Help Center" (localized) if not set. # HELP_CENTER_URL=https://intranet.example.com/speakr-help # HELP_CENTER_LABEL=Company FAQ # --- Inquire Mode (AI search across all recordings) --- ENABLE_INQUIRE_MODE=false # Agentic Inquire (opt-in beta). Replaces the single-shot Inquire pipeline # with a tool-using agent that can search, list and read your recordings # iteratively before answering, with live activity shown in the UI. # Requires ENABLE_INQUIRE_MODE=true. Falls back to the classic pipeline on # any agent failure. # ENABLE_INQUIRE_AGENT=false # Tool-calling mode: auto (probe native, fall back to prompted JSON), # native, or prompt. Default: auto. # INQUIRE_AGENT_TOOL_MODE=auto # Loop limits (defaults shown): max tool steps per answer, per-tool-result # token cap, wall-clock cap, and the conversation context budget that # triggers history compaction. # INQUIRE_AGENT_MAX_STEPS=8 # INQUIRE_AGENT_TOOL_RESULT_TOKENS=4000 # INQUIRE_AGENT_TIMEOUT_SECONDS=120 # INQUIRE_CONTEXT_BUDGET_TOKENS=24000 # Defaults for the per-user content availability toggles (users override in # Account settings; transcripts are always available): # INQUIRE_DEFAULT_ALLOW_SUMMARIES=true # INQUIRE_DEFAULT_ALLOW_NOTES=false # Embedding model for Inquire-mode semantic search. # Default is a local sentence-transformers model (no API needed). # EMBEDDING_MODEL=all-MiniLM-L6-v2 # To use an OpenAI-compatible embeddings API instead of the local model, # set the endpoint and API key below. When EMBEDDING_BASE_URL is set, # Inquire embeddings are generated via the API instead of locally. # EMBEDDING_BASE_URL= # # Chunking for search indexing. Diarized transcripts are chunked # segment-aware ("Speaker: text" lines, whole turns kept together, speaker # and timestamps stored per chunk). Set CHUNKING_STRATEGY=legacy to keep the # old plain 500-character windows instead. Existing chunks are unaffected # either way until a recording is reindexed. # CHUNKING_STRATEGY=segment # CHUNK_TARGET_CHARS=1400 # # Embedding API robustness: inputs per request (providers cap this), and how # long to skip a failing embeddings endpoint before probing again (searches # fall back to keyword matching in the meantime). # EMBEDDING_API_BATCH_SIZE=96 # EMBEDDING_API_COOLDOWN_SECONDS=120 # EMBEDDING_API_KEY= # Optional fixed embedding dimensionality. Leave empty to auto-detect from # the model/endpoint. # EMBEDDING_DIMENSIONS= # --- Automated File Processing (Black Hole Directory) --- ENABLE_AUTO_PROCESSING=false # AUTO_PROCESS_MODE=admin_only # AUTO_PROCESS_WATCH_DIR=/data/auto-process # --- Automated Export --- ENABLE_AUTO_EXPORT=false # AUTO_EXPORT_DIR=/data/exports # --- Auto-Deletion & Retention --- ENABLE_AUTO_DELETION=false # GLOBAL_RETENTION_DAYS=90 # DELETION_MODE=audio_only # --- Sharing Settings --- ENABLE_INTERNAL_SHARING=false ENABLE_PUBLIC_SHARING=true # SHOW_USERNAMES_IN_UI=false # --- Permission Controls --- USERS_CAN_DELETE=true # Delete speaker profiles when all their recordings are removed. # Default: false (speaker profiles and voice embeddings are preserved) # Set to true for privacy-sensitive deployments where biometric voice data # should not outlive the recordings it was derived from. # DELETE_ORPHANED_SPEAKERS=false # --- Video Retention --- # When enabled, uploaded video files keep their video stream for in-browser playback # The audio is extracted to a temp file for transcription, then cleaned up # Also enables the in-app recorder's "Also record video" option for system-audio # and mic+system recordings (captures the shared tab/window/screen as video) # Default: false (video uploads extract audio only, video stream is discarded) VIDEO_RETENTION=false # Video bitrate cap (kbps) for in-app tab/window/screen video capture. # Screen content compresses well; 2500 kbps keeps an hour of capture near 1 GB. # RECORDING_VIDEO_KBPS=2500 # --- Video Passthrough to ASR --- # Send original video files directly to ASR without extracting audio. # Useful for custom ASR backends that handle video internally (e.g., multi-track audio extraction). # When enabled, video files bypass audio extraction, codec conversion, and chunking. # Only affects video files — audio uploads are processed normally. # Default: false # VIDEO_PASSTHROUGH_ASR=false # --- Concurrent Uploads --- # Maximum number of simultaneous file uploads (default: 3) MAX_CONCURRENT_UPLOADS=3 # --- Reliability / Security (optional) --- # Hard wall-clock cap (seconds) on any single ffmpeg/ffprobe invocation, so a # malformed or adversarial media file can't hang a processing worker forever. # Default: 3600 (1 hour). # FFMPEG_TIMEOUT_SECONDS=3600 # # Per-endpoint rate limiting on auth routes (login, register, password reset). # Set to false only if a reverse proxy in front of Speakr already rate-limits # these. Default: true. # RATELIMIT_ENABLED=true # ============================================================================= # SERVER-SIDE RECORDING SESSIONS (optional) # ============================================================================= # Opt-in: in-app recordings stream audio chunks to the server as they record, # instead of buffering the entire recording in browser RAM. This enables # hours-long recordings and resume-on-reload if the tab is closed or refreshed. # Default: false (recordings are buffered in the browser). # ENABLE_SERVER_RECORDING_CHUNKS=false # Absolute ceiling (in hours) on a single in-app recording when server # chunking is enabled. # RECORDING_MAX_HOURS=8 # Per-user soft storage cap (in bytes) for in-progress server recording # sessions. Default: 5368709120 (5 GB). # RECORDING_SESSION_MAX_BYTES_PER_USER=5368709120 # # MediaRecorder timeslice (seconds): how often each in-app recording emits # and uploads a chunk. Smaller = finer crash recovery; larger = fewer # requests/files/DB writes. Default: 5 (range 1-60). # RECORDING_CHUNK_SECONDS=5 # # How many chunks to accumulate before committing session bookkeeping to the # DB. Chunk files always hit disk immediately; only the row counters lag, and # finalize re-derives the true count from disk. Raising this cuts DB write # pressure at scale (important on SQLite, which is single-writer). Default: 1 # (commit every chunk). For many concurrent recorders, consider 6 (~30s at 5s # chunks) and/or move to PostgreSQL. # RECORDING_SESSION_COMMIT_BATCH_SIZE=1 # # Inactivity TTL (hours) before an abandoned in-progress session is reaped. # Abandoned sessions that have audio are auto-finalized into the user's # library (not discarded), so a crashed or closed-tab recording is not lost. # Default: 24. # RECORDING_SESSION_TTL_HOURS=24 # ============================================================================= # WEBHOOKS (optional) # ============================================================================= # Outbound webhooks notify external services when events occur (e.g. a # recording finishes processing). Configured per-user in the UI. # Master kill-switch for outbound webhook delivery. Set to false to disable # all webhook delivery globally. Default: true. # WEBHOOK_GLOBAL_ENABLED=true # Maximum number of webhook subscriptions allowed per user (default: 10). # WEBHOOK_MAX_PER_USER=10 # ============================================================================= # BACKGROUND PROCESSING # ============================================================================= # Transcription queue workers (default: 2) JOB_QUEUE_WORKERS=2 # Summary queue workers (default: 2) SUMMARY_QUEUE_WORKERS=2 # Maximum retry attempts for failed jobs (default: 3) JOB_MAX_RETRIES=3 # ============================================================================= # DOCKER/DATABASE SETTINGS # ============================================================================= # Database URI - SQLite (default) or PostgreSQL SQLALCHEMY_DATABASE_URI=sqlite:////data/instance/transcriptions.db # For PostgreSQL: postgresql://username:password@hostname:5432/database_name UPLOAD_FOLDER=/data/uploads # ============================================================================= # FILE STORAGE (Local / S3-Compatible: AWS S3, MinIO) # ============================================================================= # Storage backend for recording audio files: local | s3 FILE_STORAGE_BACKEND=local # Key prefix inside the selected backend FILE_STORAGE_KEY_PREFIX=recordings # Optional local staging directory for uploads/conversion before final store # FILE_STORAGE_STAGING_DIR=/data/uploads/_staging # S3-compatible settings (used when FILE_STORAGE_BACKEND=s3) # S3_BUCKET_NAME=speakr-audio # S3_REGION=us-east-1 # S3_ENDPOINT_URL=http://minio:9000 # S3_ACCESS_KEY_ID=minioadmin # S3_SECRET_ACCESS_KEY=minioadmin # S3_SESSION_TOKEN= # S3_USE_PATH_STYLE=true # S3_VERIFY_SSL=false # S3_PRESIGN_TTL_SECONDS=900 # S3_PRESIGN_PUBLIC_TTL_SECONDS=300 # Audio delivery for S3 uses redirect to presigned URLs by default. # ============================================================================= # OPENASR CONFIGURATION (Local server) # ============================================================================= # OpenASR (https://openasr.org) is an open-source (Apache-2.0), local-first # speech-to-text desktop app that exposes a local OpenAI-compatible API. # Audio is processed entirely on your # machine. Supports diarization, word timestamps, and many model families. # # TRANSCRIPTION_CONNECTOR=openasr # TRANSCRIPTION_BASE_URL=http://127.0.0.1:8080 # TRANSCRIPTION_MODEL=qwen3-asr-0.6b # TRANSCRIPTION_API_KEY= # optional; loopback servers can skip auth # # Diarization default and request timeout reuse the shared ASR settings: # ASR_DIARIZE=true # ASR_TIMEOUT=1800 # # Per-user hotwords and initial prompts are combined into the standard # OpenAI-compatible 'prompt' parameter. The server handles long files itself, # so the app does not chunk for it. # ============================================================================= # FUTURE: Additional Provider Notes # ============================================================================= # The connector architecture is designed to support additional providers. # Currently available: openai_whisper, openai_transcribe, asr_endpoint, # azure_openai_transcribe, mistral, vibevoice # # Future connectors may include: # # - Deepgram: Known for excellent diarization and real-time transcription # - AssemblyAI: Strong diarization with speaker labels # - Google Cloud Speech-to-Text: Enterprise-grade with speaker diarization # # To request a new connector, please open an issue on GitHub.