refactor(code-runtime): name the Node runtime provider

This commit is contained in:
Tianyi Cui committed 2026-09-12 15:03:01 +08:00
1 parent b35a3b29eb
commit f95f7ec8dc
68 files changed
+138 -138

No files matched your search

+1 -1
View File
@@ -27,7 +27,7 @@ These three packages together provide program execution; each README describes w
| Package | Role | ctx key |
|---|---|---|
| [`code-runtime/`](code-runtime/README.md) | Defines what a code runtime does: run one program against host-provided bindings and report what it printed and returned | `ctx.codeRuntime` |
| [`code-runtime-worker-thread/`](code-runtime-worker-thread/README.md) | Executes TypeScript programs, each in a fresh Node worker thread | registers `ctx.codeRuntime` |
| [`code-runtime-node/`](code-runtime-node/README.md) | Executes TypeScript programs, each in a fresh Node worker thread | registers `ctx.codeRuntime` |
| [`experimental/code-runtime-python/`](../experimental/code-runtime-python/README.md) | The experimental Python backend: owns the fd-3 wire protocol between a Node host and a CPython subprocess and the CPython runtime implementation | — |
-----
+1 -1
View File
@@ -27,7 +27,7 @@ kind: "package-group"
| 包 | 角色 | ctx 键 |
|---|---|---|
| [`code-runtime/`](code-runtime/README.zh.md) | 定义代码运行时做什么:针对宿主提供的绑定运行一个程序,并报告其打印和返回的内容 | `ctx.codeRuntime` |
| [`code-runtime-worker-thread/`](code-runtime-worker-thread/README.zh.md) | 在全新的 Node Worker 线程中执行 TypeScript 程序 | 注册 `ctx.codeRuntime` |
| [`code-runtime-node/`](code-runtime-node/README.zh.md) | 在全新的 Node Worker 线程中执行 TypeScript 程序 | 注册 `ctx.codeRuntime` |
| [`experimental/code-runtime-python/`](../experimental/code-runtime-python/README.zh.md) | 实验性 Python 后端:负责 Node 宿主与 CPython 子进程之间的 fd-3 协议,以及 CPython 运行时实现 | — |
-----
@@ -1,6 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/code-runtime/code-runtime-worker-thread/README.md
README.md: c26f349762ab2dac9956099ab637cde9d6d93771
README.zh.md: b5ffeac9c06733099001189fb8cc5fa1b60e662b
# pnpm run verify-translation-pairing --write packages/code-runtime/code-runtime-node/README.md
README.md: d03fd010db7d1475cc153632ca28fc83f782704b
README.zh.md: bfc58f8ba0a9adff4a687cc233cc7da56224564a
@@ -3,7 +3,7 @@ description: "Worker-thread code execution for users and maintainers composing,
kind: "package-reference"
---
# @deepseek-ai/dsh-code-runtime-worker-thread
# @deepseek-ai/dsh-code-runtime-node
English | [中文](README.zh.md)
@@ -31,7 +31,7 @@ Mount this backend with the code-runtime seam when a composition should execute
```yaml
- name: '@deepseek-ai/dsh-code-runtime'
- name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- name: '@deepseek-ai/dsh-code-runtime-node'
config:
computeMs: 60000 # busy-time budget (measured event-loop active time)
maxWallMs: 600000 # wall-clock ceiling; never pauses for anything
@@ -46,7 +46,7 @@ Mount this backend with the code-runtime seam when a composition should execute
| `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](../../../docs/config-catalog.md#deepseek-aidsh-code-runtime-worker-thread) is the exhaustive source for every accepted field.
Every field is validated and defaulted at load; there are no other tunables. The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-code-runtime-node) is the exhaustive source for every accepted field.
### What a run returns
@@ -94,7 +94,7 @@ Two independent budgets exist because the peer is hostile: `computeMs` meters th
| File | Role |
|---|---|
| [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, `WorkerThreadCodeRuntime`, run orchestration, output ledger |
| [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, `NodeCodeRuntime`, run orchestration, output ledger |
| [`src/worker.ts`](src/worker.ts) | Source-mode worker entry (erasable TypeScript, no `lib/` dependency) |
| [`src/bootstrap.ts`](src/bootstrap.ts) | Worker-side bootstrap: namespace materialization, console shim, log capture |
| [`src/protocol.ts`](src/protocol.ts) | Port message vocabulary between host and worker |
@@ -118,7 +118,7 @@ Read these when the backend contract is not enough. They move from the seam defi
- [Code runtime seam](../code-runtime/README.md) — the abstract contract this backend implements.
- [PTC mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-ptc.md) — how `dsh-tools` consumes `ctx.codeRuntime` and presents `run_code`.
- [Code runtime subsystem reference](../../../docs/subsystems/code-runtime.md) — request/result vocabulary, bindings, and failure taxonomy.
- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-code-runtime-worker-thread) — every accepted config field and its source declaration.
- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-code-runtime-node) — every accepted config field and its source declaration.
-----
@@ -3,7 +3,7 @@ description: "Worker 线程代码执行,面向组装、容量规划或调试
kind: "package-reference"
---
# @deepseek-ai/dsh-code-runtime-worker-thread
# @deepseek-ai/dsh-code-runtime-node
[English](README.md) | 中文
@@ -31,7 +31,7 @@ kind: "package-reference"
```yaml
- name: '@deepseek-ai/dsh-code-runtime'
- name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- name: '@deepseek-ai/dsh-code-runtime-node'
config:
computeMs: 60000 # busy-time budget (measured event-loop active time)
maxWallMs: 600000 # wall-clock ceiling; never pauses for anything
@@ -46,7 +46,7 @@ kind: "package-reference"
| `maxOutputBytes` | `67,108,864` | 序列化日志加完成值或失败消息的硬上限;至少 `4` |
| `maxOldGenerationSizeMb` | `512` | worker 堆上限;溢出会杀死 worker,并以 `worker-exit` 呈现 |
每个字段在加载时都会验证并提供默认值;没有其他可调项。生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-code-runtime-worker-thread)是所有受支持字段的完整参考。
每个字段在加载时都会验证并提供默认值;没有其他可调项。生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-code-runtime-node)是所有受支持字段的完整参考。
### 运行返回什么
@@ -94,7 +94,7 @@ kind: "package-reference"
| 文件 | 职责 |
|---|---|
| [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、`WorkerThreadCodeRuntime`、运行编排、输出账本 |
| [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、`NodeCodeRuntime`、运行编排、输出账本 |
| [`src/worker.ts`](src/worker.ts) | 源码模式 worker 入口(可擦除 TypeScript,不依赖 `lib/`) |
| [`src/bootstrap.ts`](src/bootstrap.ts) | worker 侧 bootstrap:命名空间物化、console shim、日志捕获 |
| [`src/protocol.ts`](src/protocol.ts) | host 与 worker 之间的端口消息词汇 |
@@ -118,7 +118,7 @@ kind: "package-reference"
- [代码运行时 seam](../code-runtime/README.zh.md)——此后端实现的抽象约定。
- [PTC mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-ptc.zh.md)——`dsh-tools` 如何消费 `ctx.codeRuntime` 并呈现 `run_code`。
- [代码运行时子系统参考](../../../docs/subsystems/code-runtime.zh.md)——请求/结果词汇、绑定与失败分类体系。
- [生成配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-code-runtime-worker-thread)——每个受支持配置字段及其源声明。
- [生成配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-code-runtime-node)——每个受支持配置字段及其源声明。
-----
@@ -1,5 +1,5 @@
{
"name": "@deepseek-ai/dsh-code-runtime-worker-thread",
"name": "@deepseek-ai/dsh-code-runtime-node",
"description": "Worker-thread implementation of the DeepSeek Harness code-execution seam",
"version": "0.1.5-rc.2",
"publishConfig": {
@@ -8,7 +8,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
"directory": "packages/code-runtime/code-runtime-worker-thread"
"directory": "packages/code-runtime/code-runtime-node"
},
"type": "module",
"main": "lib/index.js",
@@ -2,7 +2,7 @@
* Worker-side execution logic, written as plain functions over an injected port so the unit
* suite can run every line IN-PROCESS against a fake port (a real worker thread is a separate
* V8 isolate the coverage provider cannot observe).
* @module @deepseek-ai/dsh-code-runtime-worker-thread/src/bootstrap
* @module @deepseek-ai/dsh-code-runtime-node/src/bootstrap
*/
import { inspect } from 'node:util'
@@ -3,7 +3,7 @@
* and bridges bindings over its message port. This is containment, not a security boundary:
* model code has bash-equivalent trust despite an empty environment, a heap cap, measured
* event-loop busy-time and wall-time budgets, and termination that also stops synchronous loops.
* @module @deepseek-ai/dsh-code-runtime-worker-thread
* @module @deepseek-ai/dsh-code-runtime-node
*/
import { Worker } from 'node:worker_threads'
@@ -235,7 +235,7 @@ class OutputLedger {
* the contract this implements (error-as-field, hostile-peer port,
* no cross-run state, dispose to quiescence).
*/
export class WorkerThreadCodeRuntime extends CodeRuntime {
export class NodeCodeRuntime extends CodeRuntime {
static Config: z<Config> = z.object({
computeMs: z.number().default(60_000),
maxWallMs: z.number().default(600_000),
@@ -256,16 +256,16 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
// semantic check the schema's plain number type does not carry.
this.config = config as ResolvedConfig
for (const [key, value] of Object.entries(this.config)) {
if (!(Number.isFinite(value) && value > 0)) throw new Error(`dsh-code-runtime-worker-thread: config.${key} must be a positive number, got ${String(value)}`)
if (!(Number.isFinite(value) && value > 0)) throw new Error(`dsh-code-runtime-node: config.${key} must be a positive number, got ${String(value)}`)
}
if (!Number.isSafeInteger(this.config.maxOutputBytes) || this.config.maxOutputBytes < MIN_OUTPUT_BYTES) {
throw new Error(`dsh-code-runtime-worker-thread: config.maxOutputBytes must be a safe integer of at least ${MIN_OUTPUT_BYTES}, got ${String(this.config.maxOutputBytes)}`)
throw new Error(`dsh-code-runtime-node: config.maxOutputBytes must be a safe integer of at least ${MIN_OUTPUT_BYTES}, got ${String(this.config.maxOutputBytes)}`)
}
// maxWallMs reaches setTimeout, which clamps any delay above
// MAX_TIMER_DELAY_MS to 1 ms; the positivity check above accepts such a
// value, so a 25-day ceiling would time the run out immediately.
if (this.config.maxWallMs > MAX_TIMER_DELAY_MS) {
throw new Error(`dsh-code-runtime-worker-thread: config.maxWallMs must be at most ${MAX_TIMER_DELAY_MS} (Node clamps a longer setTimeout delay to 1ms), got ${String(this.config.maxWallMs)}`)
throw new Error(`dsh-code-runtime-node: config.maxWallMs must be at most ${MAX_TIMER_DELAY_MS} (Node clamps a longer setTimeout delay to 1ms), got ${String(this.config.maxWallMs)}`)
}
ctx.effect(() => () => this.teardown(), 'worker code-runtime teardown')
}
@@ -291,7 +291,7 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
* @returns the run's outcome per the seam contract.
*/
async run(request: CodeRunRequest): Promise<CodeRunResult> {
if (this.disposed) throw new Error('dsh-code-runtime-worker-thread: run() after disposal')
if (this.disposed) throw new Error('dsh-code-runtime-node: run() after disposal')
const bindings = this.validateBindings(request)
if (request.signal?.aborted) {
return this.failureBeforeWorker({ kind: 'abort', message: String(request.signal.reason) })
@@ -321,7 +321,7 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
const bindings = new Map<string, CodeBindingNamespace>()
for (const namespace of request.bindings) {
if (!IDENTIFIER.test(namespace.global) || PORTABLE_RESERVED_WORDS.has(namespace.global)) {
throw new Error(`dsh-code-runtime-worker-thread: binding global ${JSON.stringify(namespace.global)} is not a usable identifier`)
throw new Error(`dsh-code-runtime-node: binding global ${JSON.stringify(namespace.global)} is not a usable identifier`)
}
// RESERVED_BINDING_GLOBALS is the seam's shared backend-owned set:
// `console` is THIS backend's log-capture slot; the dunder entries exist
@@ -330,10 +330,10 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
// portable across backends. The seam declaration is the single home for
// why each entry is reserved.
if (RESERVED_BINDING_GLOBALS.has(namespace.global)) {
throw new Error(`dsh-code-runtime-worker-thread: reserved binding global ${JSON.stringify(namespace.global)}`)
throw new Error(`dsh-code-runtime-node: reserved binding global ${JSON.stringify(namespace.global)}`)
}
if (bindings.has(namespace.global)) {
throw new Error(`dsh-code-runtime-worker-thread: duplicate binding global ${JSON.stringify(namespace.global)}`)
throw new Error(`dsh-code-runtime-node: duplicate binding global ${JSON.stringify(namespace.global)}`)
}
bindings.set(namespace.global, namespace)
}
@@ -343,17 +343,17 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
const descriptor = namespace.errorClass
if (!descriptor) continue
if (!IDENTIFIER.test(descriptor.name) || PORTABLE_RESERVED_WORDS.has(descriptor.name)) {
throw new Error(`dsh-code-runtime-worker-thread: binding error class ${JSON.stringify(descriptor.name)} is not a usable identifier`)
throw new Error(`dsh-code-runtime-node: binding error class ${JSON.stringify(descriptor.name)} is not a usable identifier`)
}
if (RESERVED_BINDING_GLOBALS.has(descriptor.name)) {
throw new Error(`dsh-code-runtime-worker-thread: reserved binding global ${JSON.stringify(descriptor.name)}`)
throw new Error(`dsh-code-runtime-node: reserved binding global ${JSON.stringify(descriptor.name)}`)
}
if (bindings.has(descriptor.name) || errorClassNames.has(descriptor.name)) {
throw new Error(`dsh-code-runtime-worker-thread: duplicate injected global ${JSON.stringify(descriptor.name)}`)
throw new Error(`dsh-code-runtime-node: duplicate injected global ${JSON.stringify(descriptor.name)}`)
}
const member = descriptor.memberNameProperty
if (member.length === 0 || RESERVED_ERROR_MEMBERS.has(member) || DUNDER_MEMBER.test(member)) {
throw new Error(`dsh-code-runtime-worker-thread: binding error member property ${JSON.stringify(descriptor.memberNameProperty)} is not usable`)
throw new Error(`dsh-code-runtime-node: binding error member property ${JSON.stringify(descriptor.memberNameProperty)} is not usable`)
}
errorClassNames.add(descriptor.name)
}
@@ -558,4 +558,4 @@ export class WorkerThreadCodeRuntime extends CodeRuntime {
}
}
export default WorkerThreadCodeRuntime
export default NodeCodeRuntime
@@ -1,4 +1,4 @@
/** JSON string-prefix accounting for the outer-output ledger. @module @deepseek-ai/dsh-code-runtime-worker-thread/output-json */
/** JSON string-prefix accounting for the outer-output ledger. @module @deepseek-ai/dsh-code-runtime-node/output-json */
import type { CodeJsonValue } from '@deepseek-ai/dsh-code-runtime'
@@ -2,7 +2,7 @@
* Versionless, structured-clone wire protocol between co-shipped host and worker code. The host
* treats inbound traffic as hostile because model code can forge `parentPort` messages; the
* worker trusts host replies.
* @module @deepseek-ai/dsh-code-runtime-worker-thread/src/protocol
* @module @deepseek-ai/dsh-code-runtime-node/src/protocol
*/
import type { WorkerJsonWire } from './worker-json.ts'
@@ -1,6 +1,6 @@
/**
* Lossless-JSON snapshots for the dependency-free source worker closure.
* @module @deepseek-ai/dsh-code-runtime-worker-thread/worker-json
* @module @deepseek-ai/dsh-code-runtime-node/worker-json
*/
import type { CodeJsonValue } from '@deepseek-ai/dsh-code-runtime'
@@ -1,7 +1,7 @@
/**
* Spawn-only worker entrypoint over {@link runWorkerMain}. Executable logic stays in
* `bootstrap.ts` for in-process coverage; real-worker tests cover this glue.
* @module @deepseek-ai/dsh-code-runtime-worker-thread/src/worker
* @module @deepseek-ai/dsh-code-runtime-node/src/worker
*/
import { parentPort, workerData } from 'node:worker_threads'
@@ -9,6 +9,6 @@ import { runWorkerMain } from './bootstrap.ts'
import type { WorkerBootData } from './protocol.ts'
// A worker always has a parent port; guard loudly rather than run detached.
if (!parentPort) throw new Error('dsh-code-runtime-worker-thread: worker entry loaded outside a worker thread')
if (!parentPort) throw new Error('dsh-code-runtime-node: worker entry loaded outside a worker thread')
void runWorkerMain(parentPort, workerData as WorkerBootData, { stdout: process.stdout, stderr: process.stderr })
@@ -1,7 +1,7 @@
/** Host budget decisions use controlled clocks and ELU samples; worker execution and binding transport stay real. */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import { WorkerThreadCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker-thread'
import { NodeCodeRuntime } from '@deepseek-ai/dsh-code-runtime-node'
import type { CodeRunResult } from '@deepseek-ai/dsh-code-runtime'
const meter = vi.hoisted(() => ({ sample: vi.fn() }))
@@ -52,7 +52,7 @@ describe('worker budgets with controlled ELU samples and real binding transport'
})
async function pendingBinding(): Promise<void> {
await ctx.plugin(WorkerThreadCodeRuntime, { computeMs: 1_000, maxWallMs: 30_000 })
await ctx.plugin(NodeCodeRuntime, { computeMs: 1_000, maxWallMs: 30_000 })
let entered!: () => void
const ready = new Promise<void>((resolve) => { entered = resolve })
const binding = new Promise<string>((resolve) => { release = () => { resolve('slow-done') } })
@@ -19,9 +19,9 @@ describe.skipIf(!built)('built lib real load path (plain node)', () => {
it('runs a TypeScript program with a binding through lib/index.js and its lib/worker.cjs entry', async () => {
const script = `
const { Context } = await import('@deepseek-ai/cordis')
const { WorkerThreadCodeRuntime } = await import('@deepseek-ai/dsh-code-runtime-worker-thread')
const { NodeCodeRuntime } = await import('@deepseek-ai/dsh-code-runtime-node')
const ctx = new Context()
await ctx.plugin(WorkerThreadCodeRuntime, {})
await ctx.plugin(NodeCodeRuntime, {})
const result = await ctx.codeRuntime.run({
program: 'const doubled: number = await tools.double({ n: 21 }); console.log("halfway", doubled); let failure; try { await tools.fail({}) } catch (error) { failure = { typed: error instanceof ToolCallError, name: error.name, toolName: error.toolName, message: error.message } } return { doubled, failure };',
bindings: [{
@@ -1,7 +1,7 @@
import { describe, expect, it, onTestFinished } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import { WorkerThreadCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker-thread'
import type { Config } from '@deepseek-ai/dsh-code-runtime-worker-thread'
import { NodeCodeRuntime } from '@deepseek-ai/dsh-code-runtime-node'
import type { Config } from '@deepseek-ai/dsh-code-runtime-node'
import type { CodeBindingFunction, CodeBindingNamespace, CodeRunResult } from '@deepseek-ai/dsh-code-runtime'
/**
@@ -11,8 +11,8 @@ import type { CodeBindingFunction, CodeBindingNamespace, CodeRunResult } from '@
*/
async function setup(config: Config = {}) {
const ctx = new Context()
await ctx.plugin(WorkerThreadCodeRuntime, config)
const runtime = ctx.codeRuntime as WorkerThreadCodeRuntime
await ctx.plugin(NodeCodeRuntime, config)
const runtime = ctx.codeRuntime as NodeCodeRuntime
return { ctx, runtime }
}
@@ -25,7 +25,7 @@ function tools(functions: Record<string, (args: unknown) => Promise<unknown>>):
}]
}
describe('WorkerThreadCodeRuntime — programs and bindings (real workers)', () => {
describe('NodeCodeRuntime — programs and bindings (real workers)', () => {
it('registers with the seam descriptors', async () => {
const { runtime } = await setup()
expect(runtime.language).toBe('typescript')
@@ -170,7 +170,7 @@ describe('WorkerThreadCodeRuntime — programs and bindings (real workers)', ()
})
})
describe('WorkerThreadCodeRuntime — budgets and containment (real workers)', () => {
describe('NodeCodeRuntime — budgets and containment (real workers)', () => {
it('ends a hot loop at the compute budget — including behind a pending decoy dispatch', async () => {
const { runtime } = await setup({ computeMs: 300, maxWallMs: 30_000 })
const result = await runtime.run({
@@ -447,7 +447,7 @@ describe('WorkerThreadCodeRuntime — budgets and containment (real workers)', (
}, 15_000)
})
describe('WorkerThreadCodeRuntime — hostile programs (real workers)', () => {
describe('NodeCodeRuntime — hostile programs (real workers)', () => {
it('survives forged port traffic: unknown binding names, duplicate ids, junk shapes', async () => {
const { runtime } = await setup()
const result = await runtime.run({
@@ -790,7 +790,7 @@ describe('WorkerThreadCodeRuntime — hostile programs (real workers)', () => {
})
})
describe('WorkerThreadCodeRuntime — seam misuse and lifecycle', () => {
describe('NodeCodeRuntime — seam misuse and lifecycle', () => {
it('rejects invalid and duplicate binding globals loudly', async () => {
const { runtime } = await setup()
const cases: [string, RegExp][] = [
@@ -853,23 +853,23 @@ describe('WorkerThreadCodeRuntime — seam misuse and lifecycle', () => {
it('rejects config values that are not positive numbers', async () => {
const ctx = new Context()
await expect(ctx.plugin(WorkerThreadCodeRuntime, { computeMs: -1 })).rejects.toThrow(/positive number/)
await expect(ctx.plugin(NodeCodeRuntime, { computeMs: -1 })).rejects.toThrow(/positive number/)
})
it('rejects a maxWallMs above Node\'s maximum timer delay', async () => {
// setTimeout clamps a delay past 2^31-1 ms to 1 ms, so the positivity check
// alone would accept a 25-day ceiling that expires on the first tick.
const ctx = new Context()
await expect(ctx.plugin(WorkerThreadCodeRuntime, { maxWallMs: 2_147_483_648 }))
await expect(ctx.plugin(NodeCodeRuntime, { maxWallMs: 2_147_483_648 }))
.rejects.toThrow(/maxWallMs must be at most 2147483647/)
// The boundary itself is usable.
await expect(ctx.plugin(WorkerThreadCodeRuntime, { maxWallMs: 2_147_483_647 })).resolves.toBeTruthy()
await expect(ctx.plugin(NodeCodeRuntime, { maxWallMs: 2_147_483_647 })).resolves.toBeTruthy()
})
it('requires maxOutputBytes to fit the smallest counted outer payloads', async () => {
const ctx = new Context()
await expect(ctx.plugin(WorkerThreadCodeRuntime, { maxOutputBytes: 3 })).rejects.toThrow(/safe integer of at least 4/)
await expect(ctx.plugin(WorkerThreadCodeRuntime, { maxOutputBytes: 4.5 })).rejects.toThrow(/safe integer of at least 4/)
await expect(ctx.plugin(NodeCodeRuntime, { maxOutputBytes: 3 })).rejects.toThrow(/safe integer of at least 4/)
await expect(ctx.plugin(NodeCodeRuntime, { maxOutputBytes: 4.5 })).rejects.toThrow(/safe integer of at least 4/)
})
it('keeps runs isolated: no state survives from one run to the next', async () => {
@@ -881,8 +881,8 @@ describe('WorkerThreadCodeRuntime — seam misuse and lifecycle', () => {
it('disposal aborts in-flight runs, awaits worker exit, and rejects later runs', async () => {
const ctx = new Context()
const fiber = await ctx.plugin(WorkerThreadCodeRuntime)
const runtime = ctx.codeRuntime as WorkerThreadCodeRuntime
const fiber = await ctx.plugin(NodeCodeRuntime)
const runtime = ctx.codeRuntime as NodeCodeRuntime
const inflight: Promise<CodeRunResult> = runtime.run({ program: 'for (;;) {}', bindings: [] })
// Give the worker a moment to actually start spinning.
await new Promise(resolve => setTimeout(resolve, 200))
@@ -894,8 +894,8 @@ describe('WorkerThreadCodeRuntime — seam misuse and lifecycle', () => {
it('removes ctx.codeRuntime when the providing fiber disposes (HMR safety)', async () => {
const ctx = new Context()
const fiber = await ctx.plugin(WorkerThreadCodeRuntime)
expect(ctx.get('codeRuntime')).toBeInstanceOf(WorkerThreadCodeRuntime)
const fiber = await ctx.plugin(NodeCodeRuntime)
expect(ctx.get('codeRuntime')).toBeInstanceOf(NodeCodeRuntime)
await fiber.dispose()
expect(ctx.get('codeRuntime')).toBeUndefined()
})
+2 -2
View File
@@ -41,7 +41,7 @@ const result = await ctx.codeRuntime.run({
### Choose a backend
Backends declare two descriptors you can rely on: `language` — what the program must be written in, with `'typescript'` and `'python'` as the well-known values — and `isolation` — the execution substrate (`'worker-thread'`, `'process'`, `'container'`), a label for deployments and diagnostics, not a security claim. [`dsh-code-runtime-worker-thread`](../code-runtime-worker-thread/README.md) executes TypeScript in a fresh Node worker thread; the private [`dsh-experimental-code-runtime-python`](../../experimental/code-runtime-python/README.md) package executes Python in a fresh CPython subprocess for opt-in compositions.
Backends declare two descriptors you can rely on: `language` — what the program must be written in, with `'typescript'` and `'python'` as the well-known values — and `isolation` — the execution substrate (`'worker-thread'`, `'process'`, `'container'`), a label for deployments and diagnostics, not a security claim. [`dsh-code-runtime-node`](../code-runtime-node/README.md) executes TypeScript in a fresh Node worker thread; the private [`dsh-experimental-code-runtime-python`](../../experimental/code-runtime-python/README.md) package executes Python in a fresh CPython subprocess for opt-in compositions.
### Name your bindings portably
@@ -97,7 +97,7 @@ Binding-global and error-class names are language-portable: they must match the
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.
- [PTC mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-ptc.md) — how the tool registry consumes `ctx.codeRuntime` and presents `run_code` to the model.
- [Worker-thread backend](../code-runtime-worker-thread/README.md) — the shipped TypeScript execution backend.
- [Worker-thread backend](../code-runtime-node/README.md) — the shipped TypeScript execution backend.
- [Experimental Python backend](../../experimental/code-runtime-python/README.md) — the private CPython subprocess provider and its fd-3 protocol.
- [Code runtime subsystem reference](../../../docs/subsystems/code-runtime.md) — request/result vocabulary, bindings, and the `ctx.codeRuntime` cordis surface.
- [Capability seams](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) — the Service Definition / Service Provider / Consumer split.
@@ -41,7 +41,7 @@ const result = await ctx.codeRuntime.run({
### 选择后端
后端声明两个你可以依赖的描述符:`language`——程序必须使用的源语言,已知值为 `'typescript'` 与 `'python'`——以及 `isolation`——执行基底(`'worker-thread'`、`'process'`、`'container'`),仅供部署与诊断使用,不构成安全声明。[`dsh-code-runtime-worker-thread`](../code-runtime-worker-thread/README.zh.md) 在全新的 Node Worker 线程中执行 TypeScript;私有的 [`dsh-experimental-code-runtime-python`](../../experimental/code-runtime-python/README.zh.md) 包在全新的 CPython 子进程中执行 Python,供选择性组合使用。
后端声明两个你可以依赖的描述符:`language`——程序必须使用的源语言,已知值为 `'typescript'` 与 `'python'`——以及 `isolation`——执行基底(`'worker-thread'`、`'process'`、`'container'`),仅供部署与诊断使用,不构成安全声明。[`dsh-code-runtime-node`](../code-runtime-node/README.zh.md) 在全新的 Node Worker 线程中执行 TypeScript;私有的 [`dsh-experimental-code-runtime-python`](../../experimental/code-runtime-python/README.zh.md) 包在全新的 CPython 子进程中执行 Python,供选择性组合使用。
### 可移植地命名绑定
@@ -97,7 +97,7 @@ binding-global 与 error-class 名称是语言可移植的:必须匹配标识
当包级约定不够用时阅读以下内容。它们从 PTC mode 消费方进入后端与能力 seam 模型。
- [PTC mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-ptc.zh.md)——工具注册表如何消费 `ctx.codeRuntime` 并把 `run_code` 呈现给模型。
- [Worker 线程后端](../code-runtime-worker-thread/README.zh.md)——已发布的 TypeScript 执行后端。
- [Worker 线程后端](../code-runtime-node/README.zh.md)——已发布的 TypeScript 执行后端。
- [实验性 Python 后端](../../experimental/code-runtime-python/README.zh.md)——私有的 CPython 子进程提供方及其 fd-3 协议。
- [代码运行时子系统参考](../../../docs/subsystems/code-runtime.zh.md)——请求/结果词汇、绑定与 `ctx.codeRuntime` 的 cordis 接口面。
- [能力 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.zh.md)——Service Definition / Service Provider / Consumer 拆分。