Overview
A simulation run tests an agent against a set of scenarios, and a judge model grades each conversation. To run your own scenarios, send them in scenarioGroup when you create a run. To have LiveKit generate scenarios from your agent code instead, set numSimulations and upload the code.
To upload your agent's code:
- Pack the agent project directory into a
.tar.gzarchive. - Send the archive to the
urlin thepresignedPostRequestof the response, as amultipart/form-dataPOST. Include each entry ofvaluesas a form field, and the archive in a field namedfile. - Confirm the upload with your agent's entrypoint file, such as
agent.py, incodeEntrypoint. LiveKit generates the scenarios from the code.
Reading a run needs the Read role on the project. Creating, confirming, cancelling, and generating a scenario need the Write role.
To call these endpoints from the CLI, use the lk agent simulate list, get, and cancel commands, for example lk agent simulate list --user-auth.
The simulation run object
idstringThe id value.
projectIdstringThe projectId value.
statusSimulationRun.StatusThe status value.
To learn more, see SimulationRun.Status.
agentDescriptionstringThe agentDescription value.
errorstringThe error value.
createdAttimestampThe createdAt value.
jobsArray<Job>The jobs value.
To learn more, see Job.
agentNamestringThe agentName value.
scenarioGroupScenarioGroupThe scenarioGroup value.
To learn more, see ScenarioGroup.
endedAttimestampThe endedAt value.
jobCountint32The jobCount value.
passedCountint32The passedCount value.
failedCountint32The failedCount value.
numSimulationsint32The numSimulations value.
usageSimulationRun.UsageAggregate usage across all jobs in this run (sum of Job.usage).
To learn more, see SimulationRun.Usage.
concurrencyint32Maximum simulate jobs running in parallel for this run (0 = server default).
modeSimulationModeConversation mode for every job in this run; unspecified = TEXT.
To learn more, see SimulationMode.
metricsRunMetricsRun-level aggregates over this run's jobs.
To learn more, see RunMetrics.
summaryZstdstring (byte)Zstd-compressed SimulationRunSummary: decompress, then proto.Unmarshal. Compressed by default so the blob ships as-is on every hop.
issueCountint32How many issues the stored summary flagged. Present only once a summary landed — absent and 0 differ ("never summarized" vs "no issues") — and List responses carry it without the summary blob itself.
ciCIThe pipeline this run came from; unset when it did not come from one.
To learn more, see CI.
samplingSamplingOptionsAbsent when the run ran each scenario once and required it to pass.
To learn more, see SamplingOptions.
List simulation runs
/v0/projects/{projectId}/simulation-runsLists the runs of a project, newest first. You can filter the runs by status, agent, conversation mode, and time window. Each run includes its counts (jobCount, passedCount, failedCount, and issueCount), but not its jobs or its summary.
Returns a list of SimulationRun objects, with a pageInfo cursor.
Path parameters
projectIdstringThe projectId path parameter.
Query parameters
page.cursorstringThe cursor of the page to return: the nextCursor of the previous page. When empty, the list starts at the first item.
page.pageSizeint32The maximum number of items to return. When 0, the list uses its default page size.
statusSimulationRun.StatusA run status. Returns only the runs in this status.
To learn more, see SimulationRun.Status.
agentNamestringAn agent name. Returns only the runs of the agent with this exact name.
startTimestring (date-time)The start of the window on the creation time of the run, inclusive. When unset, the window starts 45 days before endTime. The window can be at most 45 days. A longer window returns InvalidArgument.
endTimestring (date-time)The end of the window on the creation time of the run, exclusive. When unset, the window ends now.
modeSimulationModeA conversation mode. Returns only the runs in this mode.
To learn more, see SimulationMode.
Create simulation run
/v0/projects/{projectId}/simulation-runsCreates a simulation run. With a scenarioGroup, the run starts immediately and the response has no upload target. Without a scenarioGroup, the run waits in PENDING_UPLOAD for the agent source that the API generates scenarios from. Upload the source to the returned presigned POST, then call ConfirmSimulationSourceUpload. A run that stays pending for one hour fails. This RPC is not idempotent: a retry starts a second run.
Path parameters
projectIdstringThe projectId path parameter.
Request body
agentNamestringThe name of the agent under test. Each job dispatches this agent into the simulation room, so the agent must be deployed or running as a worker. When empty, the run uses the default agent of the project. The run records the name, and ListSimulationRuns can filter on it.
numSimulationsint32The number of scenarios to generate from the agent source when scenarioGroup is unset.
regionstringReserved. Must be empty. The API chooses where the run happens.
scenarioGroupScenarioGroupThe scenarios to run, with the contents of a scenarios.yaml file. When set, the run plays only these scenarios and does not generate numSimulations scenarios. The run needs no source upload and starts immediately.
To learn more, see ScenarioGroup.
concurrencyint32The maximum number of jobs that run in parallel. The maximum value is 20. A larger value returns InvalidArgument. The concurrency quota of the project can run fewer jobs at a time. When unset, the API uses its default.
modeSimulationModeThe conversation mode of each job. Unset means TEXT.
To learn more, see SimulationMode.
backgroundNoisebooleanWhen true, the simulated user has background noise. Applies only in AUDIO mode.
lowQualityMicrophonebooleanWhen true, the simulated user has a low-quality microphone. Applies only in AUDIO mode.
packetLossbooleanWhen true, the audio of the simulated user has packet loss. Applies only in AUDIO mode.
ciCIThe CI pipeline that started the run. Use it to link a run to its commit.
To learn more, see CI.
Response fields
simulationRunIdstringThe simulationRunId value.
presignedPostRequestPresignedPostRequestThe presigned POST to upload the agent source archive that the API generates scenarios from. After the upload, call ConfirmSimulationSourceUpload. Unset when the run has a scenarioGroup.
To learn more, see PresignedPostRequest.
Get simulation run
/v0/projects/{projectId}/simulation-runs/{simulationRunId}Returns one run with its jobs and aggregate metrics. The response does not include the compressed summary (summaryZstd). To get the summary, call GetSimulationRunSummary.
Returns the SimulationRun object.
Path parameters
projectIdstringThe projectId path parameter.
simulationRunIdstringThe simulationRunId path parameter.
Count simulation runs
/v0/projects/{projectId}/simulation-runs:countsReturns a histogram of the runs in the window [startTime, endTime). It takes the same filters as ListSimulationRuns, so the histogram and the list describe the same set of runs. Both bounds are required, and endTime must be after startTime.
Path parameters
projectIdstringThe projectId path parameter.
Query parameters
startTimestring (date-time)The start of the window on the creation time of the run, inclusive. Required.
endTimestring (date-time)The end of the window on the creation time of the run, exclusive. Required. Must be after startTime.
statusSimulationRun.StatusA run status. Counts only the runs in this status.
To learn more, see SimulationRun.Status.
agentNamestringAn agent name. Counts only the runs of the agent with this exact name.
modeSimulationModeA conversation mode. Counts only the runs in this mode.
To learn more, see SimulationMode.
Response fields
bucketsArray<Bucket>The buckets that hold at least one run, in ascending order of bucketStart. The response does not include empty buckets. Each run is in exactly one bucket, so the sum of the counts is the number of runs in the window.
To learn more, see Bucket.
intervaldurationThe width of each bucket. The API chooses the width from the window: the window has at most 60 buckets, and a bucket is at least one minute wide. Use the width to add the empty buckets, with a count of 0.
Cancel simulation run
/v0/projects/{projectId}/simulation-runs/{simulationRunId}:cancelStops a run that has not finished. When the run is already finished, the call succeeds and has no effect.
Path parameters
projectIdstringThe projectId path parameter.
simulationRunIdstringThe simulationRunId path parameter.
Confirm simulation source upload
/v0/projects/{projectId}/simulation-runs/{simulationRunId}:confirmSourceUploadConfirms that the agent source is uploaded and starts scenario generation. The run goes to GENERATING, then to RUNNING when the scenarios exist. The call is valid only while the run is PENDING_UPLOAD, so a repeated call fails.
Path parameters
projectIdstringThe projectId path parameter.
simulationRunIdstringThe simulationRunId path parameter.
Request body
codeEntrypointstringThe entrypoint of the uploaded source, for example agent.py.
Get simulation run summary
/v0/projects/{projectId}/simulation-runs/{simulationRunId}/summaryReturns the graded outcome of a finished run: the pass and fail counts, what went well, what to improve, the flagged issues with suggestions, and the chat history of each job. Returns FailedPrecondition while the run is in progress. Returns NotFound when the run finished without a summary.
Returns the SimulationRunSummary object.
Path parameters
projectIdstringThe projectId path parameter.
simulationRunIdstringThe simulationRunId path parameter.
Generate scenario from session
/v0/projects/{projectId}/scenarios:generateFromSessionGenerates a scenario (label, instructions, and expectations) from a recorded room session. Use the scenario in the scenarioGroup of a later run. The API does not save the scenario: the response is the only copy. The session must have a recorded chat history. Each call runs an LLM on the chat history, so it counts against the scenario-generation quota of the project. A call can take up to about one minute.
Returns the Scenario object.
Path parameters
projectIdstringThe projectId path parameter.
Request body
roomIdstringThe ID of the room session (RM_...) to generate the scenario from.
regionstringIgnored. The API finds the session recording by project and room.
Types
Types used by these endpoints, alongside the simulation run object.
agent.AgentHandoff
idstringThe id value.
oldAgentIdstringThe oldAgentId value.
newAgentIdstringThe newAgentId value.
createdAttimestampThe createdAt value.
AgentConfigUpdate
idstringThe id value.
instructionsstringThe instructions value.
toolsAddedArray<string>The toolsAdded value.
toolsRemovedArray<string>The toolsRemoved value.
createdAttimestampThe createdAt value.
Bucket
bucketStarttimestampThe bucketStart value.
countint64The count value.
ChatContent
textstringThe text value.
ChatContext
itemsArray<ChatItem>The items value.
To learn more, see ChatItem.
ChatItem
agentConfigUpdateAgentConfigUpdateThe agentConfigUpdate value.
At most one of agentConfigUpdate, agentHandoff, functionCall, functionCallOutput, and message is set.
To learn more, see AgentConfigUpdate.
agentHandoffagent.AgentHandoffThe agentHandoff value.
At most one of agentConfigUpdate, agentHandoff, functionCall, functionCallOutput, and message is set.
To learn more, see agent.AgentHandoff.
functionCallFunctionCallThe functionCall value.
At most one of agentConfigUpdate, agentHandoff, functionCall, functionCallOutput, and message is set.
To learn more, see FunctionCall.
functionCallOutputFunctionCallOutputThe functionCallOutput value.
At most one of agentConfigUpdate, agentHandoff, functionCall, functionCallOutput, and message is set.
To learn more, see FunctionCallOutput.
messageChatMessageThe message value.
At most one of agentConfigUpdate, agentHandoff, functionCall, functionCallOutput, and message is set.
To learn more, see ChatMessage.
ChatMessage
idstringThe id value.
roleChatRoleThe role value.
To learn more, see ChatRole.
contentArray<ChatContent>The content value.
To learn more, see ChatContent.
interruptedbooleanThe interrupted value.
transcriptConfidencenumberThe transcriptConfidence value.
extraMap<string, string>The extra value.
metricsMetricsReportThe metrics value.
To learn more, see MetricsReport.
createdAttimestampThe createdAt value.
ChatRole
This type has these values:
DEVELOPERSYSTEMUSERASSISTANT
CI
The pipeline this run came from. Set by the client from its CI environment; absent for runs not started by a pipeline.
providerstringE.g. github_actions
commitShastringThe commitSha value.
refstringBranch or tag.
pullRequeststringThe pullRequest value.
runUrlstringLink back to the CI job.
actorstringThe actor value.
Conversation
Audio only.
turnTakingScorenumber0-1.
heardE2eLatencyP50Msint32Floor-transfer offset; a gap is > 0, an overlap < 0.
heardE2eLatencyP95Msint32The heardE2eLatencyP95Ms value.
heardE2eLatencyP99Msint32The heardE2eLatencyP99Ms value.
timeToYieldMsintegerAgent audio continuing past a barge-in.
eotMispredictionCountintegerAgent started before the caller's turn ended.
overlapRationumberOverlapping speech / total speech.
overlapSpeechMsintegerPooling stats for overlap_ratio
totalSpeechMsintegerThe totalSpeechMs value.
awkwardSilenceCountintegerGaps past the natural-pause threshold.
unansweredTurnsintegerThe simulated party spoke, the agent never responded.
falseInterruptionCountintegerNeeds the RemoteSession; agent paused for a non-interruption.
e2eLatencyMsintegerNeeds the RemoteSession; the agent's own claim.
FunctionCall
idstringThe id value.
callIdstringThe callId value.
argumentsstringThe arguments value.
namestringThe name value.
createdAttimestampThe createdAt value.
FunctionCallOutput
idstringThe id value.
namestringThe name value.
callIdstringThe callId value.
outputstringThe output value.
isErrorbooleanThe isError value.
createdAttimestampThe createdAt value.
Issue
descriptionstringThe description value.
suggestionstringThe suggestion value.
labelstringThe label value.
Job
idstringThe id value.
statusJob.StatusThe status value.
To learn more, see Job.Status.
instructionsstringThe instructions value.
errorstringThe error value.
agentExpectationsstringThe agentExpectations value.
labelstringThe label value.
tagsArray<string>The tags value.
roomNamestringThe roomName value.
startedAttimestampThe startedAt value.
endedAttimestampThe endedAt value.
roomIdstringThe roomId value.
usageJob.UsageThe usage value.
To learn more, see Job.Usage.
metricsJobMetricsQuality metrics for this job's call. Unset when the job produced none.
To learn more, see JobMetrics.
scenarioIdstringThe Scenario.id this job ran; empty for generated runs. Every sample of one scenario shares it, so a run's jobs group back into scenarios.
sampleint321-based sample of that scenario within the run; always 1 when the run's samples is 1.
Job.Status
This type has these values:
STATUS_PENDINGSTATUS_RUNNINGSTATUS_COMPLETEDSTATUS_FAILEDSTATUS_CANCELLED
Job.Usage
textTurnsCountint32The textTurnsCount value.
audioTurnsCountint32The audioTurnsCount value.
JobMetrics
taskCompletionnumberThe scenario verdict as 1/0.
overallScorenumberWeighted mean of the judged and heard scores.
sttSTTThe stt value.
To learn more, see STT.
llmLLMThe llm value.
To learn more, see LLM.
ttsTTSThe tts value.
To learn more, see TTS.
conversationConversationThe conversation value.
To learn more, see Conversation.
turnsArray<Turn>One entry per turn, both speakers.
To learn more, see Turn.
judgeModelstringText judge for judged scores; "" if none ran.
hasRemoteSessionbooleanfalse = waveform-only capture (e.g. SIP)
t0timestampAudio only; call start (first speech edge); turn times relative to it.
concisenessnumberJudged over the authored dialog (text and audio); needs the text judge. judged {0, 0.5, 1} per agent turn; job = mean.
unnecessaryToolCallsbooleanWhole-call issue flags; true = present, absent = not judged.
informationLossbooleanThe informationLoss value.
redundantStatementsbooleanThe redundantStatements value.
poorQuestionQualitybooleanThe poorQuestionQuality value.
conversationProgressionnumber0-1, derived from the flags above.
LLM
ttftMsintegerNeeds the RemoteSession; time to first token.
ttfsMsintegerNeeds the RemoteSession; time to first sentence, the smallest speakable unit.
tokensPerSecondnumberNeeds the RemoteSession.
MetricsReport
startedSpeakingAttimestampThe startedSpeakingAt value.
stoppedSpeakingAttimestampThe stoppedSpeakingAt value.
transcriptionDelaynumberThe transcriptionDelay value.
endOfTurnDelaynumberThe endOfTurnDelay value.
onUserTurnCompletedDelaynumberThe onUserTurnCompletedDelay value.
llmNodeTtftnumberThe llmNodeTtft value.
ttsNodeTtfbnumberThe ttsNodeTtfb value.
e2eLatencynumberThe e2eLatency value.
llmNodeTpsnumberThe llmNodeTps value.
llmNodeTtfsnumberThe llmNodeTtfs value.
PresignedPostRequest
urlstringThe url value.
valuesMap<string, string>The values value.
RunMetrics
Aggregates over this run's jobs, so a run summary does not have to pull every job and turn. Reuses the JobMetrics group shapes.
scenarioPassRatenumberShare of jobs whose scenario verdict passed.
overallScorenumberMean over scored jobs.
sttSTTThe stt value.
To learn more, see STT.
llmLLMThe llm value.
To learn more, see LLM.
ttsTTSThe tts value.
To learn more, see TTS.
conversationConversationThe conversation value.
To learn more, see Conversation.
concisenessnumberMeans over the jobs that report them.
conversationProgressionnumberThe conversationProgression value.
SamplingOptions
Runs each scenario more than once, so a flaky sample is distinguishable from a broken scenario. Both fields are required when it is present.
samplesint32Samples per scenario, > 1. The run holds scenarios × samples jobs, subject to the usual job cap.
passRatenumberThe share of a scenario's samples that must pass for that scenario to pass, 0-1. A scenario needs round(rate × samples) of them, so 1 requires every sample and 0.67 of 3 requires 2.
Scenario
A single scenario, mirroring one entry in a scenarios.yaml file. Scenarios are no longer stored server-side; the yaml file is the source of truth.
labelstringThe label value.
instructionsstringThe instructions value.
agentExpectationsstringThe agentExpectations value.
tagsMap<string, string>Set as participant attributes on the simulation participant's access token.
userdatastringArbitrary JSON-encoded object, surfaced to the agent under test as SimulationContext userdata (e.g. inputs and benchmark target state).
idstringSCN_-prefixed guid. Stable across edits to label, instructions, or expectations, so runs of the same scenario can be correlated over time.
ScenarioGroup
A named group of scenarios, mirroring a whole scenarios.yaml file.
namestringThe name value.
scenariosArray<Scenario>The scenarios value.
To learn more, see Scenario.
idstringSCNG_-prefixed guid. Stable identity of the scenarios file, independent of its name.
SimulationMode
How the simulated user interacts with the agent under test.
This type has these values:
SIMULATION_MODE_UNSPECIFIEDSIMULATION_MODE_TEXTSIMULATION_MODE_AUDIO
SimulationRun.Status
This type has these values:
STATUS_PENDING_UPLOADSTATUS_GENERATINGSTATUS_RUNNINGSTATUS_SUMMARIZINGSTATUS_COMPLETEDSTATUS_FAILEDSTATUS_CANCELLED
SimulationRun.Usage
textTurnsCountint32The textTurnsCount value.
audioTurnsCountint32The audioTurnsCount value.
SimulationRunSummary
passedint32The passed value.
failedint32The failed value.
goingWellstringThe goingWell value.
toImprovestringThe toImprove value.
issuesArray<Issue>The issues value.
To learn more, see Issue.
chatHistoryMap<string, ChatContext>The chatHistory value.
To learn more, see ChatContext.
STT
The agent's perception of the caller. Audio only.
wernumberNeeds the RemoteSession; word_errors / words.
wordsintegerNeeds the RemoteSession.
wordErrorsintegerNeeds the RemoteSession.
cernumberNeeds the RemoteSession; char_errors / chars.
charsintegerNeeds the RemoteSession.
charErrorsintegerNeeds the RemoteSession.
sttDelayMsintegerNeeds the RemoteSession; agent-reported STT/endpointing delay.
entityRecognitionnumberKey entities (names, IDs, amounts) the caller said. Needs the text judge. recognized / uttered.
entitiesUtteredintegerThe entitiesUttered value.
entitiesRecognizedintegerThe entitiesRecognized value.
entityRecallnumberRetention: an entity is acquired at the first saying heard right, and these count only the sayings after that, so recall separates keeping an entity from ever getting it. acquired_recognized / acquired_uttered
entitiesAcquiredUtteredintegerThe entitiesAcquiredUttered value.
entitiesAcquiredRecognizedintegerThe entitiesAcquiredRecognized value.
TTS
The agent's voice. Audio only.
ttfbMsintegerNeeds the RemoteSession; provider byte-level TTFB.
wernumberNeeds the RemoteSession; word_errors / words.
wordsintegerNeeds the RemoteSession.
wordErrorsintegerNeeds the RemoteSession.
cernumberNeeds the RemoteSession; char_errors / chars.
charsintegerNeeds the RemoteSession.
charErrorsintegerNeeds the RemoteSession.
entityRecognitionnumberKey entities the agent said, as the caller heard them. Needs the text judge. recognized / uttered.
entitiesUtteredintegerThe entitiesUttered value.
entitiesRecognizedintegerThe entitiesRecognized value.
entityRecallnumberacquired_recognized / acquired_uttered
entitiesAcquiredUtteredintegerThe entitiesAcquiredUttered value.
entitiesAcquiredRecognizedintegerThe entitiesAcquiredRecognized value.
Turn
Rows exist for text and audio. The groups above hold the means and pools over these; anything not measured for a turn stays unset.
indexinteger1-based, conversation order.
roleChatRoleASSISTANT = the agent under test, USER = simulator persona.
To learn more, see ChatRole.
startMsintegerAudio only; relative to t0; unset if the turn could not be aligned to the audio.
endMsintegerAudio only.
sttDelayMsintegerNeeds the RemoteSession.
llmTtftMsintegerNeeds the RemoteSession.
llmTtfsMsintegerNeeds the RemoteSession.
llmTpsnumberNeeds the RemoteSession.
ttsTtfbMsintegerNeeds the RemoteSession.
e2eLatencyMsintegerNeeds the RemoteSession.
heardE2eLatencyMsint32The heardE2eLatencyMs value.
timeToYieldMsintegerThe timeToYieldMs value.
turnTakingScorenumberThe turnTakingScore value.
concisenessnumberNeeds the text judge.
eotMispredictionbooleanThe eotMisprediction value.
awkwardSilencebooleanThe awkwardSilence value.
unansweredbooleanThe unanswered value.