mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
docs: rebalance prose cleanup and add trimming skill
This commit is contained in:
@@ -92,7 +92,9 @@ export function makeConsoleShim(logs: LogBuffer): Record<(typeof CONSOLE_LEVELS)
|
||||
/**
|
||||
* Redirect a stream's `write` into the log buffer (the program-visible
|
||||
* `process.stdout`/`process.stderr` in the real worker), so raw writes land in emission order
|
||||
* alongside console output instead of racing down a pipe.
|
||||
* alongside console output instead of racing down a pipe. It preserves Node's optional callback
|
||||
* contract: the callback runs asynchronously after admission, even when the log budget drops
|
||||
* the write.
|
||||
*
|
||||
* @param logs - the buffer captured writes are pushed into.
|
||||
* @param stream - the stream whose `write` slot is patched.
|
||||
@@ -147,7 +149,8 @@ export function truncateUtf8Bytes(text: string, maxBytes: number): string {
|
||||
* Prepare the program's completion value for the done message: a value whose MEASURED
|
||||
* cross-boundary size fits `maxValueBytes` crosses raw — exact bytes for a string, the
|
||||
* structured-clone wire size (`v8.serialize`) for everything else, so a huge container whose
|
||||
* BOUNDED inspect rendering happens to be small cannot smuggle itself past the cap.
|
||||
* bounded inspect rendering happens to be small cannot smuggle itself past the cap. Oversized
|
||||
* or non-cloneable values are replaced by a bounded string rendering with an in-band marker.
|
||||
*
|
||||
* @param value - the program's completion value.
|
||||
* @param maxValueBytes - the byte cap for the value.
|
||||
@@ -205,6 +208,7 @@ export function wireReplies(port: BootstrapPort, pending: Map<number, PendingCal
|
||||
* Build the binding namespace objects the program sees: one null-prototype global per
|
||||
* namespace, each declared name an own enumerable async function that bridges over the port
|
||||
* (`__proto__`/`constructor`/`toString` are ordinary keys, never prototype collisions).
|
||||
* Non-cloneable arguments and host failure replies reject only the corresponding call.
|
||||
*
|
||||
* @param data - the boot payload's namespace declarations (globals + names).
|
||||
* @param port - the port binding calls are posted to.
|
||||
@@ -240,7 +244,8 @@ export function makeNamespaces(
|
||||
}
|
||||
|
||||
/**
|
||||
* Run one program and post its terminal {@link DoneMessage}.
|
||||
* Run one strict async-function body, allowing top-level `await` and `return`, and post exactly
|
||||
* one terminal {@link DoneMessage}; a thrown program error becomes its `error` field.
|
||||
* @param port - host message port or test double.
|
||||
* @param data - the boot payload the host sent.
|
||||
* @param streams - stdout/stderr objects captured as program logs.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Worker-thread implementation of the code-execution seam: one fresh Node worker per run,
|
||||
* executing the model's TypeScript after a host-side type-strip, with bindings bridged over
|
||||
* the message port.
|
||||
* Worker-thread code runtime: a fresh worker runs each host-type-stripped TypeScript program
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -289,9 +290,8 @@ export class WorkerCodeRuntime extends CodeRuntime {
|
||||
const logs: CodeLogEntry[] = []
|
||||
const strayLogs: CodeLogEntry[] = []
|
||||
|
||||
// one host-side ledger for everything that lands in `logs`/`strayLogs`, whatever the
|
||||
// path: honest port entries, FORGED port entries (model code posting `log` messages
|
||||
// directly, bypassing the worker-side LogBuffer), and stray pipe bytes.
|
||||
// One host-side budget covers normal, forged, and stray-pipe log entries. The first
|
||||
// overflow emits the shared in-band marker and drops everything after it.
|
||||
let logBudget = this.config.maxLogBytes
|
||||
let logsTruncated = false
|
||||
const admit = (entry: CodeLogEntry, sink: CodeLogEntry[]): void => {
|
||||
@@ -315,9 +315,8 @@ export class WorkerCodeRuntime extends CodeRuntime {
|
||||
worker.stdout.on('data', captureStray('stdout'))
|
||||
worker.stderr.on('data', captureStray('stderr'))
|
||||
|
||||
// Settlement: exactly one outcome wins; every path funnels through here, cleans up the
|
||||
// timers/listeners, terminates the worker, and resolves only after the worker actually
|
||||
// exited (quiescence).
|
||||
// Exactly one outcome wins. Every path cleans up, terminates, and awaits the worker;
|
||||
// logs captured before timeout, abort, or failure remain in the result.
|
||||
let finishResolve!: () => void
|
||||
const finished = new Promise<void>((done) => { finishResolve = done })
|
||||
const finish = (result: Omit<CodeRunResult, 'logs'>): void => {
|
||||
@@ -335,9 +334,8 @@ export class WorkerCodeRuntime extends CodeRuntime {
|
||||
|
||||
const onDone = (message: WorkerToHost): void => {
|
||||
if (message.type !== 'done') return
|
||||
// Re-cap the completion value HOST-side: the honest path already capped it in the
|
||||
// worker (prepareValue there), but a forged done message bypasses the bootstrap
|
||||
// entirely — without this, model code could flood the host past maxValueBytes.
|
||||
// Re-cap forged completion traffic at the hostile boundary. Honest worker-capped values
|
||||
// pass unchanged via VALUE_RENDER_SLACK; error text is bounded too.
|
||||
finish({
|
||||
...prepareValue(message.value, this.config.maxValueBytes + VALUE_RENDER_SLACK),
|
||||
...message.error ? { error: { kind: 'exception' as const, message: truncateUtf8Bytes(message.error.message, this.config.maxValueBytes) } } : {},
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/**
|
||||
* Wire protocol between the host runtime and the worker bootstrap.
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* The worker-thread entrypoint: self-executing glue over `bootstrap.ts`'s {@link
|
||||
* runWorkerMain}, kept to the spawn wiring alone.
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
@@ -5,10 +5,9 @@ import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
/**
|
||||
* Built-ARTIFACT smoke for the published package (the real-load-path guard from
|
||||
* docs/testing.md): the unit suite runs `src/` under vitest, where the worker entry resolves
|
||||
* to `src/worker.ts` — a consumer runs `lib/index.js` under plain `node`, where it must
|
||||
* resolve the sibling `lib/worker.js` bundle instead.
|
||||
* Keyless built-artifact smoke: plain Node imports the package by name through its exports map
|
||||
* and exercises type stripping, worker loading, bindings, and logs. It skips when `lib/` is
|
||||
* absent; CI runs it after the build.
|
||||
*/
|
||||
|
||||
const pkgDir = fileURLToPath(new URL('..', import.meta.url))
|
||||
|
||||
@@ -255,8 +255,8 @@ describe('WorkerCodeRuntime — budgets and containment (real workers)', () => {
|
||||
it('captures pipe writes that bypass the patched write slot as stray logs, capped by the same budget', async () => {
|
||||
const { runtime } = await setup({ maxLogBytes: 4 })
|
||||
const result = await runtime.run({
|
||||
// The bootstrap patches the stream instance's own `write`; going through the prototype's
|
||||
// slot reaches the real pipe underneath, so the bytes arrive host-side as stray data.
|
||||
// The prototype write bypasses the patched instance and reaches the real pipe. Pauses keep
|
||||
// writes in separate chunks and let both reach the host before settlement.
|
||||
program: `
|
||||
const write = (text) => Object.getPrototypeOf(process.stdout).write.call(process.stdout, text);
|
||||
write('abcd');
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
/**
|
||||
* Package-shape override (see the root tsdown.config.ts): besides the default lib/index.js
|
||||
* bundle, the worker BOOTSTRAP ships as its own sibling entry — `new Worker(new
|
||||
* URL('./worker.js', import.meta.url))` loads it as a file, so it cannot be part of the index
|
||||
* bundle.
|
||||
* Build the index and worker as separate single-entry bundles. The worker must be a sibling
|
||||
* file, while a multi-entry build would emit an unlisted shared chunk omitted by the package's
|
||||
* exact `files` whitelist.
|
||||
*/
|
||||
export default defineConfig([
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Code-execution seam for running one model-written program against host bindings.
|
||||
* Code-execution seam for running one model-written program against host async bindings.
|
||||
* Runtimes know nothing about tools or sessions; consumers own those concerns.
|
||||
* @module @deepseek-ai/dsh-code-runtime
|
||||
*/
|
||||
|
||||
@@ -22,9 +23,10 @@ declare module 'cordis' {
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract code-execution service. Subclass, implement {@link run} and the two descriptors,
|
||||
* and load the subclass as a plugin — it registers as `ctx.codeRuntime` (one implementation
|
||||
* per context; loading a second throws, cordis' standard duplicate-service behavior).
|
||||
* Registers one `ctx.codeRuntime` implementation. Program, budget, abort, and substrate
|
||||
* failures resolve in {@link CodeRunResult}; only seam misuse rejects. Implementations bridge
|
||||
* structured-cloneable bindings while treating programs as hostile peers, isolate runs from
|
||||
* one another, and terminate and await in-flight runs during disposal.
|
||||
*/
|
||||
export abstract class CodeRuntime extends Service {
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user