nemo_voice_agent.evaluation.bridge

View as Markdown

Voice Agent Evaluation Bridge

Connects two voice agents via WebSocket and provides:

  • Bidirectional audio routing
  • Response latency measurement
  • Dynamic system prompt updates via RTVI actions
  • Conversation monitoring and metrics

Module Contents

Classes

NameDescription
EvaluationMetricsMetrics collected during evaluation
ResponseLatencySingle response latency measurement
SegmentEntryEntry for segLST format (segment list with timing)
VoiceAgentEvaluationBridgeEvaluation bridge that connects two voice agents via WebSocket

Data

RTVI_BOT_SERVER_MESSAGE

RTVI_BOT_STARTED_SPEAKING

RTVI_BOT_STOPPED_SPEAKING

RTVI_BOT_TRANSCRIPTION

RTVI_BOT_TTS_TEXT

STOP_REASON_EXIT

STOP_REASON_TIMEOUT

_RTVI_TYPES_ALREADY_TAGGED

API

class nemo_voice_agent.evaluation.bridge.EvaluationMetrics(
turns: list = list(),
latencies: typing.List[nemo_voice_agent.evaluation.bridge.ResponseLatency] = list(),
start_time: datetime.datetime = None,
end_time: datetime.datetime = None,
log_entries: typing.List[typing.Tuple[float, str]] = list(),
user_last_audio_time: typing.Optional[float] = None,
agent_last_audio_time: typing.Optional[float] = None,
waiting_for_agent_response: bool = False,
last_user_transcript: str = '',
user_current_transcript: str = '',
agent_current_transcript: str = '',
thread_start_timestamp: typing.Optional[float] = None,
segments: typing.List[nemo_voice_agent.evaluation.bridge.SegmentEntry] = list(),
current_user_segment: typing.Optional[nemo_voice_agent.evaluation.bridge.SegmentEntry] = None,
current_agent_segment: typing.Optional[nemo_voice_agent.evaluation.bridge.SegmentEntry] = None,
agent_final_response: typing.List[str] = list(),
agent_final_response_time: typing.List[float] = list()
)
Dataclass

Metrics collected during evaluation

agent_current_transcript
str = ''
agent_final_response
List[str] = field(default_factory=list)
agent_final_response_time
List[float] = field(default_factory=list)
agent_last_audio_time
Optional[float] = None
current_agent_segment
Optional[SegmentEntry] = None
current_user_segment
Optional[SegmentEntry] = None
end_time
datetime = None
last_user_transcript
str = ''
latencies
List[ResponseLatency] = field(default_factory=list)
log_entries
List[Tuple[float, str]] = field(default_factory=list)
segments
List[SegmentEntry] = field(default_factory=list)
start_time
datetime = None
thread_start_timestamp
Optional[float] = None
turns
list = field(default_factory=list)
user_current_transcript
str = ''
user_last_audio_time
Optional[float] = None
waiting_for_agent_response
bool = False
nemo_voice_agent.evaluation.bridge.EvaluationMetrics.get_latency_stats()

Calculate latency statistics

nemo_voice_agent.evaluation.bridge.EvaluationMetrics.reset()

Reset all metrics to prepare for a new scenario

class nemo_voice_agent.evaluation.bridge.ResponseLatency(
user_stop_time: float,
agent_start_time: float,
latency_ms: float,
user_transcript: str = '',
agent_transcript: str = ''
)
Dataclass

Single response latency measurement

agent_start_time
float
agent_transcript
str = ''
latency_ms
float
user_stop_time
float
user_transcript
str = ''
class nemo_voice_agent.evaluation.bridge.SegmentEntry(
start_time: float,
end_time: float,
speaker: str,
transcript: str
)
Dataclass

Entry for segLST format (segment list with timing)

end_time
float
speaker
str
start_time
float
transcript
str
class nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge(
user_url: str,
agent_url: str,
output_dir: typing.Optional[str] = None,
scenario_name: typing.Optional[str] = None,
user_output_sample_rate: int = 24000,
agent_output_sample_rate: int = 24000,
user_input_sample_rate: int = 16000,
agent_input_sample_rate: int = 16000,
output_sample_rate: int = 16000,
audio_chunk_in_seconds: float = 0.016,
use_burst_mode: bool = False,
burst_size_range: typing.Tuple[int, int] = (3, 8),
burst_delay_ms: int = 0,
grace_period: float = 1.0,
turn_start_offset_secs: float = -0.0,
turn_end_offset_secs: float = -0.3,
noise_config: typing.Optional[nemo_voice_agent.utils.audio.NoiseConfig] = None,
log_level: str = 'DEBUG'
)

Evaluation bridge that connects two voice agents via WebSocket and provides control through RTVI actions.

Key features:

  • Routes audio bidirectionally between agents
  • Monitors transcriptions and metrics
  • Measures response latency by tracking audio frames
  • Can send RTVI control messages to update prompts
  • Works with distributed agents
agent_to_user_queue
= queue.Queue()
exit_settle_delay
= 0.5
final_response_file
= 'final_agent_response.json'
final_scenario_db_hash_file
= 'final_scenario_db_hash.txt'
metrics
= EvaluationMetrics()
scenario_summary
Optional[dict] = None
sent_to_agent_chunks
= []
sent_to_user_chunks
= []
serializer
= ProtobufFrameSerializer()
shadow_state
Optional[dict] = None
shadow_tool_map
Dict[str, Any] = {}
stop_event
= threading.Event()
sync_enabled
bool = False
sync_lock
= asyncio.Lock()
threads
= []
token_usage
dict = self._fresh_token_usage()
user_to_agent_queue
= queue.Queue()
nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._apply_initialization(
scenario,
user_shared_state_init: dict,
agent_shared_state_init: dict
) -> None
async

Send apply_initialization to BOTH bots — always, even with no init actions.

Bot-side dispatch via the apply_initialization RTVI action. The handler does three things per bot:

  1. Merge shared_state_init JSON into the bot’s shared_state (preserving runtime sentinels stashed by update_system_prompt).
  2. If db_path is in the merged state, resolve it against EVAL_DATA_ROOT and replace with the loaded db dict.
  3. Dispatch each per-side init function record (filtered by side) against the now-loaded db.

Always called once per bot, even when scenario.initialization_actions is empty — steps 1 and 2 (state merge + DB load) must run for every tau2 scenario regardless. Single-side domains (eva / airline / retail) whose setup_shared_state populates db_path rely on this call to trigger the DB load. The bot’s handler is fast (~tens of ms) when actions list is empty.

Failure handling: any per-bot success: false response (invalid JSON, missing DB file, missing init function in the bot’s registry, dispatcher exception) raises RuntimeError so the calling prepare_for_scenario aborts before the conversation starts. Partial seeding produces noisy / unscoreable runs.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._build_conversation_log()

Build conversation log entries from finalized segments with computed latencies.

Called after all segments are finalized so that latency calculation has access to all user and agent segments. For each agent segment, latency is computed as: agent.start_time - previous_user.end_time Positive = normal response delay, negative = agent interrupted/barged in early.

Applies turn_start_offset_secs and turn_end_offset_secs to match seglst timestamps.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._finalize_speaker_turn(
speaker: str,
timestamp: float
) -> typing.Optional[nemo_voice_agent.evaluation.bridge.SegmentEntry]

Finalize the current in-progress turn for the given speaker.

Sets end_time, assigns transcript (or “[INTERRUPTED]” if no TTS text was received), appends the segment to self.metrics.segments, and clears accumulation state.

Parameters:

speaker
str

“user” or “agent”

timestamp
float

Absolute timestamp (asyncio loop time)

Returns: Optional[SegmentEntry]

The finalized SegmentEntry, or None if no segment was in progress.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._format_turn_log(
role: str,
text: str,
start_time: float,
end_time: float,
latency_ms: float = None
) -> str

Format a turn entry for the conversation log.

Parameters:

role
str

“user” or “agent”

text
str

Transcript text

start_time
float

Turn start time (relative to scenario start)

end_time
float

Turn end time (relative to scenario start)

latency_ms
float" default="None

Optional response latency in milliseconds

Returns: str

Formatted log entry string

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._fresh_token_usage() -> dict
staticmethod
nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._get_relative_time(
timestamp: float
) -> float

Get time relative to scenario start (thread start time).

Parameters:

timestamp
float

Absolute timestamp (asyncio loop time)

Returns: float

Time in seconds relative to thread_start_timestamp, or 0 if not set

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._log_rtvi_event(
side: str,
message_type: str,
data: dict
) -> None

Emit a uniform side-tagged DEBUG log line for an RTVI event.

Each monitor (_monitor_user_message / _monitor_agent_message) is bound to one side by construction, so we know which side emitted the event without time-correlation. This helper writes a one-line tag plus expanded payload lines for the message types that carry analytically useful structured data (TTFB values, token counts, transcription text, RTVI action names).

Skipped types (_RTVI_TYPES_ALREADY_TAGGED): the monitors already emit dedicated side-tagged lines like [AGENT TTS] <text> for these, so adding [AGENT EVENT] type=bot-tts-text on top would just duplicate. Their expanded payload (the TTS text) is already in the existing line.

Skipping is by event-tag emission only — the underlying RTVI message still flows through pipecat’s ProtobufFrameSerializer:deserialize DEBUG log, so nothing is lost from the bridge log.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._monitor_agent_message(
frame
)
async

Monitor agent messages for timing and transcripts.

Turn lifecycle: BOT_STARTED_SPEAKING → BOT_TTS_TEXT (accumulate) → BOT_STOPPED_SPEAKING (finalize). Latency is measured from user’s last audio to agent’s first audio frame.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._monitor_user_message(
frame
)
async

Monitor user messages for timing and transcripts.

Turn lifecycle: BOT_STARTED_SPEAKING → BOT_TTS_TEXT (accumulate) → BOT_STOPPED_SPEAKING (finalize).

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._propagate_cross_side_sync(
action: dict,
source_side: str
) -> None
async

Replay one action onto the shadow DBs, run scenario.sync_state, dispatch deltas.

Called from _monitor_agent_message / _monitor_user_message when an action-applied RTVI server message arrives. source_side is which side’s monitor saw it.

No-op when sync_enabled is False (single-side scenarios).

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._receive_agent_to_queue(
agent_ws,
duration: float
)
async

Receive audio from agent WebSocket and put into queue for user thread.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._receive_to_queue(
ws: websockets.WebSocketClientProtocol,
duration: float,
direction: str,
queue: queue.Queue,
monitor_func: typing.Callable
)
async

Receive audio from websocket and put into queue.

Parameters:

ws
websockets.WebSocketClientProtocol

Source websocket to receive from

duration
float

How long to run the receive loop in seconds

direction
str

For logging (e.g., “USER→AGENT”, “AGENT→USER”)

queue
queue.Queue

Thread-safe queue to put audio chunks into

monitor_func
Callable

Async monitoring function for metrics (e.g., _monitor_user_message)

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._receive_user_to_queue(
user_ws,
duration: float
)
async

Receive audio from user WebSocket and put into queue for agent thread.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._resample_audio(
audio: numpy.ndarray,
from_rate: int,
to_rate: int
) -> numpy.ndarray
staticmethod

Resample audio array using soxr. Returns int16 array.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._retrieve_context_history(
ws
) -> dict
async

Retrieve the context history from the WebSocket. First send a message to the ws to trigger the get_context_history RTVI action, then wait for the response. Args: ws: WebSocket connection Returns: context_history: context history as a dictionary with two keys: context and logs, where context the LLM context history, and logs is the bot server logs.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._retrieve_scenario_summary(
ws,
include_db: bool = False
) -> dict
async

Retrieve the scenario summary from the bot via the get_scenario_summary RTVI action. Mirrors _retrieve_context_history.

Parameters:

ws

WebSocket connection to the agent bot.

include_db
bool" default="False

When True, ask the bot to inline the db dict alongside the hash. Set by the runner via Scenario.db_state_assertions (predicate evaluation needs the actual DB, not just a hash). Off by default to preserve the existing hash-out behavior for retail (whose 7 MB DB would exceed pipecat’s 1 MB WS frame cap).

Returns: dict

Dict with at minimum {"actions": list, "db_hash": str|None}.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_audio_log()

Save final sent audio chunks to disk as stereo WAV for debugging.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_bot_server_history(
output_dir: typing.Union[str, pathlib.Path],
context_history: dict,
role: str = ''
)

Save the bot server context history to a JSON file under the output directory.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_conversation_log()

Build and write conversation log entries sorted by start time, with computed latencies.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_final_response()

Save the agent’s final response to a JSON file under the output directory.

Two sources, in priority order:

  1. Pull (self.scenario_summary["actions"]) — the bridge-pulled auto-aggregated action list. Used when the bot registered the get_scenario_summary action (post-commit-3 bots) and returned a non-empty actions list.
  2. Push (self.metrics.agent_final_response) — <final_response> text messages captured during the conversation. Used by domains that still have an LLM-callable summary tool (restaurant / customer_service / qa) or as a fallback when pull returned empty.

Output is always list-wrapped ([{"actions": ...}]) for shape compat with the existing strict comparator and downstream consumers.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_scenario_db()

Save the post-run scenario DB hash(es) to final_scenario_db_hash.txt.

Sourced from the bridge-pulled scenario_summary["db_hash"] (and ["user_db_hash"] for telecom). Skipped if no pull happened (legacy bots) or the hash is None. Used by the runner’s DB-state matching when scenario.expected_scenario_db is set — the runner compares the expected-DB hash (computed in-process from its own gold replay) against the bot’s reported hash.

Hash-only design: the full DB stays on the bot server. See create_get_scenario_summary_action for the rationale (WebSocket frame size limit; tau2’s DB is 7 MB while pipecat’s default frame cap is 1 MB).

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_seglst()

Save segLST transcript file with offset-adjusted timestamps.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._save_user_agent_history()

Save the user and agent context history to a JSON file under the output directory.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_agent_to_user(
user_ws,
audio_stream: nemo_voice_agent.utils.audio.AudioStream,
duration: int
)
async

Get audio from queue, process through AudioStream, send to user WebSocket.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_apply_initialization(
ws,
side_label: str,
domain: str,
shared_state_init: dict,
actions: typing.List[dict]
) -> None
async

Send one apply_initialization action and wait for the result.

side_label is the bot label ("agent" or "user") used only in log lines and error messages — the bot itself doesn’t need to know which side it is, since each action in the payload already carries its own side field that the dispatcher routes by.

Raises:

  • RuntimeError: if the bot returns success: false or the request times out. The caller (_apply_initialization) propagates this up so prepare_for_scenario aborts cleanly.
nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_apply_sync_delta(
ws,
side_label: str,
domain: str,
delta: dict
) -> None
async

Send a single apply_sync_delta RTVI action to a bot.

Mirrors _send_apply_initialization: builds an action message with a unique id, awaits the response, logs success or failure. Failures are warnings — sync drift is recoverable as long as the next propagation cycle eventually catches up.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_audio_stream(
audio_stream: nemo_voice_agent.utils.audio.AudioStream,
dest_ws: websockets.WebSocketClientProtocol,
direction: str,
duration: int,
source_queue: queue.Queue,
sent_chunks_list: typing.List[bytes]
)
async

Send audio stream at fixed intervals from AudioStream with duration and grace period.

Parameters:

audio_stream
AudioStream

AudioStream containing buffered and resampled audio

dest_ws
websockets.WebSocketClientProtocol

Destination websocket to send to

direction
str

For logging (e.g., “USER→AGENT”, “AGENT→USER”)

duration
int

How long to run the send loop in seconds

source_queue
queue.Queue

Queue to retrieve audio chunks from

sent_chunks_list
List[bytes]

List to append sent chunks to for tracking

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_client_ready(
ws
)
async

Send RTVI client-ready handshake and wait for bot-ready

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_reset_action(
ws,
agent_name: str
)
async

Send RTVI reset action to clear conversation history.

Parameters:

ws

WebSocket connection

agent_name
str

Name of agent (for logging)

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._send_user_to_agent(
agent_ws,
audio_stream: nemo_voice_agent.utils.audio.AudioStream,
duration: int
)
async

Get audio from queue, process through AudioStream, send to agent WebSocket.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge._setup_cross_side_sync(
scenario
) -> None
async

Prepare shadow DBs + tool map for cross-side state propagation.

Called from prepare_for_scenario once per scenario, after _apply_initialization so the bot-side live state is already at its post-init starting point. We mirror that here by replaying the same init actions onto the shadow DBs, then run a one-shot sync_state to propagate any cross-side state that should be coherent at conversation start (e.g. agent-side set_data_usage(15.1) flipping user-side surroundings.mobile_data_usage_exceeded to True).

No-op when the scenario’s sync_state is the inherited default (single-side domains).

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.agent_websocket_thread(
duration: int
)

Thread 2: Handle all agent WebSocket traffic (bidirectional).

This thread:

  • Gets user audio from user_to_agent_queue
  • Sends user audio to agent WebSocket
  • Receives audio from agent WebSocket
  • Puts agent audio into agent_to_user_queue for user thread

Parameters:

duration
int

How long to run (seconds)

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.connect(
max_retries: int = 5,
retry_delay: float = 1.0
)
async

Connect to both user and agent with retry logic

Parameters:

max_retries
int" default="5

Maximum number of connection attempts per endpoint

retry_delay
float" default="1.0

Initial delay between retries (doubles each retry)

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.disconnect(
print_stats: bool = False
)
async

Disconnect from both user and agent.

Parameters:

print_stats
bool" default="False

If True, print final latency statistics (default: True) Set to False when disconnecting during scenario resets

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.get_metrics()

Get evaluation metrics

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.init_output_dir(
output_dir: str,
scenario_name: typing.Optional[str] = None,
log_level: str = 'DEBUG'
)

Initialize the output directory and all derived log/audio file paths.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.prepare_for_scenario(
scenario,
output_dir: str,
log_level: str = 'DEBUG'
)
async

Prepare the bridge for a scenario.

Parameters:

scenario

A Scenario instance. The bridge calls methods on it directly (get_user_prompt, get_agent_prompt, setup_shared_state, initialization_actions, sync_state, etc.) — no intermediate dict serialization step. Single source of truth.

output_dir
str

Per-scenario output directory.

log_level
str" default="'DEBUG'

Pipecat log level for the bot servers.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.reset()
async

Reset metrics and both agents’ conversation history

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.reset_agent()
async

Reset agent’s conversation history. Useful to clear context between evaluation scenarios.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.reset_user()
async

Reset user’s conversation history. Useful to clear context between evaluation scenarios.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.run_scenario(
duration: int = 300
)
async

Route audio between agents and monitor conversation. Uses separate threads per WebSocket to eliminate asyncio contention.

Parameters:

duration
int" default="300

Duration of the evaluation in seconds

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.send_text_to_agent(
text: str
)
async

Send a text message to the agent agent to trigger conversation.

Parameters:

text
str

Text to send to agent agent’s LLM

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.send_text_to_user(
text: str
)
async

Send a text message to the user agent to trigger conversation.

Parameters:

text
str

Text to send to user agent’s LLM

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.set_noise_config(
noise_config: typing.Optional[typing.Union[nemo_voice_agent.utils.audio.NoiseConfig, dict]] = None
)

Set the noise configuration

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.update_agent_prompt(
prompt: str,
tools: str,
auto_reset: bool = False,
add_suffix: bool = False,
tool_domain: str = 'default'
)
async

Update agent’s system prompt via RTVI action.

Scenario fixture data (db_path, custom keys from Scenario.setup_shared_state) is NOT sent here — it flows via the subsequent apply_initialization call instead.

Parameters:

prompt
str

New system prompt text

tools
str

New tools in json string format

auto_reset
bool" default="False

If True, also sends reset action after updating prompt

add_suffix
bool" default="False

If True, add previously configured system prompt suffix to the new prompt

tool_domain
str" default="'default'

Registry namespace the bot server should use to look up tools by name (e.g., "tau2_airline"). Falls back to "default" per-tool if the name isn’t in the specified domain (with a warning logged bot-side).

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.update_user_prompt(
prompt: str,
tools: str,
auto_reset: bool = False,
add_suffix: bool = False,
tool_domain: str = 'default'
)
async

Update user’s system prompt via RTVI action.

Scenario fixture data (db_path, custom keys from Scenario.setup_shared_state) is NOT sent here — it flows via the subsequent apply_initialization call instead.

Parameters:

prompt
str

New system prompt text

tools
str

New tools in json string format

auto_reset
bool" default="False

If True, also sends reset action after updating prompt

add_suffix
bool" default="False

If True, add previously configured system prompt suffix to the new prompt

tool_domain
str" default="'default'

Registry namespace the bot server should use to look up tools by name. Stashed on bot-side shared_state["__tool_domain__"] for write tools to read when emitting action-applied events.

nemo_voice_agent.evaluation.bridge.VoiceAgentEvaluationBridge.user_websocket_thread(
duration: int
)

Thread 1: Handle all user WebSocket traffic (bidirectional).

This thread:

  • Receives audio from user WebSocket
  • Puts user audio into user_to_agent_queue for agent thread
  • Gets agent audio from agent_to_user_queue
  • Sends agent audio to user WebSocket

Parameters:

duration
int

How long to run (seconds)

nemo_voice_agent.evaluation.bridge.RTVI_BOT_SERVER_MESSAGE = RTVI.ServerMessage(data=(RTVI.TextMessageData(text=''))).type
nemo_voice_agent.evaluation.bridge.RTVI_BOT_STARTED_SPEAKING = RTVI.BotStartedSpeakingMessage().type
nemo_voice_agent.evaluation.bridge.RTVI_BOT_STOPPED_SPEAKING = RTVI.BotStoppedSpeakingMessage().type
nemo_voice_agent.evaluation.bridge.RTVI_BOT_TRANSCRIPTION = RTVI.BotTranscriptionMessage(data=(RTVI.TextMessageData(text=''))).type
nemo_voice_agent.evaluation.bridge.RTVI_BOT_TTS_TEXT = RTVI.BotTTSTextMessage(data=(RTVI.TextMessageData(text=''))).type
nemo_voice_agent.evaluation.bridge.STOP_REASON_EXIT = '[EXIT]'
nemo_voice_agent.evaluation.bridge.STOP_REASON_TIMEOUT = '[TIMEOUT]'
nemo_voice_agent.evaluation.bridge._RTVI_TYPES_ALREADY_TAGGED = frozenset({RTVI_BOT_STARTED_SPEAKING, RTVI_BOT_TTS_TEXT, RTVI_BOT_STOPPED_SPEAKI...