Files
javis/config.example.yaml
T
JavisandCopilot 1fa75e58fc End recording when the user stops, not the music
Silero VAD answers "is this voice-like?", which music, TV and podcasts
satisfy just as well as the user does. With Spotify playing through the
device's own speakers the VAD never went quiet, so record_utterance never
saw the end of the command and ran to the 20 s cap on master and slave
alike -- and music alone was enough to defeat the "no speech during the
grace window" early return.

Wrap the VAD in a SpeechEndpointer that tracks the background loudness of
the recent window and only reports speech while a frame is clearly louder
than it. Both wake-word loops feed their idle audio through observe(), so
the gate is already calibrated when a turn starts, and only non-voice
frames update the background so a long sentence cannot raise the gate onto
itself. Onset/release hysteresis keeps trailing quiet syllables.

The master owns the knob (wake_word.voice_gate_ratio, 0 = off) and pushes
it to satellites in the wake-word block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-10 13:04:13 +02:00

127 lines
6.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Javis configuration. Copy to config.yaml and edit.
gui:
theme: "dark" # dark | light (Tools → "Toggle light/dark theme")
show_startup_dialog: true # show the configuration dialog before the main window
minimize_to_tray: true # closing the window hides to the tray; quit via File → Quit
global_ptt_hotkey: "ctrl+alt+space" # system-wide push-to-talk (Windows); "" = off
llm:
base_url: "http://localhost:11434"
model: "gemma3:4b"
temperature: 0.7
request_timeout_seconds: 120
# Keep the model loaded in Ollama for 1 h after each request (default is
# only 5 min, so gaps > 5 min force a full model reload next turn).
# -1 keeps it loaded until Ollama restarts.
keep_alive: 3600
stt:
model_size: "large-v3" # tiny, base, small, medium, large-v3, distil-large-v3
device: "auto" # auto, cuda, cpu
compute_type: "float16" # float16, int8_float16, int8, float32
language: null # null = auto-detect
hotwords: "" # bias Whisper towards names, e.g. "Javis, Esszimmer, Homey"
tts:
backend: "piper" # piper (Piper VITS — CPU ONNX, default) | f5 (F5-TTS voice cloning)
device: "auto"
default_voice: "default" # Piper voice name (see the Voices tab / voice-ref-curator)
# Overnight voice training — the default voice is retrained once per night
# inside the start_hour → end_hour window, resuming from the latest checkpoint.
# Toggle/disable here (or in Settings → Voice Training); changes apply live.
training:
enabled: true
start_hour: 3 # window opens at 03:00 (0-23)
end_hour: 6 # window closes at 06:00 (0-23)
min_remaining_minutes: 60 # don't start a run if less window time remains
max_epochs: 6000
batch_size: 32
num_workers: 2
accelerator: "gpu" # gpu | cpu
precision: "16-mixed" # 32 | 16-mixed | bf16-mixed
language: "de" # espeak-ng voice code used for phonemisation (de, en-us, …)
audio:
sample_rate: 16000
input_device: null # null = system default; or int device index
output_device: null
thinking_cue_delay_s: 2.5 # soft tick while Javis is still working; 0 = off
wake_word:
enabled: true
model: "hey_jarvis" # built-in openWakeWord name, or a custom model: "rufus" -> ~/.javis/models/wakeword/rufus.onnx (see docs/WAKE_WORD.md)
threshold: 0.5
vad_threshold: 0.5 # silero-vad probability threshold
vad_gate: 0.0 # >0: wake only when openWakeWord's own VAD agrees (fewer false wakes from TV/music)
silence_ms: 800 # end-of-utterance silence
voice_gate_ratio: 3.0 # how much louder than the background a frame must be to count as
# the user talking — lets recording end while your own speakers play
# music (Silero rates music as speech). 0 = off, raise if commands
# get cut off, lower if music keeps the recorder running.
mcp:
servers_config: "mcp_servers.json"
approval_default: "ask" # ask | allow | deny (headless: "ask" is denied — no UI)
confirm_destructive: true # ask before tools marked destructiveHint, even on "allow" servers
call_timeout_seconds: 30
approval_timeout_seconds: 45 # auto-deny if the approval dialog isn't answered; 0 = wait
voice_approval: true # answer the approval prompt with "ja"/"nein" (needs STT + mic)
api:
# HTTP API for javis-slave companion devices (plain HTTP — trusted LAN only).
enabled: false
host: "0.0.0.0" # bind address; 0.0.0.0 = all interfaces
port: 8765
pairing_code_ttl_seconds: 300 # lifetime of a single-use pairing code
agent:
# Persona preset. Choose one: default | smart_home | concise | verbose
preset: "default"
# Optional verbatim system prompt (overrides the preset above).
system_prompt_inline: null
# Optional path to a .txt file (highest priority — overrides everything else).
system_prompt_file: null
history_max_turns: 20
# Maximum LLM <-> tool-call iterations per turn before giving up.
max_llm_iterations: 5
# Spoken feedback for voice users (empty string = silent).
error_phrase: "Entschuldigung, da ist etwas schiefgelaufen. Bitte versuch es noch einmal."
# Spoken when the GPU was lost (e.g. NVIDIA driver updated while running).
gpu_lost_phrase: "Die Grafikkarte ist nicht mehr erreichbar, vermutlich wurde der Treiber aktualisiert. Bitte starte Javis neu."
approval_phrase: "Soll ich das ausführen? Sag ja oder nein."
memory:
# "ollama" uses llm.base_url; "hermes" uses the remote Hermes API server.
provider: "ollama"
# Hermes API root (not the dashboard URL). Required when provider is hermes.
base_url: null
# Store API_SERVER_KEY in this environment variable; never put it in YAML.
api_key_env: "JAVIS_HERMES_API_KEY"
# Dedicated model for background fact extraction.
# null = use the same model as llm.model.
# Set to a smarter or reasoning model for higher-quality extraction without
# slowing down the main conversation (extraction runs in the background).
# Examples: "qwen2.5:14b", "qwen3:8b", "deepseek-r1:8b", "llama3.1:8b"
model: null
# Temperature for extraction calls. Low values (0.0–0.2) give more consistent
# JSON output. Reasoning models work well at 0.1.
temperature: 0.1
# Context window for extraction. Much smaller than the main LLM is fine —
# extraction prompts are short. Reduce if memory calls are slow.
num_ctx: 4096
# Timeout (seconds) for extraction calls. 120 is a safe default.
# Increase for reasoning models on slow hardware (deepseek-r1 can take 3–5 min on CPU).
# Set to null only to inherit llm.request_timeout_seconds (not recommended).
timeout_seconds: 120
# Maximum number of new facts to extract per turn.
max_facts: 2
# Maximum number of existing memories included in the extraction prompt
# (most-recently-updated first). Raise for larger memories, lower to keep
# extraction prompts short.
max_existing_for_prompt: 25
paths:
base_dir: null # null = ~/.javis