Files
piperust/.env.example
T
2026-10-16 12:33:56 +01:00

160 lines
7.6 KiB
Bash

# Audio Agent Engine — Environment Variables
# Copy to `.env` and adjust as needed.
# --- Server ---
SERVER_PORT=8787
# --- TTS Engine Selection ---
# Choose the TTS engine plugin. Supported values:
# fish — Fish Audio / SGLang Drama 3 (OpenAI-compatible HTTP endpoint)
# kokoro — Kokoro TTS (stub; see src/tts/kokoro.rs)
TTS_ENGINE=fish
# --- Fish Audio / SGLang (TTS_ENGINE=fish) ---
SGLANG_URL=http://10.8.0.3:8000
TTS_MODEL=fishaudio/drama-3
TTS_VOICE=default
# Optional voice-cloning reference (path on the Fish Audio server filesystem).
TTS_REFERENCE_AUDIO=/root/pipecat-voice/voice_profiles/solis.wav
# Optional transcript. If it looks like a .txt path, its contents are loaded;
# otherwise the raw string is used. Leave empty to auto-load <audio>.txt.
TTS_REFERENCE_TEXT=/root/pipecat-voice/voice_profiles/solis.txt
# --- Kokoro (TTS_ENGINE=kokoro) ---
KOKORO_URL=http://localhost:8880
KOKORO_VOICE=af_heart
# --- STT (Parakeet TDT, pure-Rust ONNX pipeline) ---
# Directory containing nemo128.onnx, encoder-model*.onnx,
# decoder_joint-model.onnx, vocab.txt and config.json.
STT_MODEL_PATH=models/parakeet
# Optional external tokenizer; leave empty — Parakeet decodes text internally.
STT_TOKENIZER_PATH=
# --- VAD (Silero VAD v5, ONNX) ---
# Master switch. When disabled, the STT worker falls back to its internal
# RMS-based segmentation (legacy behaviour).
VAD_ENABLED=true
# Path to the Silero VAD ONNX model (16 kHz, 512-sample windows).
VAD_MODEL_PATH=models/silero_vad.onnx
# Speech probability above which a window counts as voice.
VAD_THRESHOLD=0.5
# Probability below which a window counts as silence. Must be <= VAD_THRESHOLD;
# the gap provides hysteresis and prevents onset/offset flapping.
VAD_NEG_THRESHOLD=0.35
# Speech required (ms) to confirm an utterance start.
VAD_MIN_SPEECH_MS=250
# Silence required (ms) to close an utterance (end-of-utterance window).
VAD_MIN_SILENCE_MS=300
# Audio kept (ms) before the detected onset, so the first phoneme is not clipped.
VAD_SPEECH_PAD_MS=30
# Speech required (ms) to fire the fast barge-in onset (must be <= VAD_MIN_SPEECH_MS).
VAD_BARGE_IN_MIN_SPEECH_MS=150
# Feed the STT engine with VAD-segmented utterances (true) instead of letting
# the worker run its own RMS segmentation (false).
VAD_SEGMENT_STT=true
# Interrupt the agent when the user starts speaking over it.
VAD_BARGE_IN=true
# Log the speech probability of every analysis window (debug).
VAD_DEBUG=false
# --- Fillers / Mixer ---
# Directory of preloaded "*.raw" PCM clips (16-bit LE mono, 44.1 kHz), e.g.
# uhm / eh / mmm. Played round-robin at most once per turn.
FILLERS_DIR=assets/fillers
# Master switch. When disabled, no end-of-turn filler is ever queued.
FILLER_ENABLED=true
# Latency guard (ms): the filler is a latency mask, so it is only played if the
# response audio has not started within this window. If the reply starts
# speaking earlier the filler is dropped, instead of talking over the first
# words of the answer. Increase for slower LLM/TTS, decrease for faster ones.
FILLER_DELAY_MS=2500
FILLER_GAIN_IDLE=1.0
FILLER_GAIN_DUCK=0.15
# TTS jitter buffer (ms): how much synthesized audio the mixer buffers before it
# starts playing the reply. Lower values start speaking sooner; higher values
# absorb uneven TTS chunk arrival at the cost of added latency. Drama-3's vocoder
# emits audio in windows of `stream_followup_stride` codec frames (2048 samples =
# 46.4 ms each); with the recommended server setting (stride 16, ramp
# "[10,12,16]") the first window is 10 frames = 0.464 s, so 450 ms starts
# playback on that very first window. Mid-reply underruns resume as soon as any
# audio is queued again (no full refill).
TTS_PREBUFFER_MS=450
# Number of TTS requests kept in flight at once. Reply chunks are synthesized
# ahead of playback (and replayed in order) so each request's start-up latency
# hides behind the previous chunk's audio instead of leaving an audible gap.
# 1 restores strictly serial synthesis.
TTS_PIPELINE_DEPTH=3
# --- Backchannel (short acknowledgments while the user speaks) ---
# Master switch. When disabled, no during-utterance acknowledgment is played.
BACKCHANNEL_ENABLED=true
# Directory of preloaded "*.raw" PCM clips (16-bit LE mono, 44.1 kHz), e.g.
# mmhmm / ajá / claro. Played round-robin.
BACKCHANNEL_DIR=assets/backchannel
# Mix gain applied to the backchannel channel (0..1). Kept low so the cue stays
# in the background.
BACKCHANNEL_GAIN=0.35
# Continuous speech required (ms) before the first backchannel of a turn.
BACKCHANNEL_MIN_SPEECH_MS=1500
# Minimum spacing (ms) between two backchannels. Clamped to >= MIN_SPEECH_MS.
BACKCHANNEL_INTERVAL_MS=3000
# Maximum backchannels emitted per user turn.
BACKCHANNEL_MAX_PER_TURN=2
# --- LLM reasoning (OpenAI-compatible chat-completions endpoint) ---
# When enabled, the user transcript is sent to the model and the reply is
# spoken by the TTS (sentence by sentence while streaming). When disabled the
# pipeline is a plain STT → TTS echo. The `/mivocero` client shows both the
# user transcript and the assistant reply in its chat box.
# Enabled automatically when both LLM_BASE_URL and LLM_MODEL are set.
LLM_ENABLED=true
# Base URL including the API version, e.g. a local vLLM / SGLang server.
LLM_BASE_URL=http://10.8.0.4:8000/v1
# Sent as `Authorization: Bearer <key>`. Local servers accept any value.
LLM_API_KEY=EMPTY
LLM_MODEL=Qwen/Qwen3.6-35B-A3B
LLM_MAX_TOKENS=1024
LLM_TEMPERATURE=0.7
# Stream tokens as they are generated (true → lower time-to-first-audio) or
# wait for the complete reply before speaking (false).
LLM_STREAM=true
# Rolling conversation window kept in memory (messages, system prompt excluded).
LLM_HISTORY_MESSAGES=16
# --- Chain-of-thought control (three independent mechanisms) ---
# Some reasoning models narrate their thinking instead of answering directly:
# Qwen3 on vLLM/SGLang writes it to a separate `reasoning_content` field (or
# inline think blocks) when a reasoning parser is enabled, but with no parser
# at all it leaks straight into `content` and would be read aloud by the TTS.
# 1) Server-side thinking mode. `false` sends
# `chat_template_kwargs: {"enable_thinking": false}` (vLLM/SGLang, Qwen3).
# Leave unset/omitted to not send the vendor-specific field at all.
LLM_ENABLE_THINKING=false
# 2) Drop the reasoning from the reply before it reaches the chat box / TTS:
# ignores `reasoning_content` deltas and removes inline think blocks (also
# stable when a marker is split across streamed deltas).
LLM_STRIP_REASONING=true
# 3) Append an explicit "answer directly, never narrate your reasoning"
# directive to the system prompt (see `DIRECT_ANSWER_DIRECTIVE`).
LLM_DIRECT_ANSWERS=true
# Streaming chunking: characters the reply must hold before the FIRST chunk is
# handed to the TTS. Small by default so the agent starts speaking on the first
# few words instead of waiting for a whole sentence. `0` disables the early
# word-boundary flush (chunks then end on sentence punctuation only).
LLM_STREAM_FIRST_CHUNK_CHARS=20
# Same threshold for every chunk after the first. Larger chunks give better
# prosody; smaller ones keep the audio flowing while the model is generating.
LLM_STREAM_CHUNK_CHARS=120
# Optional system prompt override. Leave unset for the built-in voice-assistant
# prompt (see `DEFAULT_LLM_SYSTEM_PROMPT` in src/config.rs).
#LLM_SYSTEM_PROMPT=
# --- HTTPS (optional) ---
# Set BOTH to serve HTTPS/WSS instead of plain HTTP. A secure context is
# required by browsers to grant microphone access (getUserMedia) when the page
# is not opened on localhost. Generate a self-signed pair with:
# ./server.sh cert
# Then open https://localhost:8787/ and accept the certificate warning.
TLS_CERT=certs/cert.pem
TLS_KEY=certs/key.pem