Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions dream-server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ OPENCLAW_TOKEN=CHANGEME
# escape hatch; a loud warning banner is logged at startup when set.
# Leave unset (the secure default) unless you fully accept the risk.
# OPENCLAW_DANGEROUSLY_DISABLE_DEVICE_AUTH=
# OPENCLAW_LLM_URL=
# OPENCLAW_HTTP_API=

# ═══════════════════════════════════════════════════════════════════
# Network Binding
Expand All @@ -83,6 +85,7 @@ LLM_BACKEND=llama-server
# API base path: /v1 for llama-server, /api/v1 for Lemonade (set by installer)
LLM_API_BASE_PATH=/v1
LLM_API_URL=http://llama-server:8080
# LLM_URL= # Optional dashboard-api diagnostics override; normally follows LLM_API_URL

# Dream Talk image attachment vision backend. Leave empty to use the local
# inference backend. May be a host root (http://host:8080) or an
Expand Down Expand Up @@ -231,6 +234,9 @@ WEBUI_PORT=3000 # Open WebUI (external → internal 8080)
# detection fails. Set explicitly to override.
# DREAM_AGENT_BIND=

# Host Agent HTTP port used by dashboard-api for privileged host operations.
# DREAM_AGENT_PORT=7710

# Hostname/IP dashboard-api containers use to reach dream-host-agent.
# Docker Desktop installs set this to host.docker.internal because the
# host-agent stays loopback-only on macOS/Windows.
Expand All @@ -249,6 +255,11 @@ WEBUI_PORT=3000 # Open WebUI (external → internal 8080)
# currently-issued session cookies (forces re-redemption).
# DREAM_SESSION_SECRET=

# Public/custom URL and cookie domain for invite links, tunnels, and
# subdomain SSO. Leave empty for normal localhost or mDNS LAN generation.
# DREAM_PUBLIC_URL=
# DREAM_COOKIE_DOMAIN=

# Privacy Shield API key (generate: openssl rand -hex 32) - auto-generated by installer; shared between dashboard-api and privacy-shield containers
# SHIELD_API_KEY=

Expand Down Expand Up @@ -303,15 +314,30 @@ LANGFUSE_INIT_USER_PASSWORD= # auto-generated during install
# Whisper model (tiny, base, small, medium, large-v3-turbo)
# WHISPER_MODEL=base

# Whisper STT model (HuggingFace repo ID). Installer auto-selects by GPU:
# Open WebUI STT settings. Installer auto-selects AUDIO_STT_MODEL by GPU:
# NVIDIA → deepdml/faster-whisper-large-v3-turbo-ct2 (faster, ~1.5GB)
# AMD/CPU → Systran/faster-whisper-base (~130MB)
# Override to use a different model — must then run `dream restart` and
# manually download the new model via:
# curl -X POST --max-time 3600 http://localhost:9000/v1/models/<url-encoded-model-id>
# AUDIO_STT_ENGINE=openai
# AUDIO_STT_OPENAI_API_BASE_URL=http://whisper:8000/v1
# AUDIO_STT_OPENAI_API_KEY=
# AUDIO_STT_MODEL=Systran/faster-whisper-base

# Kokoro TTS voice name
# Internal URLs used by dashboard-api and Dream Talk when running diagnostics
# or voice flows from inside the Docker network.
# WHISPER_URL=http://whisper:8000
# TTS_URL=http://tts:8880
# EMBEDDING_URL=http://embeddings:80

# Kokoro/Open WebUI TTS settings
# AUDIO_TTS_ENGINE=openai
# AUDIO_TTS_OPENAI_API_BASE_URL=http://tts:8880/v1
# AUDIO_TTS_OPENAI_API_KEY=
# AUDIO_TTS_MODEL=kokoro
# AUDIO_TTS_VOICE=af_heart
# Legacy Kokoro TTS voice name
# TTS_VOICE=en_US-lessac-medium

# Open WebUI authentication (true/false)
Expand Down Expand Up @@ -350,6 +376,15 @@ LANGFUSE_INIT_USER_PASSWORD= # auto-generated during install
# Image generation (ComfyUI + SDXL Lightning)
# ENABLE_IMAGE_GENERATION=true

# ═══════════════════════════════════════════════════════════════════
# Agent Policy Engine (APE)
# ═══════════════════════════════════════════════════════════════════
#
# APE audits and can enforce policy decisions for agent tool usage.
# APE_PORT=7890
# APE_RATE_LIMIT_RPM=60
# APE_STRICT_MODE=false

# ═══════════════════════════════════════════════════════════════════
# AMD-specific (only needed with GPU_BACKEND=amd)
# ═══════════════════════════════════════════════════════════════════
Expand Down Expand Up @@ -417,6 +452,7 @@ LANGFUSE_INIT_USER_PASSWORD= # auto-generated during install
# HERMES_LLM_BASE_URL=http://llama-server:8080/v1 # OpenAI-compat endpoint
# HERMES_LLM_API_KEY=sk-dream-hermes-local # Dummy (OpenAI SDK requires non-empty)
# HERMES_LANGUAGE=en # UI language
# SEARXNG_URL=http://searxng:8080 # Hermes web-search backend
# (No HERMES_MODEL_NAME — the model lives in /opt/data/config.yaml,
# not in env. Edit the file after first start to switch models.)
#
Expand All @@ -426,6 +462,9 @@ LANGFUSE_INIT_USER_PASSWORD= # auto-generated during install
# WHATSAPP_ENABLED=false
# WHATSAPP_MODE=self-chat
# WHATSAPP_ALLOWED_USERS=15551234567
# WHATSAPP_REQUIRE_MENTION=
# WHATSAPP_FREE_RESPONSE_CHATS=
# WHATSAPP_REPLY_PREFIX=
#
# Hermes is reached on the LAN via dream-hermes-proxy (Caddy sidecar) which
# verifies the dream-session cookie against dashboard-api's verify endpoint
Expand All @@ -434,6 +473,7 @@ LANGFUSE_INIT_USER_PASSWORD= # auto-generated during install
# HERMES_PROXY_PORT=9120 # LAN entry — what users actually browse to
# HERMES_PROXY_UPSTREAM=dream-hermes:9119 # Where the proxy forwards (internal DNS)
# DREAM_AUTH_UPSTREAM=dream-dashboard-api:3002 # Where forward_auth verifies sessions
# HERMES_PROXY_AUTH_DOCS_URL= # Optional help link on the auth-required page

# Tailscale (Remote Access)
# ═══════════════════════════════════════════════════════════════════
Expand Down
153 changes: 153 additions & 0 deletions dream-server/.env.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
"description": "URL where all services send LLM requests",
"default": "http://llama-server:8080"
},
"LLM_URL": {
"type": "string",
"description": "LLM base URL used by dashboard-api functional diagnostics. Leave empty to follow LLM_API_URL inside the Docker network."
},
"LLM_BACKEND": {
"type": "string",
"description": "Inference backend: llama-server or lemonade",
Expand Down Expand Up @@ -216,6 +220,12 @@
"description": "OpenClaw agent framework token",
"secret": true
},
"OPENCLAW_DANGEROUSLY_DISABLE_DEVICE_AUTH": {
"type": "string",
"description": "Dangerous escape hatch that disables OpenClaw device pairing. Leave empty unless you fully accept unauthenticated LAN/Tailscale agent access risk.",
"enum": ["", "true", "false"],
"default": ""
},
"BIND_ADDRESS": {
"type": "string",
"description": "IP address for Docker port bindings. 127.0.0.1 (default) for localhost-only access. 0.0.0.0 for LAN access on headless servers. See SECURITY.md.",
Expand Down Expand Up @@ -249,6 +259,18 @@
"description": "Number of model layers to offload to GPU",
"default": 99
},
"LLAMA_BATCH_SIZE": {
"type": "integer",
"description": "llama.cpp prompt processing batch size. Higher values can improve prefill throughput but use more memory.",
"minimum": 1,
"default": 2048
},
"LLAMA_THREADS": {
"type": "integer",
"description": "CPU threads for llama.cpp non-GPU work.",
"minimum": 1,
"default": 4
},
"HOST_RAM_GB": {
"type": "integer",
"description": "Unified system RAM in GB. macOS Apple Silicon only; the macOS env-generator writes it from sysctl hw.memsize and it is passed to llama.cpp for the Metal backend so it can size the unified-memory pool. Not written on Linux or Windows .env files. Not sensitive.",
Expand Down Expand Up @@ -317,6 +339,10 @@
"type": "string",
"description": "Optional llama.cpp container image override for model families that require newer runtime support"
},
"LLAMA_SERVER_IMAGE_FALLBACK": {
"type": "string",
"description": "Optional explicit fallback image if a custom llama.cpp image tag disappears or fails to pull."
},
"LEMONADE_SERVER_IMAGE": {
"type": "string",
"description": "Optional AMD Lemonade container image override. AMD Linux installs default to the image pinned in config/backends/amd.json."
Expand Down Expand Up @@ -555,11 +581,59 @@
"description": "Whisper STT model size",
"default": "base"
},
"WHISPER_URL": {
"type": "string",
"description": "Internal Whisper STT URL used by dashboard-api and Dream Talk. Leave empty for the bundled whisper service."
},
"AUDIO_STT_ENGINE": {
"type": "string",
"description": "Open WebUI speech-to-text engine.",
"default": "openai"
},
"AUDIO_STT_OPENAI_API_BASE_URL": {
"type": "string",
"description": "OpenAI-compatible speech-to-text base URL used by Open WebUI.",
"default": "http://whisper:8000/v1"
},
"AUDIO_STT_OPENAI_API_KEY": {
"type": "string",
"description": "Optional API key for the Open WebUI speech-to-text backend.",
"secret": true
},
"AUDIO_STT_MODEL": {
"type": "string",
"description": "Whisper STT model (HuggingFace repo ID). Auto-set by installer based on GPU backend: NVIDIA picks large-v3-turbo (faster, ~1.5GB), others pick base (~130MB). Edit in .env to override, then run `dream restart` (or reinstall).",
"default": "Systran/faster-whisper-base"
},
"TTS_URL": {
"type": "string",
"description": "Internal Kokoro TTS URL used by dashboard-api and Dream Talk. Leave empty for the bundled tts service."
},
"AUDIO_TTS_ENGINE": {
"type": "string",
"description": "Open WebUI text-to-speech engine.",
"default": "openai"
},
"AUDIO_TTS_OPENAI_API_BASE_URL": {
"type": "string",
"description": "OpenAI-compatible text-to-speech base URL used by Open WebUI.",
"default": "http://tts:8880/v1"
},
"AUDIO_TTS_OPENAI_API_KEY": {
"type": "string",
"description": "Optional API key for the Open WebUI text-to-speech backend.",
"secret": true
},
"AUDIO_TTS_MODEL": {
"type": "string",
"description": "Open WebUI/Dream Talk text-to-speech model id.",
"default": "kokoro"
},
"AUDIO_TTS_VOICE": {
"type": "string",
"description": "Open WebUI/Dream Talk Kokoro voice id.",
"default": "af_heart"
},
"TIMEZONE": {
"type": "string",
"description": "System timezone",
Expand All @@ -584,6 +658,10 @@
"description": "Embedding model for RAG",
"default": "BAAI/bge-base-en-v1.5"
},
"EMBEDDING_URL": {
"type": "string",
"description": "Embedding service URL used by dashboard-api functional diagnostics. Leave empty for the bundled embeddings service."
},
"VIDEO_GID": {
"type": "integer",
"description": "GID of the 'video' group on the host (used in container group_add for AMD GPU access)",
Expand Down Expand Up @@ -905,6 +983,18 @@
"description": "Agent Policy Engine port",
"default": 7890
},
"APE_RATE_LIMIT_RPM": {
"type": "integer",
"description": "APE per-minute policy check rate limit.",
"default": 60,
"minimum": 1
},
"APE_STRICT_MODE": {
"type": "string",
"description": "When true, APE blocks policy violations instead of only logging advisory decisions.",
"enum": ["true", "false"],
"default": "false"
},
"OPENCLAW_API_KEY": {
"type": "string",
"description": "OpenClaw API key for authentication",
Expand All @@ -914,11 +1004,28 @@
"type": "string",
"description": "OpenClaw configuration profile name"
},
"OPENCLAW_LLM_URL": {
"type": "string",
"description": "Optional OpenClaw provider base URL override, mainly for routing OpenClaw traffic through monitoring/proxy layers."
},
"OPENCLAW_HTTP_API": {
"type": "string",
"description": "Opt-in OpenClaw OpenAI-compatible HTTP shim. Leave empty unless you are deliberately exposing the shim for advanced integrations.",
"enum": ["", "true", "false"],
"default": ""
},
"DREAM_AGENT_BIND": {
"type": "string",
"description": "Bind address for the Dream Host Agent HTTP server. Defaults to 127.0.0.1 on macOS/Windows, dream-network gateway IP on Linux, then Docker bridge gateway, then 127.0.0.1.",
"default": ""
},
"DREAM_AGENT_PORT": {
"type": "integer",
"description": "Host Agent HTTP port used by dashboard-api to request privileged host operations such as .env writes and service recreation.",
"default": 7710,
"minimum": 1,
"maximum": 65535
},
"DREAM_AGENT_HOST": {
"type": "string",
"description": "Hostname or IP that dashboard-api containers use to reach the Dream Host Agent. Docker Desktop installs set this to host.docker.internal so loopback-only host-agent binds remain reachable from containers.",
Expand Down Expand Up @@ -1001,6 +1108,14 @@
"description": "HMAC signing secret for the dream-session cookie. dashboard-api uses this to sign at magic-link redemption; the Hermes auth-proxy uses /api/auth/verify-session to validate. Generate with `openssl rand -hex 32`. Rotating kicks all current sessions.",
"secret": true
},
"DREAM_PUBLIC_URL": {
"type": "string",
"description": "Public base URL used by dashboard-api when generating invite and magic-link URLs for custom domains, tunnels, or Tailscale Funnel. Leave empty for normal mDNS/LAN URL generation."
},
"DREAM_COOKIE_DOMAIN": {
"type": "string",
"description": "Cookie domain for dream-session SSO across dashboard/chat/auth/hermes subdomains. Empty keeps cookies host-only; proxy installs commonly use <device>.local."
},
"DREAM_PROXY_PORT": {
"type": "integer",
"description": "Host port for the Dream Server reverse proxy (Caddy). Default 80 — standard HTTP. The proxy is opt-in via `dream enable dream-proxy`.",
Expand Down Expand Up @@ -1031,6 +1146,40 @@
"description": "UI language for Hermes Agent's web dashboard (defaults to en).",
"default": "en"
},
"SEARXNG_URL": {
"type": "string",
"description": "SearXNG URL used by Hermes web tools. Defaults to the bundled searxng service on the Docker network.",
"default": "http://searxng:8080"
},
"WHATSAPP_ENABLED": {
"type": "string",
"description": "Enable Hermes's optional WhatsApp gateway integration. Disabled by default.",
"enum": ["", "true", "false"],
"default": "false"
},
"WHATSAPP_MODE": {
"type": "string",
"description": "Hermes WhatsApp gateway mode.",
"default": "self-chat"
},
"WHATSAPP_ALLOWED_USERS": {
"type": "string",
"description": "Comma-separated WhatsApp user IDs or phone numbers allowed to talk to Hermes."
},
"WHATSAPP_REQUIRE_MENTION": {
"type": "string",
"description": "Require a mention/prefix before Hermes replies in WhatsApp chats.",
"enum": ["", "true", "false"],
"default": ""
},
"WHATSAPP_FREE_RESPONSE_CHATS": {
"type": "string",
"description": "Comma-separated WhatsApp chat IDs where Hermes may respond without an explicit mention."
},
"WHATSAPP_REPLY_PREFIX": {
"type": "string",
"description": "Optional prefix added to Hermes WhatsApp replies."
},
"HERMES_PROXY_PORT": {
"type": "integer",
"description": "External port for the Hermes auth-proxy (Caddy sidecar that gates LAN access by verifying the dream-session cookie via dashboard-api's /api/auth/verify-session endpoint).",
Expand All @@ -1046,6 +1195,10 @@
"description": "Where Caddy forward_auth sends its session-verify sub-request. Defaults to the in-network dashboard-api container; override if dashboard-api lives elsewhere.",
"default": "dream-dashboard-api:3002"
},
"HERMES_PROXY_AUTH_DOCS_URL": {
"type": "string",
"description": "Optional docs/help URL shown on the Hermes auth-required page when a visitor lacks a valid dream-session cookie."
},
"TS_AUTHKEY": {
"type": "string",
"description": "Tailscale auth key (tskey-auth-...). Generate at https://login.tailscale.com/admin/settings/keys. Consumed once on first join; the daemon caches the node key in data/tailscale/.",
Expand Down
16 changes: 8 additions & 8 deletions dream-server/docker-compose.base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,16 @@ services:
{"type":"seed","key":"seed","node_ids":["3"]},
{"type":"n","key":"batch_size","node_ids":["5"]}]
# ── Speech-to-Text (Whisper) ──
AUDIO_STT_ENGINE: "openai"
AUDIO_STT_OPENAI_API_BASE_URL: "http://whisper:8000/v1"
AUDIO_STT_OPENAI_API_KEY: ""
AUDIO_STT_ENGINE: "${AUDIO_STT_ENGINE:-openai}"
AUDIO_STT_OPENAI_API_BASE_URL: "${AUDIO_STT_OPENAI_API_BASE_URL:-http://whisper:8000/v1}"
AUDIO_STT_OPENAI_API_KEY: "${AUDIO_STT_OPENAI_API_KEY:-}"
AUDIO_STT_MODEL: "${AUDIO_STT_MODEL:-Systran/faster-whisper-base}"
# ── Text-to-Speech (Kokoro) ──
AUDIO_TTS_ENGINE: "openai"
AUDIO_TTS_OPENAI_API_BASE_URL: "http://tts:8880/v1"
AUDIO_TTS_OPENAI_API_KEY: ""
AUDIO_TTS_MODEL: "kokoro"
AUDIO_TTS_VOICE: "af_heart"
AUDIO_TTS_ENGINE: "${AUDIO_TTS_ENGINE:-openai}"
AUDIO_TTS_OPENAI_API_BASE_URL: "${AUDIO_TTS_OPENAI_API_BASE_URL:-http://tts:8880/v1}"
AUDIO_TTS_OPENAI_API_KEY: "${AUDIO_TTS_OPENAI_API_KEY:-}"
AUDIO_TTS_MODEL: "${AUDIO_TTS_MODEL:-kokoro}"
AUDIO_TTS_VOICE: "${AUDIO_TTS_VOICE:-af_heart}"
TZ: "${TIMEZONE:-UTC}"
volumes:
- ./data/open-webui:/app/backend/data:z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def _tts_model() -> str:


def _tts_voice() -> str:
return os.environ.get("AUDIO_TTS_VOICE") or "af_heart"
return os.environ.get("AUDIO_TTS_VOICE") or os.environ.get("TTS_VOICE") or "af_heart"


async def _transcribe_bytes(data: bytes, filename: str, content_type: str) -> str:
Expand Down
Loading
Loading