description: "Worker-thread code execution for users and maintainers composing, sizing, or debugging the shipped TypeScript backend that runs each program in a fresh Node worker."
English | 中文
dsh-code-runtime-worker-thread executes TypeScript programs for the dsh-code-runtime seam: each program runs in one fresh Node worker thread with host-provided bindings callable as ordinary async functions, and the run returns { value, logs, error? }. It is the shipped backend for PTC mode in dsh-tools, so mounting it is what makes model-written TypeScript execution work in a composition. The runtime contains a program without isolating it: the trust posture is bash-equivalent, with an empty environment, a heap cap, measured busy-time and wall-clock budgets, and hard termination. Programs run once per request with no state carried between runs, and every failure — syntax error, budget expiry, abort, OOM exit, or output overflow — comes back as a result field.
Mount this backend with the code-runtime seam when a composition should execute model-written TypeScript programs; PTC mode in dsh-tools then drives it through ctx.codeRuntime whenever the model calls run_code. Every execution cap is validated config, so you can size the runtime for your deployment from cordis.yml.
- name: '@deepseek-ai/dsh-code-runtime'
- name: '@deepseek-ai/dsh-code-runtime-worker-thread'
config:
computeMs: 60000 # busy-time budget (measured event-loop active time)
maxWallMs: 600000 # wall-clock ceiling; never pauses for anything
maxOutputBytes: 67108864 # combined serialized outer-output cap (64 MiB)
maxOldGenerationSizeMb: 512 # worker heap cap
| Field | Default | Meaning |
|---|---|---|
computeMs |
60,000 |
Busy-time budget: the run fails with timeout once the worker's measured event-loop active time exceeds it |
maxWallMs |
600,000 |
Wall-clock ceiling, the backstop for waits that busy time cannot see; at most 2_147_483_647 |
maxOutputBytes |
67,108,864 |
Hard cap for serialized logs plus the completion value or failure message; at least 4 |
maxOldGenerationSizeMb |
512 |
Worker heap cap; overflow kills the worker and surfaces as worker-exit |
Every field is validated and defaulted at load; there are no other tunables. The generated configuration catalog is the exhaustive source for every accepted field.
A successful run returns the program's lossless-JSON completion value as result.value and the text it printed, in order, as result.logs. Top-level await and return work, and the program can call the host-provided binding functions (PTC mode exposes one tools object) as ordinary async calls.
A program runs with authority comparable to the bash tool: it can reach Node APIs, and the backend deliberately does not promise isolation from the host. What it does provide is containment — a separate isolate, an empty environment (no ambient credentials, no inherited loader flags), a configurable heap cap, and hard termination that also stops a hot synchronous loop. OS processes a program spawns survive terminate() and need deployment-level cleanup.
Every program outcome resolves as a result, so a failed run is a result.error, not a rejection: a syntax error or non-erasable TypeScript (enum, namespaces) fails as exception before any worker spawns; budget expiry is timeout; the abort signal is abort; a heap overflow or other worker death is worker-exit; a completion value that is not lossless JSON is invalid-output; and serialized output beyond the cap is output-limit — with the fitting captured log prefix retained. Rejection means caller misuse, such as a run submitted after disposal.
Read these when the backend contract is not enough. They move from the seam definition to the consumer and the configuration surface.
dsh-tools consumes ctx.codeRuntime and presents run_code.Indirectly, through PTC mode in dsh-tools, which renders the exact outer value when it fits or an explicit invalid-output / output-limit failure, while only the outer run_code result enters model context under its ordinary spill policy and binding traffic plus intermediate values remain execution-local.
No direct invalidation; the named consumer owns any request-prefix changes.
These limits define when the backend is a poor fit or needs special operational care. They are current package constraints, not a task backlog.
worker.terminate() ends the thread only, weaker than bash-local's process-group kill; orphan cleanup is a deployment concern until a container backend exists.stripTypeScriptTypes API — amaro or sucrase are the named drop-in replacements if the relied-on behavior shifts.computeMs expiry can overshoot by up to one poll interval — busy time is sampled every 25 ms (an internal constant, deliberately not config).console shim (log/info/warn/error/debug) — deliberately not Node's full console API.output-limit; bytes rejected beyond the runtime cap never reach the spill layer.