Dry-run an Agent version's machine over scripted events
POST /v1/agents/{agent_id}/versions/{version}/machine/dry-run
| Property | Value |
|---|---|
| Operation | dry_run_agent_version_machine |
| Group | Agent versions |
| Scope | agents:write |
| Route class | control |
| Idempotency | Idempotency-Key accepted: a retry with the same key replays the first answer |
| Audit | Not audited: A dry run: it changes no state and reads no Call content, so it writes no Audit event (ADR 0012, statecharts-and-squads.md 9.3). |
| Released in | 1.58.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Runs the TypeScript interpreter over the version's compiled machine, the implicit machine for a version without one, and the scripted events of the body, and answers each step's value, effects, records, guard outcomes and state hook dispatches with the final value (1.58.0). Guards are evaluated by the rules engine against each step's context; no Policy is evaluated, so a veto is scripted. It writes nothing: no Call event, Audit event or Usage event. A body whose events the version cannot take is 422 validation_failed, and from 1.60.0 so is a version whose machine is a Workflow, with the detail machine_is_workflow (MachineDryRunIssueCode): its dry run is test_workflow.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the agents:write scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl -X POST "$VOCAL_API/v1/agents/agt_.../versions/1/machine/dry-run" \
-H "Authorization: Bearer $VOCAL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"type": "decision.verdict"
}
]
}'const response = await fetch(`${process.env.VOCAL_API}/v1/agents/agt_.../versions/1/machine/dry-run`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"events": [
{
"type": "decision.verdict"
}
]
}),
});
console.log(response.status, await response.text());import os
import uuid
import requests
response = requests.post(
f"{os.environ['VOCAL_API']}/v1/agents/agt_.../versions/1/machine/dry-run",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"events": [
{
"type": "decision.verdict",
},
],
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
agent_id | path | AgentId | yes | The id of an Agent: agt_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
version | path | integer | yes | A version number, from 1. |
idempotency-key | header | string | no | A client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response. |
Request body
Content type application/json, required: MachineDryRunRequest.
| Field | Type | Required | Description |
|---|---|---|---|
events | array of MachineDryRunEventInput | yes | |
slots | map of any | no | Slot values at the start, over the declared defaults. |
variables | map of CallEventValue | no | The variables root at the start; the declared defaults when omitted. |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | MachineDryRunResult | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden |
404 | application/json | ErrorEnvelope | not_found |
409 | application/json | ErrorEnvelope | idempotency_in_progress, idempotency_key_reused |
422 | application/json | ErrorEnvelope | validation_failed |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 200 answer
The shape is MachineDryRunResult.
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | AgentId | yes | |
agent_version | integer | yes | |
final | MachineState | yes | |
object | "machine_dry_run" | yes | |
source | one of "implicit", "authored" | yes | |
steps | array of MachineDryRunStep | yes |