Skip to main content

Agent testing

Reference for lk agent debugger and lk agent simulate, the LiveKit CLI commands for testing agents.

Overview

Use these commands to test your agent without a person at the microphone:

  • lk agent debugger lets a script or coding agent converse with your local agent one turn at a time, in text or audio.
  • lk agent simulate runs Agent Simulations: whole conversations with LLM-driven simulated users, scored by a judge.

To talk to your agent yourself, use lk agent console. To install the CLI, see Install the CLI.

Agent debugger

Run your agent locally and drive a conversation with it from a script or coding agent. For a guide, see CLI Agent Debugger. lk agent dbg is an alias. Requires LiveKit CLI v2.19.0 or later.

Typical workflow

Run the commands from your agent's project directory:

# Start the agent and print its greeting, if any
lk agent debugger start
# Send user turns
lk agent debugger say "Hi, what can you do?"
lk agent debugger say "Book me a table for two tonight"
# Inspect the session between turns
lk agent debugger logs --last 40
lk agent debugger chat-history
# Pick up a code change with a fresh conversation
lk agent debugger restart
# Stop the agent and print a closing summary with the conversation
lk agent debugger stop --chat-history

Run restart after every code change; a running session keeps the code it started with.

Session modes

By default, a session is text: the agent runs with STT and TTS off, so a turn costs only your LLM and tool usage.

Start with --audio to speak each say line into the agent's microphone input using LiveKit Inference TTS. The agent runs its full audio pipeline, which catches problems text skips, such as misheard names, spelled-out digits, and endpointing. The microphone input is a continuous realtime stream with silence between turns, so endpointing behaves as it does on a call.

In audio mode, a turn lasts until the agent has transcribed the speech, responded, and then stayed silent for a few seconds. say shows what the agent transcribed, with the sent text beneath it when the two differ, for example (sent: "My order number is 4 8 1 5."). A turn the agent hears but never answers is reported as silent.

Audio-mode TTS is billed to your LiveKit Cloud project, which the debugger resolves like other lk commands: --project, LIVEKIT_* environment variables, livekit.toml, or the default project. It passes those credentials to the session under separate names, so the agent still reads its own from .env. The mode lasts for the whole session, including across restart.

Sessions

A session is one agent process and its conversation. The debugger runs one session per local port (default 8775), so subcommands can run from different shells. To run several agents side by side, give each its own port with --port or LK_SESSION_PORT, and pass that port to every subcommand.

A session stops after 30 minutes without a command. Change this with start --idle-timeout.

Entrypoint detection

The debugger finds your agent like the other local development commands. The agent reads credentials from its own .env file.

Commands

Every subcommand accepts --port to select the session.

start

Launch the agent in the background and return once it's ready. Prints the agent's greeting, if any, and a summary with the active agent, its tools, and the log path.

lk agent debugger start [options] [entrypoint] [-- runtime-args]

Options for debugger start:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --idle-timeout DURATION: Stop the session after DURATION without any command. Takes a duration with a unit, such as 30m, 2h, or 90s. Use 0 to keep it running until stop. Default: 30m.
  • --audio: Speak each turn into the agent's microphone input instead of sending text, running its full audio pipeline. Uses LiveKit Inference TTS on your connected LiveKit Cloud project.
  • --json (alias -j): Print the greeting events and session status as JSON.

For --audio, see Session modes.

If a session is already running on the port, start fails. Use restart to replace it, or --port to run another.

lk agent debugger start src/my_agent.py --audio

say

Send one user turn and print everything the agent does until it completes: tool calls and results, handoffs, config changes, errors, and the reply. Anything the agent said since the previous turn prints first, labeled (before this turn).

lk agent debugger say [options] <text>

Options for debugger say:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print the turn as one JSON document.
  • --metrics: Show time to first token for each reply and how long the turn took.
  • --timeout DURATION: Stop waiting for the agent's reply after DURATION. Takes a duration with a unit, such as 2m or 90s. Default: 2m.
  • --logs: Show the agent's log lines emitted during the turn, beneath the step they belong to. Useful for finding a tool's traceback.

For the --json format, see JSON output.

You can also pipe the text on stdin:

echo "Book me a table for two" | lk agent debugger say

chat-history

Print the conversation so far from the agent's chat history, which is exactly what the LLM has seen. Works during a turn.

lk agent debugger chat-history [options]
# or
lk agent debugger transcript [options]

Options for debugger chat-history/debugger transcript:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print the chat history as one JSON document.
  • --metrics: Show time to first token for each reply and how long the turn took.

events

Stream the session's events as a timestamped feed until interrupted, including agent state transitions. It only observes, so it works alongside say from another shell.

lk agent debugger events [options]

Options for debugger events:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print one JSON object per event, one per line (NDJSON).
  • --last N (alias -n): Print the last N events before streaming new ones. Use 0 for every event kept, up to 500. Default: 50.
  • --logs: Include the agent's log lines in the stream.

status

Show whether a session is running, with its entrypoint, mode, active agent and tools, turn count, and log path.

lk agent debugger status [options]

Options for debugger status:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print the session status as JSON, including the active agent's full instructions. With no session running, prints "running": false and exits 1.

With --json, it also includes the active agent's full instructions. When no session is running, it prints "running": false and exits non-zero.

logs

Print the agent process's recent output. For a single turn's lines, use say --logs.

lk agent debugger logs [options]

Options for debugger logs:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --last N (alias -n): Print the last N lines. Use 0 for the whole log. Default: 50.
  • --follow (alias -f): Keep streaming new lines until interrupted.

restart

Relaunch the agent with the same entrypoint and port, picking up code changes and starting a fresh conversation.

lk agent debugger restart [options]

Options for debugger restart:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print the greeting events and session status as JSON, like start.

stop

Shut the agent down and print a summary of the session.

lk agent debugger stop [options]

Options for debugger stop:

  • --port PORT: Local PORT for the session. Default: 8775. Also read from LK_SESSION_PORT.
  • --json (alias -j): Print the summary, conversation, and logs in one JSON document.
  • --metrics: Show latency metrics for each turn of the conversation. Requires --chat-history.
  • --chat-history: Also print the full conversation.
  • --logs: Also print the agent process's entire log.

JSON output

Add --json to start, say, chat-history, events, status, restart, or stop for machine-readable output. A say turn prints one object:

{
"text": "Book me a table for two tonight",
"heard": "Book me a table for two tonight",
"events": [
{
"type": "tool_call",
"name": "check_availability",
"arguments": "{\"party_size\": 2, \"date\": \"2026-09-23\"}",
"output": "{\"times\": [\"19:00\", \"20:30\"]}"
},
{
"type": "message",
"role": "assistant",
"text": "I have tables at 7 and 8:30 tonight. Which works for you?"
}
],
"reply": "I have tables at 7 and 8:30 tonight. Which works for you?",
"duration_ms": 2140
}

The turn object has these fields:

  • text: The user turn you sent.
  • heard: What the agent heard. Same as text in text mode; the transcript in audio mode.
  • events: Everything the agent did during the turn, in order.
  • reply: The agent's reply text.
  • duration_ms: How long the turn took.
  • silent: true when the agent produced no output. Omitted otherwise.
  • error: The error, when the turn failed or timed out. Omitted otherwise.

Each event has a type and the fields that apply to it:

TypeFields
messagerole (user or assistant), text, interrupted, and metrics (latencies in seconds, such as llm_ttft).
tool_callname, arguments, output (absent while running), and is_error.
handofffrom and to. The first agent appears with no from.
configchanges to the agent's instructions or tools.
errortext.
logtext, one log line.
statefrom and to. Reported only by events.

Events can also include time (RFC 3339) and earlier, which marks an event from before the turn, such as a greeting.

Exit codes

Every command exits non-zero when no session is running on the port. say also exits non-zero when the agent reports an error or the turn times out; the agent keeps running.

Agent Simulations

Run Agent Simulations against your agent, which the CLI starts locally by default, with the simulation running on LiveKit Cloud. Requires LiveKit CLI v2.19.0 or later.

lk agent simulate <command> [options]
# or
lk agent simulation <command> [options]

Subcommands:

  • text [entrypoint]: Run scenarios in text mode.
  • audio [entrypoint]: Run scenarios through the full STT-LLM-TTS pipeline.
  • list: List the project's most recent simulation runs.
  • view RUN_ID: Open a previous run instead of starting a new one. No agent is started and nothing is dispatched.
  • export RUN_ID: Print a finished run and its per-job chat contexts to stdout as JSON. The run must have finished: completed, failed, or cancelled.
  • cancel RUN_ID: Cancel a run that's still in progress.

Options for simulate/simulation:

  • --num-simulations N (alias -n): Number N of scenarios to generate from the agent's source. Has no effect when a scenario file is in use.
  • --concurrency N: Maximum number N of simulations to run in parallel within a run. Defaults to 15 when unset. An explicit value can't exceed 20; a higher value is rejected. Separately, a project-wide limit of 30 running simulations applies across all runs.
  • --samples K (alias -k): Run every scenario K times in one run, and report pass@k (passed at least once) and pass^k (passed every time). Requires --scenarios when K is more than 1. LiveKit Cloud accepts 1 or 3. Each sample counts as a separate simulation, and the number of scenarios multiplied by K can't exceed the limit of 250 simulations per run.
  • --pass-rate RATE: Share of samples that must pass for a scenario to pass, as a RATE greater than 0 and at most 1. Rounds to whole samples with a minimum of one; for example, 0.75 of 3 samples needs 2 passes. Requires --samples of more than 1. Default: 0.75.
  • --scenarios FILE: Path to a scenario FILE. If you omit it, the CLI generates scenarios from the agent's source. The file and every scenario in it need an id, and the CLI offers to add any that are missing.
  • --yes (alias -y): Skip the confirmation prompts for the source upload and for adding missing IDs to the scenario file. Required for non-interactive runs that generate scenarios from source or run a file with missing IDs.
  • --agent-name NAME: Run against an already-running agent instead of spawning one locally. Pass the registered NAME, or an empty string ("") to target the project's default agent that auto-joins every room. Requires --scenarios.

You can pass the simulate options before or after the text or audio subcommand name. To run against the project's default agent, pass --agent-name "". For audio runs, see Simulate audio.

The entrypoint follows entrypoint detection. A Node.js project with a build script must name its entrypoint, such as dist/main.js.

Scenario IDs

A scenario file and each scenario in it need a stable id (SCNG_ for the file, SCN_ for scenarios), so LiveKit can track scenarios across runs. If IDs are missing, the CLI offers to add them in place; --yes adds them without asking.

Simulate text

lk agent simulate text [options] [entrypoint]

Also takes the options for simulate.

Simulate audio

Run scenarios through the agent's full STT-LLM-TTS pipeline, with the simulated user speaking over an audio track.

lk agent simulate audio [options] [entrypoint]

Options for simulate audio:

  • --background-noise: Mix ambient noise into the simulated user's audio.
  • --low-quality-microphone: Publish the simulated user's audio as a low-quality microphone would capture it.
  • --packet-loss: Drop packets from the simulated user's audio track.

Also takes the options for simulate.

List runs

lk agent simulate list [options]

Options for simulate list:

  • --limit N: Number N of runs to return. If unset, defaults to the API page size.
  • --json (alias -j): Output as JSON.

View a run

lk agent simulate view RUN_ID

Export a run

lk agent simulate export RUN_ID

Cancel a run

lk agent simulate cancel [options] RUN_ID

Options for simulate cancel:

  • --json (alias -j): Output as JSON.

Examples

Generate and run 10 scenarios from the agent's source:

lk agent simulate text -n 10

Run a checked-in scenario file:

lk agent simulate text --scenarios scenarios.yaml

Run every scenario 3 times. With the default pass rate of 0.75, a scenario passes when at least 2 of its 3 samples pass:

lk agent simulate text --scenarios scenarios.yaml --samples 3

Run scenarios over audio, with a noisy connection:

lk agent simulate audio --background-noise --packet-loss

Export a finished run as JSON:

lk agent simulate export RUN_ID > run.json