mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
refactor: apply repository naming contract
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# 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/README.md
|
||||
README.md: 024dea980b1678ca7d375bad4d4a627b4956bb02
|
||||
README.zh.md: 8dcfe84fa0aca950fb831a34d4a0d3894dfa37f7
|
||||
README.md: 6f91a163dea33b39875c76885e82ff5d7448bad4
|
||||
README.zh.md: 6515ba02a04c4bf0660591b65cd2dd0a11ad03b1
|
||||
|
||||
@@ -7,7 +7,7 @@ The code-execution capability seam (see [capability seams](../../.agents/notes/i
|
||||
| Package | Role | ctx key |
|
||||
|---|---|---|
|
||||
| [`code-runtime/`](code-runtime/README.md) | Service Definition and shared vocabulary | `ctx.codeRuntime` |
|
||||
| [`code-runtime-worker/`](code-runtime-worker/README.md) | Worker-thread backend | registers `ctx.codeRuntime` |
|
||||
| [`code-runtime-worker/`](code-runtime-worker-thread/README.md) | Worker-thread backend | registers `ctx.codeRuntime` |
|
||||
|
||||
Providers register the service without changing its Consumer. The child READMEs own language, isolation, and execution-budget details.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
| 包 | 职责 | ctx key |
|
||||
|---|---|---|
|
||||
| [`code-runtime/`](code-runtime/README.md) | Service Definition 与共享词汇 | `ctx.codeRuntime` |
|
||||
| [`code-runtime-worker/`](code-runtime-worker/README.md) | Worker 线程后端 | 注册 `ctx.codeRuntime` |
|
||||
| [`code-runtime-worker/`](code-runtime-worker-thread/README.md) | Worker 线程后端 | 注册 `ctx.codeRuntime` |
|
||||
|
||||
提供方在不改变Consumer的情况下注册该服务。子 README 负责语言、隔离和执行预算细节。
|
||||
|
||||
|
||||
@@ -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/README.md
|
||||
README.md: 44ba6a98169057f24d55f41cf3ca7b9f68bb329c
|
||||
README.zh.md: e45aa484c0935d5b4b1626f5c4c7c72482cd5b5d
|
||||
# pnpm run verify-translation-pairing --write packages/code-runtime/code-runtime-worker-thread/README.md
|
||||
README.md: 5507faee57a5d6cd53a1429fa426d2b876046b87
|
||||
README.zh.md: 7ae76e4ca65fc92bd181b1c45f4d4d9b840ba12b
|
||||
@@ -1,14 +1,14 @@
|
||||
# @deepseek-ai/dsh-code-runtime-worker
|
||||
# @deepseek-ai/dsh-code-runtime-worker-thread
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Worker-thread implementation of the [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam: `WorkerCodeRuntime` runs each program in ONE fresh Node `worker_threads.Worker` — TypeScript in, type-stripped host-side, bindings bridged over the message port, `{ value, logs, error? }` out. **Containment, not a security boundary**: trust posture is bash-equivalent by design (the [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) § Trust posture), with containment bash does not have — separate isolate, empty environment, heap cap, hard termination.
|
||||
Worker-thread implementation of the [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam: `WorkerThreadCodeRuntime` runs each program in ONE fresh Node `worker_threads.Worker` — TypeScript in, type-stripped host-side, bindings bridged over the message port, `{ value, logs, error? }` out. **Containment, not a security boundary**: trust posture is bash-equivalent by design (the [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) § Trust posture), with containment bash does not have — separate isolate, empty environment, heap cap, hard termination.
|
||||
|
||||
## Config
|
||||
|
||||
```yaml
|
||||
- id: code-runtime
|
||||
name: '@deepseek-ai/dsh-code-runtime-worker'
|
||||
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
|
||||
@@ -34,7 +34,7 @@ Every field is validated and defaulted; `maxOutputBytes` is a safe integer of at
|
||||
|
||||
Source mode loads erasable-only `src/worker.ts` through Node's native type stripping. Its transitive runtime closure contains only Node built-ins and relative source modules, so a fresh checkout never requires a sibling workspace package's unbuilt `lib/` export. The worker-local and session-owned JSON boundaries both flatten and rebuild validated values around the message port so application nesting never reaches structured clone. Built mode passes the sibling `lib/worker.cjs` as a filesystem path because pkg's VFS Worker hook expects CommonJS; the same path works under ordinary Node. The repository-wide requirement to exercise this published entry path belongs to the [testing policy](../../../docs/testing.md).
|
||||
|
||||
The SDK API is the default/named `WorkerCodeRuntime` class plus `Config`. The operational `./worker` subpath exists only as the packaged spawn entry; the wire protocol and bootstrap helpers are source-private implementation details.
|
||||
The SDK API is the default/named `WorkerThreadCodeRuntime` class plus `Config`. The operational `./worker` subpath exists only as the packaged spawn entry; the wire protocol and bootstrap helpers are source-private implementation details.
|
||||
|
||||
## Model Experience
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# @deepseek-ai/dsh-code-runtime-worker
|
||||
# @deepseek-ai/dsh-code-runtime-worker-thread
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
这是 [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam 的 worker 线程实现:`WorkerCodeRuntime` 会在每次运行中使用一个全新的 Node `worker_threads.Worker`,输入 TypeScript,由宿主侧剥离类型,通过消息端口桥接绑定,输出 `{ value, logs, error? }`。**这是隔离措施,而非安全边界**:其信任立场有意与 bash 等价(参见 [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 的 Trust posture 章节),但提供 bash 没有的隔离:独立 isolate、空环境、堆上限与强制终止。
|
||||
这是 [`@deepseek-ai/dsh-code-runtime`](../code-runtime/README.md) seam 的 worker 线程实现:`WorkerThreadCodeRuntime` 会在每次运行中使用一个全新的 Node `worker_threads.Worker`,输入 TypeScript,由宿主侧剥离类型,通过消息端口桥接绑定,输出 `{ value, logs, error? }`。**这是隔离措施,而非安全边界**:其信任立场有意与 bash 等价(参见 [Code Mode Agent Note](../../../.agents/notes/implemented/feature/2026-06-15-code-mode.md) 的 Trust posture 章节),但提供 bash 没有的隔离:独立 isolate、空环境、堆上限与强制终止。
|
||||
|
||||
## 配置
|
||||
|
||||
```yaml
|
||||
- id: code-runtime
|
||||
name: '@deepseek-ai/dsh-code-runtime-worker'
|
||||
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
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
源代码模式通过 Node 原生类型剥离加载只包含可擦除语法的 `src/worker.ts`。其传递运行时闭包只包含 Node 内置模块和相对源模块,因此全新 checkout 绝不需要兄弟工作区包尚未构建的 `lib/` 导出。worker 本地和会话自有的 JSON 边界都会在消息端口两侧展平并重建已验证值,使应用嵌套永远不会进入 structured clone。构建模式会把兄弟文件 `lib/worker.cjs` 作为文件系统路径传入,因为 pkg 的虚拟文件系统(VFS)Worker hook 要求 CommonJS;同一路径也可在普通 Node 下使用。对这个已发布入口路径进行测试的仓库级要求由[测试策略](../../../docs/testing.md)规定。
|
||||
|
||||
SDK 对外提供默认及具名导出的 `WorkerCodeRuntime` 类,以及 `Config`。运行所用的 `./worker` 子路径仅作为打包后的 spawn 入口存在;wire 协议与启动辅助模块是源代码私有的实现细节。
|
||||
SDK 对外提供默认及具名导出的 `WorkerThreadCodeRuntime` 类,以及 `Config`。运行所用的 `./worker` 子路径仅作为打包后的 spawn 入口存在;wire 协议与启动辅助模块是源代码私有的实现细节。
|
||||
|
||||
## 模型体验
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@deepseek-ai/dsh-code-runtime-worker",
|
||||
"name": "@deepseek-ai/dsh-code-runtime-worker-thread",
|
||||
"description": "Worker-thread implementation of the DeepSeek Harness code-execution seam",
|
||||
"version": "0.0.1-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"
|
||||
"directory": "packages/code-runtime/code-runtime-worker-thread"
|
||||
},
|
||||
"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/src/bootstrap
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread/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
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread
|
||||
*/
|
||||
|
||||
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 WorkerCodeRuntime extends CodeRuntime {
|
||||
export class WorkerThreadCodeRuntime 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 WorkerCodeRuntime 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: config.${key} must be a positive number, got ${String(value)}`)
|
||||
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.isSafeInteger(this.config.maxOutputBytes) || this.config.maxOutputBytes < MIN_OUTPUT_BYTES) {
|
||||
throw new Error(`dsh-code-runtime-worker: config.maxOutputBytes must be a safe integer of at least ${MIN_OUTPUT_BYTES}, got ${String(this.config.maxOutputBytes)}`)
|
||||
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)}`)
|
||||
}
|
||||
// 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: 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-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)}`)
|
||||
}
|
||||
ctx.effect(() => () => this.teardown(), 'worker code-runtime teardown')
|
||||
}
|
||||
@@ -291,7 +291,7 @@ export class WorkerCodeRuntime 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: run() after disposal')
|
||||
if (this.disposed) throw new Error('dsh-code-runtime-worker-thread: 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 WorkerCodeRuntime 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: binding global ${JSON.stringify(namespace.global)} is not a usable identifier`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: 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 WorkerCodeRuntime 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: reserved binding global ${JSON.stringify(namespace.global)}`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: reserved binding global ${JSON.stringify(namespace.global)}`)
|
||||
}
|
||||
if (bindings.has(namespace.global)) {
|
||||
throw new Error(`dsh-code-runtime-worker: duplicate binding global ${JSON.stringify(namespace.global)}`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: duplicate binding global ${JSON.stringify(namespace.global)}`)
|
||||
}
|
||||
bindings.set(namespace.global, namespace)
|
||||
}
|
||||
@@ -343,17 +343,17 @@ export class WorkerCodeRuntime 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: binding error class ${JSON.stringify(descriptor.name)} is not a usable identifier`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: 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: reserved binding global ${JSON.stringify(descriptor.name)}`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: reserved binding global ${JSON.stringify(descriptor.name)}`)
|
||||
}
|
||||
if (bindings.has(descriptor.name) || errorClassNames.has(descriptor.name)) {
|
||||
throw new Error(`dsh-code-runtime-worker: duplicate injected global ${JSON.stringify(descriptor.name)}`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: 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: binding error member property ${JSON.stringify(descriptor.memberNameProperty)} is not usable`)
|
||||
throw new Error(`dsh-code-runtime-worker-thread: binding error member property ${JSON.stringify(descriptor.memberNameProperty)} is not usable`)
|
||||
}
|
||||
errorClassNames.add(descriptor.name)
|
||||
}
|
||||
@@ -558,4 +558,4 @@ export class WorkerCodeRuntime extends CodeRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
export default WorkerCodeRuntime
|
||||
export default WorkerThreadCodeRuntime
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* Package-owned invariant companion for `@deepseek-ai/dsh-code-runtime-worker`.
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker/invariant
|
||||
* Package-owned invariant companion for `@deepseek-ai/dsh-code-runtime-worker-thread`.
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread/invariant
|
||||
*/
|
||||
|
||||
/* jscpd:ignore-start */
|
||||
import type { Context } from '@deepseek-ai/cordis'
|
||||
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
|
||||
|
||||
const PACKAGE_NAME = '@deepseek-ai/dsh-code-runtime-worker'
|
||||
const PACKAGE_NAME = '@deepseek-ai/dsh-code-runtime-worker-thread'
|
||||
|
||||
/** Cordis companion plugin name. */
|
||||
export const name = 'code-runtime-worker-invariant'
|
||||
export const name = 'code-runtime-worker-thread-invariant'
|
||||
/** Service required before the companion can reserve package ownership. */
|
||||
export const inject = ['invariants']
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** JSON string-prefix accounting for the outer-output ledger. @module @deepseek-ai/dsh-code-runtime-worker/output-json */
|
||||
/** JSON string-prefix accounting for the outer-output ledger. @module @deepseek-ai/dsh-code-runtime-worker-thread/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/src/protocol
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread/src/protocol
|
||||
*/
|
||||
|
||||
import type { WorkerJsonWire } from './worker-json.ts'
|
||||
@@ -1,4 +1,7 @@
|
||||
/** Lossless-JSON snapshots for the dependency-free source worker closure. @module @deepseek-ai/dsh-code-runtime-worker/worker-json */
|
||||
/**
|
||||
* Lossless-JSON snapshots for the dependency-free source worker closure.
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread/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/src/worker
|
||||
* @module @deepseek-ai/dsh-code-runtime-worker-thread/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: worker entry loaded outside a worker thread')
|
||||
if (!parentPort) throw new Error('dsh-code-runtime-worker-thread: worker entry loaded outside a worker thread')
|
||||
|
||||
void runWorkerMain(parentPort, workerData as WorkerBootData, { stdout: process.stdout, stderr: process.stderr })
|
||||
@@ -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 { WorkerCodeRuntime } = await import('@deepseek-ai/dsh-code-runtime-worker')
|
||||
const { WorkerThreadCodeRuntime } = await import('@deepseek-ai/dsh-code-runtime-worker-thread')
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(WorkerCodeRuntime, {})
|
||||
await ctx.plugin(WorkerThreadCodeRuntime, {})
|
||||
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 } from 'vitest'
|
||||
import { Context } from '@deepseek-ai/cordis'
|
||||
import { WorkerCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker'
|
||||
import type { Config } from '@deepseek-ai/dsh-code-runtime-worker'
|
||||
import { WorkerThreadCodeRuntime } from '@deepseek-ai/dsh-code-runtime-worker-thread'
|
||||
import type { Config } from '@deepseek-ai/dsh-code-runtime-worker-thread'
|
||||
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(WorkerCodeRuntime, config)
|
||||
const runtime = ctx.codeRuntime as WorkerCodeRuntime
|
||||
await ctx.plugin(WorkerThreadCodeRuntime, config)
|
||||
const runtime = ctx.codeRuntime as WorkerThreadCodeRuntime
|
||||
return { ctx, runtime }
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ function tools(functions: Record<string, (args: unknown) => Promise<unknown>>):
|
||||
}]
|
||||
}
|
||||
|
||||
describe('WorkerCodeRuntime — programs and bindings (real workers)', () => {
|
||||
describe('WorkerThreadCodeRuntime — 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('WorkerCodeRuntime — programs and bindings (real workers)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('WorkerCodeRuntime — budgets and containment (real workers)', () => {
|
||||
describe('WorkerThreadCodeRuntime — 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({
|
||||
@@ -438,7 +438,7 @@ describe('WorkerCodeRuntime — budgets and containment (real workers)', () => {
|
||||
}, 15_000)
|
||||
})
|
||||
|
||||
describe('WorkerCodeRuntime — hostile programs (real workers)', () => {
|
||||
describe('WorkerThreadCodeRuntime — 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({
|
||||
@@ -781,7 +781,7 @@ describe('WorkerCodeRuntime — hostile programs (real workers)', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('WorkerCodeRuntime — seam misuse and lifecycle', () => {
|
||||
describe('WorkerThreadCodeRuntime — seam misuse and lifecycle', () => {
|
||||
it('rejects invalid and duplicate binding globals loudly', async () => {
|
||||
const { runtime } = await setup()
|
||||
const cases: [string, RegExp][] = [
|
||||
@@ -844,23 +844,23 @@ describe('WorkerCodeRuntime — seam misuse and lifecycle', () => {
|
||||
|
||||
it('rejects config values that are not positive numbers', async () => {
|
||||
const ctx = new Context()
|
||||
await expect(ctx.plugin(WorkerCodeRuntime, { computeMs: -1 })).rejects.toThrow(/positive number/)
|
||||
await expect(ctx.plugin(WorkerThreadCodeRuntime, { 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(WorkerCodeRuntime, { maxWallMs: 2_147_483_648 }))
|
||||
await expect(ctx.plugin(WorkerThreadCodeRuntime, { maxWallMs: 2_147_483_648 }))
|
||||
.rejects.toThrow(/maxWallMs must be at most 2147483647/)
|
||||
// The boundary itself is usable.
|
||||
await expect(ctx.plugin(WorkerCodeRuntime, { maxWallMs: 2_147_483_647 })).resolves.toBeTruthy()
|
||||
await expect(ctx.plugin(WorkerThreadCodeRuntime, { 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(WorkerCodeRuntime, { maxOutputBytes: 3 })).rejects.toThrow(/safe integer of at least 4/)
|
||||
await expect(ctx.plugin(WorkerCodeRuntime, { maxOutputBytes: 4.5 })).rejects.toThrow(/safe integer of at least 4/)
|
||||
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/)
|
||||
})
|
||||
|
||||
it('keeps runs isolated: no state survives from one run to the next', async () => {
|
||||
@@ -872,8 +872,8 @@ describe('WorkerCodeRuntime — 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(WorkerCodeRuntime)
|
||||
const runtime = ctx.codeRuntime as WorkerCodeRuntime
|
||||
const fiber = await ctx.plugin(WorkerThreadCodeRuntime)
|
||||
const runtime = ctx.codeRuntime as WorkerThreadCodeRuntime
|
||||
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))
|
||||
@@ -885,8 +885,8 @@ describe('WorkerCodeRuntime — 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(WorkerCodeRuntime)
|
||||
expect(ctx.get('codeRuntime')).toBeInstanceOf(WorkerCodeRuntime)
|
||||
const fiber = await ctx.plugin(WorkerThreadCodeRuntime)
|
||||
expect(ctx.get('codeRuntime')).toBeInstanceOf(WorkerThreadCodeRuntime)
|
||||
await fiber.dispose()
|
||||
expect(ctx.get('codeRuntime')).toBeUndefined()
|
||||
})
|
||||
@@ -24,7 +24,7 @@
|
||||
"path": "../code-runtime"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
},
|
||||
{
|
||||
"path": "../../util/timeout"
|
||||
@@ -15,7 +15,7 @@
|
||||
"path": "../../../vendor/cordis"
|
||||
},
|
||||
{
|
||||
"path": "../../support/invariants"
|
||||
"path": "../../runtime-diagnostics/invariants"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user