Batch: Run Tools
cad_batchExecute an ordered list of CAD tool calls in one request, validating each step and referencing earlier results. Dry-run and revision checks preview and safely apply batches.
Instructions
Execute an ordered list of tool calls in ONE round trip.
N calls collapse into one request/response pair, and bind lets a later
step reference an earlier step's result so handles never have to be echoed
back through the model.
steps=[
{"tool": "entity_create_line", "args": {...}, "bind": "edge"},
{"tool": "point_from_snap", "args": {"handle": "$edge", "snap": "mid"},
"bind": "mid"},
{"tool": "entity_create_circle","args": {"cx": "$mid.x", "cy": "$mid.y",
"radius": 4}},
]Successful steps report only their handle; pass verbose=True for the full result. Anything without a handle is returned whole.
VALIDATION runs first, always: an unknown tool, a schema-invalid argument or
a reference no earlier step binds refuses the whole batch before anything
executes. on_error governs run-time failures only. dry_run=True returns
that validation report and executes nothing.
ERRORS are typed, never text: each failed step carries error.kind - one of
unsupported (with the backend capability), invalid_args, refused, failed,
unknown_tool, unresolved_ref, denied, malformed_step, quarantined, busy,
active_document_changed (live engine: the operator switched documents),
stale_revision, scan_incomplete, timed_out, unknown_commit (a write that
outran its deadline while its worker ran), cancelled, operation_conflict -
and its own operation_id.
PREVIEW AND APPLY. dry_run=True also returns preview: the document id and
content revision, the exact fingerprint of every LITERAL handle in a handle
parameter (a '$reference' resolves late and an entity a step creates has
none) and the planned steps. Pass its revision as expected_revision and
its preconditions back, and the batch runs only if nothing moved -
otherwise it is refused with kind stale_revision and no step runs. A
guarded batch reports revision: {checked, after, interleaved}; each step
is its own locked call, so a change another call made between two steps is
listed under interleaved (a rollback restores the checkpoint, that change
included).
OPERATIONS: the batch and each step are operations with their own ids
(system_status lists the recent ones). Pass operation_id (or the
request's _meta.operation_id) to make a retry safe: the same id with the
same steps replays the recorded result instead of drawing twice. The
journal is in memory: a server restart forgets it (durable in 1.8.0, B13).
ATOMICITY is reported, not assumed. Read the atomicity block: on the
headless backend rollback restores a full document snapshot; on live AutoCAD
it sends an UNDO whose landing AutoCAD never confirms. The default
on_error="stop" claims nothing and is exact on both. A checkpoint a step
opens with transaction_begin is closed with the batch's (unwound).
NOT CALLABLE from a batch: the raw command/LISP escape hatches, and cad_batch itself. Call those directly.
For a few hundred entities of the same kind, entity_batch_create is denser still (no per-step tool name) - and it can be one step of a cad_batch.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| steps | Yes | Ordered steps. Each: {'tool': <tool name>, 'args': {...}, 'bind': <optional name>}. 'bind' names this step's result so a later step can reference it as '$name' (its handle), '$name.field' or '$name.list.0'. '$$' is a literal dollar sign. | |
| dry_run | No | Validate every step against its tool's real JSON Schema and execute nothing. | |
| verbose | No | Return each step's full result instead of just its handle. | |
| on_error | No | stop (default): halt at the first failure, keep what already ran. continue: run every step. rollback: open a checkpoint first and undo on failure - read the returned `atomicity` block for what that is worth on this backend. | stop |
| operation_id | No | Your own id for this batch (1-128 printable characters). Sent again with the same steps it returns the recorded result (replayed: true) instead of running twice; with other steps it is refused (operation_conflict); after a run whose outcome is unknown (cancelled or timed out mid-write) it is refused (requires_reconcile). Held in memory only: a server restart forgets it. | |
| preconditions | No | A dry run's `preview.preconditions` ({handle, fingerprint} per literal handle): run only if every entity is exactly as previewed; otherwise refused stale_revision, no step run. | |
| expected_revision | No | Run only if the document's content revision is still this one (a dry run's `preview.revision`); otherwise refused stale_revision, no step run. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||