Program into something that executes: the host supplies bindings through a RuntimeEnv, Interpreter::load checks everything up front, and Interpreter::run evaluates the program on an input map. This page lists the full surface, plus include_program! for compiling a .dsrs file into a Rust binary.
RuntimeEnv
What the host supplies at load: live models, host tool and hole bindings, the sandbox, and the capability grants. Secrets never travel in the artifact; model clients are bound here from host-held keys and env vars.
Interpreter::load
Loading front-loads every check; nothing is lazy and nothing waits for call time. The checks run in this order:
Program::validate(the structural graph rules).program.capsmust be a subset ofenv.grants(no ambient authority).- Every model must be bindable: pre-bound by name, or client-constructible from its config.
- Every
ToolKind::Hosttool name must be bound. - Every sandboxed tool and hole is registered through the full sandbox lifecycle (parse, compile, register). A hole that does not compile fails the load, not the call.
LoadError variants
Interpreter::run
Evaluates the program on an input map, reading parameters through an optional overlay (never mutating the program) and metering spend against a budget.
inputis a JSON object of the program’s input fields. It is checked against the program’s external signature: a missing required field or a type mismatch isRunError::Input.overlayisOption<Arc<Overlay>>. When present, itsbasemust equal the program’s hash or the run fails withRunError::Overlaybefore anything executes.budgetcaps spend for this run.
Budget
Run-level spend limits; None means unlimited. Budget::default() and Budget::unlimited() are the same: no limits.
An
AgentLoop’s per-node budget chains a child meter under the run meter, so node spend also counts against the run.
RunError variants
RunError::retryable() is true only for Lm, Parse, Tool, and Hole; those are the errors Retry and Refine may intercept. Budget and CapabilityDenied are never retried.
Ambient overlays
These two functions let#[module] executable functions pick up a candidate without threading it through every call.
with_ambient_overlay(overlay, fut)runs a future with anArc<Overlay>as the ambient candidate for every#[module]function called on that task. Scoping is task-local: spawned subtasks do not inherit it, and nesting replaces the outer scope. The overlay’sbaseis checked byInterpreter::runagainst each module’s program, not here, so one scope can span calls into several modules and only the matching one accepts it.current_overlay()returns the ambient overlay (Option<Arc<Overlay>>) if awith_ambient_overlayscope is active on this task.#[module]-generated functions read it immediately beforeInterpreter::run.
default_lm
The globally configured LM, used when a module does not name a model. default_lm() returns Option<Arc<LM>>: the model set through configure(...) in the global settings, or None when nothing was configured. Generated #[module] environments use it to bind the default model ref at load.
Embedding programs with include_program!
include_program! compiles a .dsrs file into your binary:
qa.dsrs becomes mod qa). The path is resolved relative to your crate’s Cargo.toml directory. The generated module contains:
qa::SOURCE: the embedded text.qa::program(): the parsed, validated program (panics on a bad file).qa::try_program(): the same, but returns aResult.- A generated test, so
cargo testfails if the file ever becomes invalid.
dsrs serve cannot bind: embed the file, bind your implementations with bind_host_tool and bind_host_hole, and serve from your own binary.
See also
- Program and nodes: the
Programvalue the runtime loads, and the Overlay API - The .dsrs file: the text format
include_program!embeds - CLI:
dsrs serve, the hosted version of this load-and-run path - Code Mode: the
run_jssurfacewith_code_modeenables - Capabilities: grants, caps ceilings, and
CapabilityDenied
