.dsrs file is the canonical text form of a program: its declarations first, then exactly one main. The program hash is computed from this canonical text, minus the lineage block, so the file is the program’s identity, and any two loads of the same text agree on it. This page lists every declaration and node form with a short example of each.
General rules: // starts a comment. Whitespace is insignificant except inside js``` ``` code fences. Strings are JSON strings. Reserved words cannot be used as names: dsrs program caps model sig class enum tool lineage main in out predict cot agent hole seq fork join route retry refine loop else js demos string int float bool map true false null while carry.
File skeleton
Declarations may appear in any order;main comes last.
Declarations
dsrs 1
The format pragma. It must be the first line of every file.
program
Names the program.
caps
The program’s capability ceiling: the full set of capabilities anything in the file may use. Omit the block when the program needs none. Capability names are namespaced with a colon.
model
Declares a model that nodes reference as @name. The options block is optional; all keys inside it are optional: base_url "...", temperature N, max_tokens N, max_tool_iterations N, max_retries N, retry_base_delay_ms N, cache true|false.
sig
An LM-call interface: the fields going in and coming out, with an optional instruction string first. alias renames a field for the LM; check and assert attach constraints (a check always needs a label).
string, int, float, bool; Name (a declared class or enum); "lit" (a literal string type); T[] (list); T? (optional); map<T> (string-keyed map); A | B (union); (A | B)[] (grouped union in a list).
class
A struct type, referenced by name in signatures. Fields may carry doc strings and constraints.
enum
A unit enum. Variants may carry doc strings.
tool
A tool a loop may call: a name, a description, an optional caps [...] list, and an in/out interface. A host tool has no code block; the runtime binds its implementation by name at load. A sandboxed tool carries its JavaScript in the artifact as a js``` ``` fence.
lineage
Optional provenance for optimized artifacts: which optimizer produced this program, on what data, at what cost. parent and overlay are stamped by Program::bake. The lineage block is excluded from the program hash.
main and node forms
main is the program body: always a seq typed by the program’s main signature.
seq is name = <expr>; names are program-unique, and a node may only reference nodes named earlier. The seq exports fields with a final out { ... } step, and main’s seq must export every out field of its signature. @model may be omitted when exactly one model is declared. Leaf nodes (predict, cot, agent, hole) always need a name =; containers in arm or child positions may be anonymous.
predict
One LM call over a signature. The optional block sets the instruction and demos.
cot
A predict with a prepended reasoning output.
agent
An LM plus tool loop. The block is required.
hole
Typed opaque code: the type system sees a normal node, the implementation is either sandboxed JavaScript carried in the artifact or a native function the host binds by name. Every hole declares caps [...] (empty when it needs none), then either a js``` ``` fence or extern "<hash>".
Sandboxed form:
seq
A nested scope with its own exported fields.
fork / join
Concurrent branches that cannot see each other, joined into one set of exported fields.
route / else
Branches on an enum-typed (or literal-union) port. Arms must export identical fields; else is required unless the arms cover every variant.
retry
Re-runs a child on retryable failure, with optional backoff and parse-error feedback.
refine
A body plus a judge: the body re-runs with the judge’s feedback until the score passes the threshold or the rounds run out. The judge’s signature must output score: float and feedback: string; feedback_field names the string input of the body that receives the feedback.
loop
A bounded loop. ^field reads the previous iteration’s carried value; while (optional) continues while a bool port is true; carry rebinds next-iteration inputs (each carried field must shadow a scope input); join names the loop’s exported fields.
Ports
The right side of every binding is a port:
Every
in field of a leaf’s signature must be bound exactly once. Types must match; the allowed widenings are int to float, T to T?, and T to a union containing T.
Hard rules
Violations of any of these are compile errors:dsrs 1first;main: <Sig> = seq { ... }last.- Node names are program-unique; only earlier nodes are referenceable.
- Every hole and tool
caps [...]must be a subset of the programcaps { ... }. routeneedselseunless its arms cover every enum variant; arms export identical fields.- All loops carry explicit bounds (
max_iters,max_turns,attempts,max_rounds). - Signatures need at least one
inand oneoutfield;checkneeds a label. - Class, enum, sig, tool, and model names must be declared before
mainuses them.
See also
- Program and nodes: the in-memory
Programthis text lowers to, and the hash rules - CLI:
dsrs check,dsrs fmt, and serving a.dsrsfile over HTTP - Runtime: loading and running a program, including
include_program! - Capabilities: the
capsceiling and host grants
