Skip to main content
--agent https://your-agent/step rehearses any agent that runs as a service, in any language. sandtable sends one POST per step, and the agent answers with either its reply to the user or tool calls for sandtable to run against the simulated world. The agent keeps its own conversation state, keyed by session_id.

Request

POST <url> with content-type: application/json:
Each request carries either message or tool_results, never both. Each entry in tool_results has:

Response

A 2xx response with a JSON body, in one of two shapes:
Tool calls in one response run in order. sandtable then POSTs all their results back in a single request with tool_results.

One turn, step by step

Rules and limits

  • Tool calls are graded. Every call is checked against the domain’s invariants before it runs, then executed against the trial’s mock world. Nothing reaches a real system.
  • Step budget. After 16 rounds of tool calls in one turn, the turn ends with the reply [agent exceeded its step budget for this turn].
  • Errors end the trial. A non-2xx status (the error shows the status and body), a body that is not JSON, or a response with neither reply nor tool_calls ends the trial with a runtime failure. It counts as a failed trial.
  • Concurrency. Up to --concurrency trials (default 4) run at once, so your service sees interleaved sessions. Key all state on session_id.
  • No timeout of its own. sandtable does not abort slow requests, so a hung endpoint stalls its trial.
  • No end-of-session call. Your service is not told when a trial ends.
  • No token usage. sandtable cannot see your agent’s model calls, so reported tokens and cost cover only the simulated user.
session_id starts with the run’s id (also in results.json as runId), so it never repeats across runs, and a service that keeps state between runs won’t resume an old conversation.

Authentication and custom headers

The CLI sends no extra headers. If your endpoint needs them, wrap the HTTP adapter in a small module and pass that to --agent:
http-agent.mjs

A toy agent

The quickstart has a complete agent in Node and in Python that implements this protocol, and runs against the bundled freight example.