Skip to main content
The runtime is what turns a 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:
  1. Program::validate (the structural graph rules).
  2. program.caps must be a subset of env.grants (no ambient authority).
  3. Every model must be bindable: pre-bound by name, or client-constructible from its config.
  4. Every ToolKind::Host tool name must be bound.
  5. 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.
With code mode enabled there is one extra load-time refusal: two non-stop tool names in one loop that mangle to the same JS identifier.

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.
  • input is 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 is RunError::Input.
  • overlay is Option<Arc<Overlay>>. When present, its base must equal the program’s hash or the run fails with RunError::Overlay before anything executes.
  • budget caps 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 an Arc<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’s base is checked by Interpreter::run against 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 a with_ambient_overlay scope is active on this task. #[module]-generated functions read it immediately before Interpreter::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:
The macro creates a module named after the file stem (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 a Result.
  • A generated test, so cargo test fails if the file ever becomes invalid.
The file is parsed and validated while your crate compiles, so a broken artifact breaks your build, not a running process. This is the shipping path for programs with host tools or host holes, which 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 Program value 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_js surface with_code_mode enables
  • Capabilities: grants, caps ceilings, and CapabilityDenied