Pipecat target

The pipecat target tests a Pipecat agent through its websocket
transport with the protobuf frame serializer, the transport most Pipecat bots expose for
browser and native clients. tamesu connects as the client: in text mode it types each user
turn and reads the bot’s text; in audio mode it speaks the turn as audio frames and reads the
bot’s voice, its transcript and the RTVI events around them.
targets:
bot:
type: pipecat
url: wss://bot.example.com/ws # the websocket of the transport
headers: { Authorization: "Bearer {{secrets.BOT_TOKEN}}" }
mode: text # text | audio
sample_rate: 16000 # audio mode: the transport's rate
idle: 2s # end of turn when the bot stops without saying so
turn_timeout: 60s
tool_results: # answers to client-side function calls
lookup_policy: { topic: "{{args.topic}}", window_days: 30 }
The bot needs an RTVI observer in its pipeline (RTVIObserver), which Pipecat’s starter
templates include: it is what tells tamesu when the bot starts and stops talking and carries the
bot’s words.
How a turn works
- tamesu connects, sends
client-readyand waits briefly forbot-ready; a transport that never sends it is given up on after 3 s, not failed. - Text mode: the user turn is a
send-textmessage (run_immediately: true,audio_response: false). The bot’sbot-llm-textdeltas make the turn’s text (elsebot-tts-textorbot-transcription), andbot-llm-stoppedends it. Audio mode: the turn is synthesised withspeech.tts, streamed as 20 ms frames atsample_ratein real time with half a second of silence after it, so the bot’s voice activity detector hears the end. The bot’s audio frames go on the right track ofaudio.wav, itsbot-tts-textorbot-transcriptionis the turn’s text (its audio is transcribed withspeech.sttwhen it sends neither), andbot-stopped-speakingends the turn. - Without a stop message the turn ends after
idlewith no further sign of the bot;turn_timeoutbounds the whole turn. - Function calls are recorded as tool calls from
llm-function-call-in-progress(functions the bot runs itself) andllm-function-call(functions it asks the client to run). A client-side function listed undertool_resultsis answered withllm-function-call-resultand the turn goes on with the bot’s reaction; up to five answers per turn.
A bot that says goodbye does not end the session on this transport, so rely on
scenario.stop_when and max_turns.
Keys
| Key | Meaning |
|---|---|
url | The transport’s websocket endpoint. Templates apply. |
headers | Handshake headers; credentials as {{secrets.NAME}}. |
mode | text (default) or audio; a test’s mode or --mode overrides it. Audio mode needs speech.tts (and speech.stt for bots that send no text) in tamesu.yaml. |
sample_rate | Audio mode: the rate of the frames sent and of audio.wav (default 16000). The bot’s frames are resampled to it when they differ. |
idle | Silence after the bot’s last message or audio that ends a turn when no stop message arrives (default 2s). |
turn_timeout | The wait for the end of a turn, and the connection (default 60s). |
tool_results | Answers to client-side function calls, by name: any YAML value, string leaves may use {{args.<key>}}. |
fuzz_tools (on a test) | Replaces the named tools’ answers for that test: error, empty, malformed, hostile, delay, … See when the tools fail. |
Metrics
| Metric | Definition |
|---|---|
turn_latency_ms (_p50, _p95, _max) | the turn was sent → the bot stopped |
time_to_first_token_ms | the turn was sent → the first text or audio from the bot |
time_to_first_audio_ms (_p50, _p95, _max) | audio mode: the caller’s last frame → the bot’s first |
agent_speech_ms, user_speech_ms | audio mode: how much each side spoke |
turns | the number of bot turns |
ws_messages_received | the frames and messages of the session |
Timestamps are taken around the socket, never from a model.
Assertions that apply
Every assertion of Concepts except status, json_path and the
phone ones; tool_called sees the bot’s function calls.
Artifacts
Text mode leaves the transcript and result.json like any conversational test, with every RTVI
message of each turn in the turn’s raw payload. Audio mode adds audio.wav, a stereo file at
sample_rate with the simulated user on the left and the bot on the right, which the HTML report
plays.
Barge-in
In audio mode, behaviors.interrupt_probability on the persona makes the caller talk over the
bot: tamesu stops listening partway through a bot turn (after 0.6 to 2 seconds of its audio, at
random, repeatable with the test’s seed) and speaks its next line while the bot’s audio is
still playing. A Pipecat pipeline with an interruption strategy answers with an interruption
frame or bot-interrupted (and bot-stopped-speaking); interruption_stop_ms is the time from
the caller’s first word to that signal, or, when the bot never yields, until the audio it had
already sent would have played out. interruptions counts them; the cut-short turn is marked
interrupted, and the events read interrupting, interruption, bot_interrupted and
interruption_stopped with the measured time. An interrupt_missed event means the bot had
finished before the caller got to speak.
persona:
name: Marta
behaviors: { interrupt_probability: 0.5 }
assert:
- metric: { name: interruption_stop_ms_p95, lt: 800 }