description: "Abstract code-execution seam (ctx.codeRuntime) for users and maintainers composing, consuming, or building a backend that runs one model-written program against host-provided bindings."
kind: "package-reference"
English | 中文
Summary
Use dsh-code-runtime to run one model-written program against host-provided asynchronous functions through a configured backend. A request returns a lossless-JSON value, ordered per-channel logs, or a structured error; program failures resolve in the result, while rejected promises indicate caller misuse. Each run is isolated from prior runs, and the runtime has no knowledge of tools or sessions. Choose an execution backend separately; its language and isolation descriptors identify the required source language and execution substrate but do not themselves promise a security boundary.
Table of Contents
Use this package
Choose this package when you compose a deployment that executes model-written programs, consume ctx.codeRuntime directly, or build a backend that runs programs. In the shipped composition, PTC mode in dsh-tools is the consumer: only what the program printed and returned re-enters the conversation.
Run a program
Give the runtime a program and binding namespaces, then call resolve(request) followed by run(spec). Resolution validates optional cwd, timeout and sandbox policy against the provider's capabilities and fills deployment defaults. The program runs as an async function body, so top-level await and return work; a lossless-JSON completion becomes result.value, captured text becomes result.logs, and program failures become result.error. Each output channel preserves its own order, while cross-channel interleaving is backend-dependent.
const spec = ctx.codeRuntime.resolve({
program: 'return await tools.add({ a: 1, b: 2 })',
bindings: [{ global: 'tools', functions: { add: async (args) => args.a + args.b } }],
})
const result = await ctx.codeRuntime.run(spec)
// result.value === 3
Choose a backend
Backends expose language and isolation as diagnostic descriptors; neither grants authority or proves confinement. dsh-code-runtime-node executes erasable TypeScript in a fresh managed Node process under the resolved sandbox policy. The private dsh-experimental-code-runtime-python provider executes Python in a fresh CPython subprocess without file confinement. sandboxMode advertises a provider's deployment file-policy mode, or is absent when that capability is unsupported.
Name your bindings portably
Binding-global and error-class names are language-portable: they must match [A-Za-z_][A-Za-z0-9_]*, avoid every portable target language's reserved words, and avoid backend-owned slots, so one namespace list is valid against every backend. A name like $tools, lambda, or console fails the run before it starts; the exact exclusion sets are part of the seam contract.
What can go wrong
Failures arrive as result.error with an orthogonal kind: exception, timeout, abort, worker-exit, invalid-output, output-limit, protocol or sandbox-unavailable. Providers return applicable result.sandbox facts separately from success or failure. Invalid or unsupported execution options fail during resolve; run rejects caller misuse, such as unresolved inputs, invalid binding names or a call after disposal.
Understand the implementation
Implementation internals — click to expand
This section explains the design behind the seam; observable behavior is fully covered in [Use this package](#use-this-package).
### Design concept
The package is the Service Definition role of the code-execution capability seam ([capability seams](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md)): an abstract `CodeRuntime extends Service` registered as `ctx.codeRuntime`, plus the vocabulary both backends and the consumer share. Providers subclass `CodeRuntime`, implement `resolve` and `run`, and register the service; the consumer (PTC mode in `dsh-tools`) generates the model-facing SDK and bridges tool dispatch. The runtime stays ignorant of tools and sessions by contract: it receives a program, named async bindings and resolved execution options, then returns captured output, the outcome and applicable sandbox facts.
### Service API
`resolve(request)` owns supported option validation and deployment defaulting. `run(spec)` executes the complete inputs and resolves program outcomes after cleanup. Language and substrate descriptors guide presentation; `sandboxMode` indicates whether the consumer can pass a resolved file policy. Neither descriptors nor a successful program result substitute for the backend's reported enforcement facts.
The exhaustive semantics live in the [code runtime subsystem reference](../../../docs/subsystems/code-runtime.md); the exact signatures are in [`src/index.ts`](src/index.ts).
### Vocabulary
`CodeRunRequest` carries the program, host bindings, cancellation and optional execution choices. `CodeRunSpec` requires the resolved cwd and elapsed deadline. `CodeBindingNamespace` declares program globals and optional typed rejection constructors. `CodeRunResult` separates logs/value, failure and `CodeRunSandbox` facts; exact fields and provider obligations live in [`src/types.ts`](src/types.ts).
### Portable identifiers
Binding-global and error-class names are language-portable: they must match the identifier subset `[A-Za-z_][A-Za-z0-9_]*` (no JS-only `$`) and clear the seam-exported exclusion sets, so one `bindings` list is valid against every backend. The package exports the contract every backend enforces — `PORTABLE_RESERVED_WORDS` (ECMAScript ∪ Python reserved words), `RESERVED_BINDING_GLOBALS` (backend-owned globals such as `console` and `__dsh_main__`), `RESERVED_ERROR_MEMBERS` and `DUNDER_MEMBER` (error-member exclusions) — so a name like `$tools`, `lambda`, or `__dsh_main__` makes `run()` reject as seam misuse on any backend. See `src/index.ts` for the exact sets.
### Source map
| File | Role |
|---|---|
| [`src/index.ts`](src/index.ts) | Plugin entry: abstract `CodeRuntime` service and the portable-identifier exclusion sets |
| [`src/types.ts`](src/types.ts) | Vocabulary: `CodeRunRequest`, `CodeRunSpec`, bindings, results, failures and sandbox facts |
| — | No runtime invariant companion is published; this package exposes no independent event sequence or mutable data relation beyond contracts enforced at its owning seam. |
Further Exploration
Read these when the package-level contract is not enough. They move from the PTC mode consumer to the backends and the capability-seam model.
Model Experience
Indirectly, through PTC mode in dsh-tools, which exposes run_code and returns program logs, values, or failures as retained tool-result tokens.
KV Cache effect
No direct invalidation; the named consumer owns any request-prefix changes.
Known Limitations and Deferred Work
These limits define what the seam cannot do; they are current package constraints, not a task backlog.
run() is one-shot — logs arrive only on the resolved CodeRunResult; the seam exposes no streaming-log or progress API for a live program's output.
- No state survives between runs — every request runs against a fresh world; a persistent REPL-style kernel is deferred until a backend brings its own logging story.
- Providers have different confinement capabilities — the shipped Node provider enforces a resolved file policy, while the private experimental Python provider rejects an explicit policy. No container provider is supplied.
- No uniform binding byte cap applies across providers — each provider owns its transport limits; a binding can still allocate memory before its result reaches those limits.
Dev Note
Working context for maintainers — click to expand
This Dev Note is working context for maintainers: undecided directions and open questions. It is explicitly non-authoritative — shipped behavior and limits live in the sections above and the package code.
#### Future: persistent kernel backend
A REPL-style kernel that keeps state across `run_code` calls remains undecided; it would need its own logging story, because the no-state-between-runs contract is what keeps every request reconstructable from the session log alone.
#### Future: container backend
A container-class backend would provide a hard multi-tenant boundary for both code and shell execution; nothing is decided beyond the well-known `isolation` value.