Code and Agents
run and agent hand work to a sandbox or to a model. Each declares its boundary in the file.
run executes sandboxed code, for logic that the declarative layer cannot express.
- wow_deltas: run: python code: | cur, prev = ctx.metrics.this_week, ctx.metrics.last_week return {k: (cur[k] - prev[k]) / prev[k] for k in cur if k in prev} network: [] # default: no egress timeout: 10sThe value of run is a language identifier from the registry of run languages. This version registers python and javascript. Each registered language has its own capability name, so an implementation declares the languages that it executes.
code holds the source inline. This version defines no way to reference code in a separate file.
ctx is bound to the readable scope, and exposes the same tree that the expression language walks, so {{ classify.category }} and ctx.classify.category denote the same value. The step binds the JSON-serializable value that the code returns.
Implementations MUST NOT give sandboxed code the ability to invoke a connector action, to schedule work, or to read the filesystem. Implementations MUST grant no network egress by default. network grants egress to the listed hosts, and to no others.
timeout bounds one execution. Implementations MUST also apply a memory bound and a result size bound, and both are implementation-defined.
run-python and run-javascript are capabilities.
agent is a bounded autonomy node, for a sub-task whose control flow cannot be specified in advance. An action such as llm.categorize is called with declared inputs and outputs; an agent node differs only in that the control flow inside it is not declared.
- resolve: agent: triage-assistant goal: "Find the account for {{ sender }}; it may be under a parent org." with: { sender: "{{ message.from }}" } tools: [crm.search, billing.lookup] returns: { account_id: "string" } budget: { steps: 8, tokens: 20000 } on_exhausted: [ ... ]Scope. with is a projection, and it is the node’s entire readable context together with the rendered goal. Implementations MUST NOT expose any other binding to the node. A goal is an ordinary expression-bearing scalar, evaluated in the calling scope.
Tools. tools is an allowlist of connector actions from the resolved catalog. Implementations MUST NOT permit the node to invoke an action outside the list. Implementations MUST validate every invocation against the action’s manifest, exactly as they validate an ordinary action call, and MUST record every invocation and its result.
Result. returns declares the result schema, as field declarations. Implementations MUST validate the node’s result against it, and MUST fail the step when the result does not satisfy it.
Budget. budget is REQUIRED, and MUST declare at least one bound. The defined bounds are steps (the number of action invocations), tokens, and duration. Cost in a currency is not a bound of this format, because a price is a fact about one provider.
When a bound is reached, implementations MUST stop the node. on_exhausted is a step list that then runs. When a file declares no on_exhausted, exhausting a bound fails the step.
Replay. Implementations MUST record the actions that the node took and their results. The run then replays exactly, although the original execution was not deterministic.
agent-nodes is a capability.