step2
This commit is contained in:
+172
-15
@@ -20,6 +20,25 @@ TTS_REFERENCE_AUDIO=/root/pipecat-voice/voice_profiles/solis.wav
|
||||
# otherwise the raw string is used. Leave empty to auto-load <audio>.txt.
|
||||
TTS_REFERENCE_TEXT=/root/pipecat-voice/voice_profiles/solis.txt
|
||||
|
||||
# --- Drama 3 de-emphasis (TTS_ENGINE=fish) ---
|
||||
# Drama 3 can sound overly theatrical/recitative. Two knobs trim that register
|
||||
# without changing the voice reference. Leave a sampling variable EMPTY to omit
|
||||
# the field and fall back to the server default.
|
||||
# Sampling temperature sent to SGLang. Lower values reduce over-articulation;
|
||||
# the recitative "radio drama" register lives in the distribution tails, so a
|
||||
# lower value makes the delivery flatter. Tunable range: 0.3–0.6.
|
||||
TTS_TEMPERATURE=0.45
|
||||
# Nucleus sampling top-p: trims the tail of the acoustic token distribution
|
||||
# (exaggerated intonations). 0.7–0.8 is the useful range.
|
||||
TTS_TOP_P=0.75
|
||||
# Optional top-k. Leave empty to omit the field (server default).
|
||||
TTS_TOP_K=
|
||||
# Neutral style tag prepended to every synthesis request that does not already
|
||||
# start with a "[...]" tag. LLM replies carry no tag (the system prompt forbids
|
||||
# stage directions), so they get this register; clip banks with their own tag
|
||||
# are left untouched. Empty disables the prefix.
|
||||
TTS_STYLE_TAG="[conversational, casual]"
|
||||
|
||||
# --- Kokoro (TTS_ENGINE=kokoro) ---
|
||||
KOKORO_URL=http://localhost:8880
|
||||
KOKORO_VOICE=af_heart
|
||||
@@ -71,15 +90,50 @@ FILLER_ENABLED=true
|
||||
FILLER_DELAY_MS=2500
|
||||
FILLER_GAIN_IDLE=1.0
|
||||
FILLER_GAIN_DUCK=0.15
|
||||
# --- Start filler (turn-start acknowledgment when the reply is late) ---
|
||||
# A second latency mask, on its own mixer channel: if the first audio chunk of
|
||||
# the reply has not reached the mixer within START_FILLER_GO_DELAY ms, one of the
|
||||
# phrases below (picked at random) is played so the agent acknowledges the turn
|
||||
# while the LLM/TTS are still working. If audio arrives in time the cue is
|
||||
# dropped. It shares the filler gain, so it ducks out of the way once the reply
|
||||
# starts.
|
||||
START_FILLER_ENABLED=true
|
||||
# How long (ms) to wait for the first audio chunk of the reply before playing the
|
||||
# start filler (default 1200). Measured from chunk ARRIVAL (not from playback
|
||||
# start, which would also include the TTS_PREBUFFER_MS jitter buffer). Same idea
|
||||
# as FILLER_DELAY_MS, but shorter.
|
||||
START_FILLER_GO_DELAY=500
|
||||
# Phrases spoken by the start filler, ONE PER LINE (a single line with "|"
|
||||
# separators also works). One clip is synthesized per phrase and a RANDOM one is
|
||||
# played when the reply is late, so the cue varies turn to turn. The bank follows
|
||||
# this list: editing it triggers a full re-synthesis at the next restart (no
|
||||
# manual deletion needed), phrases dropped here are deleted on disk, and a
|
||||
# failed synthesis keeps the previous clip. An unchanged list is skipped, so
|
||||
# startup stays fast. Drama-3 style tags ([calm], [sigh], ...) are passed
|
||||
# through to the TTS.
|
||||
START_FILLER_TEXTS="[calm] Un momento...
|
||||
[thoughtful] A ver, veamos...
|
||||
[hesitant] Entonces... echemos un vistazo...
|
||||
[sigh] Vale, ya voy..."
|
||||
# Directory holding the start-filler clips (kept separate from FILLERS_DIR so
|
||||
# they are not added to the round-robin filler bank).
|
||||
START_FILLER_DIR=assets/start_filler
|
||||
# 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
|
||||
# emits audio in windows of codec frames (2048 samples = 46.4 ms each); with the
|
||||
# recommended server setting (stride 4, followup 8, overlap 16, crossfade 512)
|
||||
# the first window is 4 frames = 185.8 ms and the steady windows are 8 frames =
|
||||
# 371.6 ms. The first arrives at the server TTFB (~0.38 s) and the second ~350 ms
|
||||
# later, so ANY value in (186, 557] ms primes on the same second window (TTFA
|
||||
# ~0.73 s); 550 ms takes the whole ~557 ms cushion for free. That cushion absorbs
|
||||
# the drain when several TTS requests share one GPU and produce slower than real
|
||||
# time (measured ~1.5x concurrent vs ~0.94x alone); without it every chunk seam
|
||||
# starves the queue and pauses playback (a micro-gap at each sentence start).
|
||||
# Below ~186 ms playback starts on the first window (TTFA ~= server TTFB) but
|
||||
# leaves almost no cushion. Mid-reply underruns resume as soon as any audio is
|
||||
# queued again (no refill).
|
||||
TTS_PREBUFFER_MS=550
|
||||
# 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.
|
||||
@@ -89,18 +143,98 @@ 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.
|
||||
# Directory of the generated "*.raw" PCM clips (16-bit LE mono, 44.1 kHz). One
|
||||
# clip is synthesized per phrase of BACKCHANNEL_TEXTS at startup.
|
||||
BACKCHANNEL_DIR=assets/backchannel
|
||||
# Phrases spoken by the backchannel, ONE PER LINE (a single line with "|"
|
||||
# separators also works). One clip is synthesized per phrase and a RANDOM one is
|
||||
# played, so the cue varies from turn to turn. The bank follows this list:
|
||||
# editing it triggers a full re-synthesis at the next restart (no manual
|
||||
# deletion needed), phrases dropped here are deleted on disk, and a failed
|
||||
# synthesis keeps the previous clip. An unchanged list is skipped, so startup
|
||||
# stays fast. Drama-3 style tags ([calm], ...) are passed through to the TTS.
|
||||
#
|
||||
# A line may start with an optional "category::" prefix (e.g. "agree::..."); the
|
||||
# scheduler uses it to progress through the turn (an acknowledgment first,
|
||||
# agreement later) and to avoid chaining two cues of the same kind. Lines
|
||||
# without a prefix belong to the default "ack" category.
|
||||
BACKCHANNEL_TEXTS="ack::[calm] Mm-hmm...
|
||||
ack::[attentive] Ajá...
|
||||
agree::[agreeing] Claro...
|
||||
ack::[listening] Ya veo..."
|
||||
# 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_GAIN=0.55
|
||||
# Confirmed speech required (ms) before the first cue may be considered.
|
||||
BACKCHANNEL_MIN_SPEECH_MS=1500
|
||||
# Minimum spacing (ms) between two backchannels. Clamped to >= MIN_SPEECH_MS.
|
||||
# Base spacing (ms) between two cues of the same turn; randomized by ±JITTER/2.
|
||||
BACKCHANNEL_INTERVAL_MS=3000
|
||||
# Maximum backchannels emitted per user turn.
|
||||
BACKCHANNEL_MAX_PER_TURN=2
|
||||
# Timing jitter (ms): delays the first cue by 0..JITTER after MIN_SPEECH_MS and
|
||||
# spreads the spacing, so cues don't land on a fixed cadence.
|
||||
BACKCHANNEL_JITTER_MS=1200
|
||||
# Micro-pause window (ms): the cue lands only while the user is in a short
|
||||
# pause. The reaction DEPTH is drawn at random inside [MIN, MAX] per pause, so
|
||||
# cues don't all land at exactly MIN. Below MIN the user is likely still
|
||||
# mid-word; above MAX (capped below VAD_MIN_SILENCE_MS) the utterance is about
|
||||
# to close.
|
||||
BACKCHANNEL_PAUSE_MIN_MS=96
|
||||
BACKCHANNEL_PAUSE_MAX_MS=260
|
||||
# Probability (0..1) of cueing when a qualifying micro-pause occurs.
|
||||
BACKCHANNEL_PROB=0.65
|
||||
# Random per-cue volume scaling (± fraction) so cues don't sit at a fixed level.
|
||||
BACKCHANNEL_VOLUME_JITTER=0.2
|
||||
# Maximum cues emitted per user turn.
|
||||
BACKCHANNEL_MAX_PER_TURN=3
|
||||
|
||||
# --- Multilingual clip banks (backchannel + filler + start filler) ---
|
||||
# Every clip bank lives in a per-language subdirectory `<dir>/<lang>` named after
|
||||
# the ISO 639-1 code (<dir>/<lang>/, e.g. assets/backchannel/es/), including the
|
||||
# default language LANG_DEFAULT. When the user is detected speaking a different
|
||||
# language, that language's banks are generated on demand into their own
|
||||
# subdirectory and the session switches to them. Each language has its own
|
||||
# directory, so regenerating one never removes the clips of another.
|
||||
LANG_DEFAULT=es
|
||||
# Detect the user's language with a dedicated LLM call (a short auxiliary
|
||||
# request that returns only the ISO code) and switch the banks when it differs
|
||||
# from the active one. Requires the LLM (LLM_ENABLED=true).
|
||||
LANG_DETECT_ENABLED=true
|
||||
# Minimum transcript length (chars) before a sample is sent to the LLM.
|
||||
LANG_MIN_CHARS=12
|
||||
# The first user turn is always checked; afterwards the language is re-checked
|
||||
# once every N turns, so a mid-conversation switch is picked up without paying
|
||||
# for a detection call on every turn.
|
||||
LANG_REDETECT_EVERY=5
|
||||
# Built-in phrase tables cover es/en/it/fr/de/pt. For any other language the
|
||||
# phrase list is generated by the LLM; set false to keep only the tables.
|
||||
LANG_LLM_FALLBACK_ENABLED=true
|
||||
|
||||
# --- Per-session audit log ---
|
||||
# Writes one structured JSONL file per WebSocket session: a configuration
|
||||
# snapshot at the start, every inbound control message and outbound event, the
|
||||
# cue emissions, the language switches, the barge-ins / interrupts and an
|
||||
# event-count summary at the end. Useful for post-mortem analysis and for
|
||||
# tuning latency knobs (FILLER_DELAY_MS, START_FILLER_GO_DELAY, ...). One
|
||||
# <id>.jsonl file per session, written under SESSION_AUDIT_DIR.
|
||||
SESSION_AUDIT_ENABLED=true
|
||||
SESSION_AUDIT_DIR=logs/sessions
|
||||
|
||||
# --- External audio source (URL / radio / YouTube) ---
|
||||
# Injects an audio stream — a direct media URL, an Icecast/Shoutcast radio or a
|
||||
# YouTube link — into the mixer's own "external" channel, mixed under the
|
||||
# agent's voice. Demonstrated in the /mivocero client (URL box + Play/Stop +
|
||||
# volume slider). Decoding is delegated to external tools:
|
||||
# * ffmpeg — decodes direct URLs, radio and HLS streams (required);
|
||||
# * yt-dlp — resolves YouTube URLs to a decodable stream (YouTube only).
|
||||
# A barge-in (interrupt) stops the agent but leaves this background source
|
||||
# playing; the external channel does not count as the agent speaking.
|
||||
# Gain applied to the external channel (kept below 1 so it sits under the voice).
|
||||
EXTERNAL_AUDIO_GAIN=0.6
|
||||
# Override the decoder binaries if they are not on PATH.
|
||||
MEDIA_FFMPEG_BIN=ffmpeg
|
||||
MEDIA_YTDLP_BIN=yt-dlp
|
||||
# Extra yt-dlp arguments (space-separated), e.g. to pass cookies or a JS
|
||||
# runtime: "--cookies /path/cookies.txt". Leave empty normally.
|
||||
MEDIA_YTDLP_ARGS=
|
||||
|
||||
# --- LLM reasoning (OpenAI-compatible chat-completions endpoint) ---
|
||||
# When enabled, the user transcript is sent to the model and the reply is
|
||||
@@ -143,12 +277,35 @@ LLM_DIRECT_ANSWERS=true
|
||||
# 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
|
||||
# prosody and fewer TTS requests: each chunk is a separate request with its own
|
||||
# start-up and its own audio seam, so a larger value cuts the number of seams
|
||||
# (where the TTS queue can starve) per reply.
|
||||
LLM_STREAM_CHUNK_CHARS=240
|
||||
# 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=
|
||||
|
||||
# --- Tool calling (configurable HTTP tools) ---
|
||||
# Lets the model call external HTTP services (weather, home automation, a
|
||||
# webhook, …) before answering. The deployment's vLLM server runs without a
|
||||
# tool parser, so it returns the call as text in the Qwen native
|
||||
# `<tool_call>` format: the engine parses it client-side, executes the HTTP
|
||||
# request and hands the result back to the model (see src/tools.rs). The
|
||||
# tool-call block is never spoken nor shown in the chat box.
|
||||
# Enabled automatically when LLM_TOOLS_FILE points to a valid tool file.
|
||||
LLM_TOOLS_ENABLED=false
|
||||
# JSON file with the tool definitions (name, description, JSON schema, url,
|
||||
# method, headers). See tools.example.json.
|
||||
LLM_TOOLS_FILE=
|
||||
# Maximum tool-call rounds per turn (call → execute → re-prompt). Bounds
|
||||
# runaway loops; the first round is the model's initial reply.
|
||||
LLM_TOOL_MAX_ITERATIONS=4
|
||||
# Timeout of a single tool HTTP request, in seconds.
|
||||
LLM_TOOL_TIMEOUT_SECS=15
|
||||
# Tool responses are truncated to this many characters before being handed
|
||||
# back to the model (keeps the context small).
|
||||
LLM_TOOL_RESULT_MAX_CHARS=2000
|
||||
|
||||
# --- 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
|
||||
|
||||
Reference in New Issue
Block a user