Audio Capture and Logging
NeMo Labs Voice Agent writes two independent outputs. Per-session audio and transcript capture is off by default. The pipeline also emits a rotating text log at runtime. This page explains how to enable audio capture and interpret both outputs.
Enable Audio Capture
Audio capture is controlled by two keys in the transport: block of the top-level server config
(examples/generic_voice_agent/server/server_configs/default.yaml, and the same block in
default_nvidia.yaml):
build_audio_logger in nemo_voice_agent/pipecat/services/nemo/builders.py reads those two keys.
When record_audio_data is false it returns None. Every downstream service—speech-to-text (STT),
text-to-speech (TTS), turn-taking, and diarization—is then constructed with audio_logger=None, so capture
adds no runtime work.
The session ID is generated at server start, not per client connection:
session_YYYYMMDD_HHMMSS. Because the server keeps one pipeline alive across reconnects, as described in
Server Config, a client that disconnects and reconnects keeps appending to the
same session directory.
audio_logs/, audio_logs_user/, and audio_logs_agent/ are gitignored.
What Lands on Disk
Each capture session produces per-speaker audio and metadata plus a whole-session stereo mixdown.
The NNNNN prefix is a per-speaker counter (the user and agent counters are separate), and HHMMSS is
wall-clock time at save. User turns get a 0.8-second pre-roll prepended, clamped so a turn never
overlaps the previous entry’s end time.
Metadata Fields
Both sides share base_name, counter, turn_index, speaker, timestamp (ISO 8601),
start_time / end_time (float seconds from the first audio frame of the session),
audio_file, sample_rate, num_channels, and audio_duration_sec. Beyond that:
session_metadata.json holds session_id, start_time, last_updated, a flat user_entries
list, and an agent_entries list where each element is itself the list of segments for one agent
turn. finalize_session adds end_time, total_user_entries, total_agent_segments, and
total_agent_turns.
How Capture Is Wired
AudioLogger (nemo_voice_agent/pipecat/services/nemo/audio_logger.py) is a plain object passed
into the services by the builders. Each service pushes data into it at the right moment.
Two limitations worth knowing:
build_audio_loggerpasses only the directory, session ID, and enabled flag.AudioLogger’s other constructor arguments (user sample rate, pre-roll seconds, rounding precision) are not exposed through YAML, so their defaults always apply. Change them by constructingAudioLoggeryourself. Refer to Builders.- The
AudioLoggerdocstring records a known issue withconversation_stereo.wav: the two channels need roughly a -0.8 s offset applied to sound in sync. The per-turn WAV files are unaffected.
Quick check after a session:
Server Log File
Logging is configured by setup_logging in nemo_voice_agent/utils/misc.py, which installs a
colorized stderr sink plus a file sink with rotation="1 day" at DEBUG level. Each day, loguru
rolls the active file aside into a timestamped sibling, so when debugging a failure check the
newest bot_server.*.log and not only bot_server.log.
setup_rotating_log wraps that with a rename-or-delete step for a pre-existing file: it either
removes the old log or renames it to bot_server.<YYYYmmdd_HHMMSS>.log before installing the sinks.
Gotcha: the example server (examples/generic_voice_agent/server/server.py) calls
setup_logging() with no arguments, so it always writes bot_server.log at DEBUG regardless of
the server.log_file / server.log_level values in default.yaml. Those keys take effect for the
evaluation bot servers, which resolve them through resolve_log_file_path and setup_rotating_log.
The call is repeated after service construction because model libraries reconfigure loguru during
import.
Evaluation Runs
The evaluation role configs (evaluation/server_configs/agent.yaml and user.yaml) also ship with
record_audio_data: false, and give each role its own audio_log_dir (./audio_logs_agent,
./audio_logs_user) so the two bots do not collide. Independently of this, the bridge writes
conversation_log.wav (stereo), conversation_log.txt, and conversation_log.seglst.json into each
scenario’s output directory. For output details, refer to
Evaluation Results.
Related Pages
Use these pages to continue configuring or inspecting the runtime:
- Server Config — the rest of the top-level YAML.
- Configuration — how
default.yamland the model sub-configs merge. - Config Schema — full key reference.
- Troubleshooting — reading the logs when a session misbehaves.