English | 中文
The code-execution capability seam supplies ctx.codeRuntime through dsh-code-runtime. It runs one program against host bindings and reports output, failure and applicable sandbox facts. Code execution is optional rather than part of the agent-loop spine. The PTC foundation owns registry presentation, the typed-return contract owns binding values, and the sandboxed Node decision owns the shipped execution provider.
Source: packages/code-runtime/code-runtime/src/types.ts
CodeRunRequest contains the program, bindings, cancellation and optional execution choices. The provider's resolve validates supported choices and applies its deployment defaults; run receives a CodeRunSpec with an explicit directory and deadline. A provider that cannot enforce a requested policy rejects it before program execution:
/**
* Caller inputs for one program. The provider's resolve method validates supported
* options and supplies directory, deadline, and authority before execution.
*/
interface CodeRunRequest {
/**
* The program source, in the runtime's {@link ../index.ts | language}. It
* runs as the body of an async function: top-level `await` and `return`
* are available, and the completion value becomes
* {@link CodeRunResult.value}.
*/
program: string
/** Host functions exposed to the program, one global object per namespace. */
bindings: CodeBindingNamespace[]
/** Working directory in the mounted filesystem and subprocess execution world. */
cwd?: string
/** Requested elapsed execution time; the provider's resolver validates and caps it. */
timeoutMs?: number
/** Resolved authority for this execution. Providers without confinement reject an explicit policy. */
sandboxPolicy?: SandboxExecutionPolicy
/**
* Abort the run: the runtime stops the program (hard, even mid-loop) and
* resolves with a {@link CodeRunFailure} of kind `'abort'`. In-flight
* binding calls are the CALLER's to settle — the runtime only stops asking.
*/
signal?: AbortSignal
}
/** Fully resolved execution inputs; run never supplies a missing directory or timeout. */
interface CodeRunSpec extends CodeRunRequest {
/** Absolute directory in the provider's execution world. */
cwd: string
/** Positive finite execution deadline in milliseconds, after provider capping. */
timeoutMs: number
}
/** File confinement applied to a program, independently of its terminal outcome. */
interface CodeRunSandbox {
/** File-effect mode used for this execution. */
mode: SandboxMode
/** Whether an observed failure matches the selected backend's denial diagnostics. */
denied: boolean
/** Completeness reported by the selected confining backend; absent for full access. */
enforcement?: SandboxEnforcement
}
Program failures resolve through CodeRunResult.error; invalid caller inputs may reject before execution. Sandbox mode, observed denial and enforcement completeness are separate facts, so a successful program does not by itself prove that every requested restriction was enforced:
/**
* The outcome of one run. An error is a FIELD on a resolved result, never a
* rejection of `run()` — reporting a failed program is the caller's job, not
* an exception path.
*/
interface CodeRunResult {
/** Applied file policy and observed denial, when the provider enforces file policy. */
sandbox?: CodeRunSandbox
/**
* The program's completion value (its top-level `return`), when it ran to
* completion and the value crossed the runtime's lossless-JSON boundary.
* Invalid or over-limit completions fail the run instead of substituting a
* rendered string; a failed or value-less run leaves this absent.
*/
value?: CodeJsonValue
/**
* Captured text. Each source channel preserves emission order; interleaving
* across independent channels is backend-dependent. Bounded only as part of
* the outer result.
*/
logs: string[]
/** Present iff the run failed; see {@link CodeRunFailure} for the taxonomy. */
error?: CodeRunFailure
}
Each CodeBindingNamespace becomes a global object of async callables; PTC passes tools. Arguments and resolutions must be lossless JSON. Providers enforce their own transport caps; the seam sets no uniform binding-byte limit. An optional error-class descriptor creates program-visible typed rejections without naming a consumer inside the runtime. Binding names are own properties, so __proto__ cannot traverse a prototype:
/**
* Program-visible typed rejection for one binding namespace. The runtime
* injects a real error constructor under `name`; rejected member calls become
* its instances and expose the exact member name through
* `memberNameProperty`. Both strings are runtime data rather than knowledge
* of a particular consumer such as PTC mode.
*/
interface CodeBindingErrorClass {
/** Constructor global and resulting `Error.name`; same portable identifier rule as {@link CodeBindingNamespace.global}. */
name: string
/**
* Non-empty own property for the member name. The portable exclusion set is
* `RESERVED_ERROR_MEMBERS` plus dunder-form names (`__x__`, non-empty
* middle), enforced identically by every backend; any other name —
* identifiers or not — is accepted everywhere.
*/
memberNameProperty: string
}
/**
* A named group of {@link CodeBindingFunction}s the runtime exposes to the
* program as one global object (e.g. `tools`). Function names are arbitrary
* strings — a runtime must treat names like `__proto__` or `constructor` as
* ordinary own properties (null-prototype construction), never as prototype
* collisions.
*/
interface CodeBindingNamespace {
/**
* The global identifier the program sees. Must match the LANGUAGE-PORTABLE
* identifier subset `[A-Za-z_][A-Za-z0-9_]*` and no language's reserved
* words, so the same namespace list works against every backend regardless
* of `language` — a JS-only spelling like `$tools` is rejected by design,
* not just by the Python backend. Names that satisfy the identifier rule but
* name a backend-owned slot (`RESERVED_BINDING_GLOBALS`, e.g. `console`,
* `__dsh_main__`) are also refused everywhere; see its declaration for the
* exact set and why each entry is reserved.
*/
global: string
/** The callable members, keyed by the exact name the program calls. */
functions: Record<string, CodeBindingFunction>
/** Optional program-visible typed rejection contract for this namespace. */
errorClass?: CodeBindingErrorClass
}
/** A lossless JSON value transferable through the dependency-light Service Definition. */
type CodeJsonValue = null | boolean | number | string | CodeJsonValue[] | { [key: string]: CodeJsonValue }
/**
* One host-side function exposed to the program as an async callable. The
* runtime bridges calls to it (possibly across a serialization boundary), so
* `args` and the resolution value MUST be lossless JSON. A runtime rejects a
* lossy or non-cloneable value with a descriptive error rather than corrupting
* the run. No seam-level byte cap applies to a binding resolution. A rejection
* of this function surfaces inside the program as a rejection of the
* corresponding call.
*/
type CodeBindingFunction = (args: unknown) => Promise<CodeJsonValue>
Logs are plain strings. Each source channel preserves emission order, while interleaving across independent channels is backend-dependent because channel metadata is not part of the seam. The runtime captures the program's console and stream output, and consumers render only the text. Implementations cap the serialized outer log-array plus completion-value or failure-message payload; fixed result-envelope syntax and consumer presentation whitespace are not part of that variable-payload ledger. Overflow is an explicit failure rather than in-band value substitution.
Failure kinds are orthogonal outcomes reported independently (per defensive-patterns): a budget expiry is not an exception, an abort is not a timeout, and a substrate death (e.g. OOM) is neither:
/**
* Why a run failed. The kinds are orthogonal outcomes reported independently
* (per docs/defensive-patterns.md): a budget expiry is not an exception, an
* abort is not a timeout, and a substrate death is neither.
*
* - `'exception'` — the program threw or failed to parse/transform.
* - `'timeout'` — an implementation-owned budget expired; the message says which.
* - `'abort'` — {@link CodeRunRequest.signal} fired.
* - `'worker-exit'` — the execution substrate died without settling (e.g. OOM).
* - `'invalid-output'` — the completion value was not lossless JSON.
* - `'output-limit'` — the serialized outer logs/value/diagnostic exceeded the configured cap.
*/
interface CodeRunFailure {
/** The failure class (see the interface doc for each kind's meaning). */
kind: 'exception' | 'timeout' | 'abort' | 'worker-exit' | 'invalid-output' | 'output-limit' | 'protocol' | 'sandbox-unavailable'
/** Human-readable detail, suitable for feeding back to a model to self-correct. */
message: string
}
CodeRuntime is defined in src/index.ts. resolve(request) returns complete execution inputs, and run(spec) executes them. language selects supported program presentation; isolation describes the substrate without claiming security. sandboxMode advertises file-policy support, with undefined for a provider that does not supply confinement. Each implementation keeps program state separate between runs and terminates and awaits active executions during disposal.
Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.
ctx.codeRuntime — CodeRuntime (abstract seam)Registers one ctx.codeRuntime implementation. Program, budget, abort, and substrate failures resolve in CodeRunResult; only Service Definition contract misuse rejects. Implementations bridge structured-cloneable bindings, materialize each declared namespace rejection class, treat programs as hostile peers, isolate runs from one another, and terminate and await in-flight runs during disposal.
/**
* Resolve supported options and provider defaults before execution.
* @param request - Program, bindings, cancellation and optional execution choices.
* @returns Complete directory, deadline and supported authority for run.
* @throws When an explicit choice is invalid or unsupported by this provider.
*/
abstract resolve(request: CodeRunRequest): CodeRunSpec
/**
* Execute resolved inputs; program outcomes resolve as result fields.
* @param spec - directory, deadline, program, bindings, cancellation and supported policy.
* @returns Captured output and the execution outcome.
*/
abstract run(spec: CodeRunSpec): Promise<CodeRunResult>