@deepseek-ai/dsh-ptc-runtime-node 0.1.6-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +155 -0
- package/README.zh.md +155 -0
- package/lib/index.js +1178 -0
- package/lib/process.js +1136 -0
- package/lib/types/bindings.d.ts +8 -0
- package/lib/types/bootstrap.d.ts +143 -0
- package/lib/types/channel.d.ts +32 -0
- package/lib/types/environment.d.ts +4 -0
- package/lib/types/index.d.ts +55 -0
- package/lib/types/json-wire.d.ts +46 -0
- package/lib/types/launch.d.ts +17 -0
- package/lib/types/output-json.d.ts +26 -0
- package/lib/types/output-ledger.d.ts +18 -0
- package/lib/types/output-stream.d.ts +10 -0
- package/lib/types/process-entry.d.ts +2 -0
- package/lib/types/process.d.ts +19 -0
- package/lib/types/protocol.d.ts +75 -0
- package/package.json +61 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PtcBindingNamespace, PtcRunRequest } from '@deepseek-ai/dsh-ptc-runtime';
|
|
2
|
+
/**
|
|
3
|
+
* Reject unusable namespaces before starting a process.
|
|
4
|
+
* @param request - Host-owned binding declarations.
|
|
5
|
+
* @returns Namespaces keyed by their declared global.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateBindings(request: PtcRunRequest): Map<string, PtcBindingNamespace>;
|
|
8
|
+
//# sourceMappingURL=bindings.d.ts.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Program evaluation, output capture, and host binding proxies over the process channel.
|
|
3
|
+
* @module @deepseek-ai/dsh-ptc-runtime-node/src/bootstrap
|
|
4
|
+
*/
|
|
5
|
+
import type { DoneMessage, ReplyMessage, ProgramBootData, ProgramToHost } from './protocol.ts';
|
|
6
|
+
/** Program messages and host replies transported by the private process channel. */
|
|
7
|
+
export interface BootstrapPort {
|
|
8
|
+
postMessage(message: ProgramToHost): void;
|
|
9
|
+
on(event: 'message', listener: (message: ReplyMessage) => void): void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A writable stream's `write` slot, as the bootstrap patches it (see
|
|
13
|
+
* {@link captureStreamWrites}). Method-typed so the real
|
|
14
|
+
* `process.stdout`/`process.stderr` (narrower chunk parameters) remain
|
|
15
|
+
* assignable.
|
|
16
|
+
*/
|
|
17
|
+
export interface PatchableStream {
|
|
18
|
+
write(chunk: unknown, ...rest: unknown[]): boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Ordered text capture under the shared outer JSON-byte budget, delivered to
|
|
22
|
+
* a sink as each item lands (the real sink streams text over the port eagerly,
|
|
23
|
+
* so captured output survives a mid-run termination). It includes the log
|
|
24
|
+
* array syntax and string escaping in its accounting. Once exhausted it emits
|
|
25
|
+
* the fitting prefix and reports the limit once; the host turns that condition
|
|
26
|
+
* into an explicit `output-limit` run failure.
|
|
27
|
+
*/
|
|
28
|
+
export declare class LogBuffer {
|
|
29
|
+
private bytes;
|
|
30
|
+
private entries;
|
|
31
|
+
private truncated;
|
|
32
|
+
private readonly sink;
|
|
33
|
+
private readonly onLimit;
|
|
34
|
+
private readonly maxBytes;
|
|
35
|
+
constructor(maxBytes: number, sink: (text: string) => void, onLimit?: () => void);
|
|
36
|
+
/**
|
|
37
|
+
* Emit text to the sink, charging it against the budget (drops + marks once exhausted).
|
|
38
|
+
* @param text - the captured text to deliver.
|
|
39
|
+
*/
|
|
40
|
+
push(text: string): void;
|
|
41
|
+
/** Remaining exact JSON-byte budget for the completion value or failure message. */
|
|
42
|
+
remainingOutputBytes(): number;
|
|
43
|
+
}
|
|
44
|
+
/** The five console methods the shim captures, in the seam's level vocabulary. */
|
|
45
|
+
declare const CONSOLE_LEVELS: readonly ["log", "info", "warn", "error", "debug"];
|
|
46
|
+
/**
|
|
47
|
+
* A `console` replacement whose five leveled methods render their arguments
|
|
48
|
+
* `util.inspect`-style (matching real console formatting closely enough for
|
|
49
|
+
* a model to recognize its own output) into the buffer. Only these five
|
|
50
|
+
* exist — the program gets a deliberately small console, not Node's full
|
|
51
|
+
* console API.
|
|
52
|
+
* @param logs - the buffer every rendered line is pushed into.
|
|
53
|
+
* @returns the five-method console object handed to the program.
|
|
54
|
+
*/
|
|
55
|
+
export declare function makeConsoleShim(logs: LogBuffer): Record<(typeof CONSOLE_LEVELS)[number], (...args: unknown[]) => void>;
|
|
56
|
+
/**
|
|
57
|
+
* Redirect a stream's `write` into the log buffer (the program-visible
|
|
58
|
+
* `process.stdout`/`process.stderr` in the Node child), so raw writes land in emission order
|
|
59
|
+
* alongside console output instead of racing down a pipe. It preserves Node's optional callback
|
|
60
|
+
* contract: the callback runs asynchronously after admission, even when the log budget drops
|
|
61
|
+
* the write.
|
|
62
|
+
*
|
|
63
|
+
* @param logs - the buffer captured writes are pushed into.
|
|
64
|
+
* @param stream - the stream whose `write` slot is patched.
|
|
65
|
+
* @returns the restore function (the in-process tests un-patch; the real
|
|
66
|
+
* child never needs to).
|
|
67
|
+
*/
|
|
68
|
+
export declare function captureStreamWrites(logs: LogBuffer, stream: PatchableStream): () => void;
|
|
69
|
+
/**
|
|
70
|
+
* Prepare the program's completion value for the done message. Only lossless
|
|
71
|
+
* JSON crosses, and a value that does not fit the remaining combined outer
|
|
72
|
+
* budget reports `output-limit`; the host revalidates hostile traffic and
|
|
73
|
+
* remains authoritative for native pipe writes the program shim cannot observe.
|
|
74
|
+
*
|
|
75
|
+
* @param value - the program's completion value.
|
|
76
|
+
* @param remainingOutputBytes - exact bytes left after captured logs.
|
|
77
|
+
* @param maxOutputBytes - the configured cap named in an overflow diagnostic.
|
|
78
|
+
* @returns the done-message fragment: `{}` for `undefined`, else a flat wire `{ value }`.
|
|
79
|
+
*/
|
|
80
|
+
export declare function prepareCompletion(value: unknown, remainingOutputBytes: number, maxOutputBytes?: number): Omit<DoneMessage, 'type'>;
|
|
81
|
+
/**
|
|
82
|
+
* Prepare a thrown program value without sending an unbounded stack or
|
|
83
|
+
* string across the process channel.
|
|
84
|
+
* @param error - the value thrown by the program.
|
|
85
|
+
* @param remainingOutputBytes - exact bytes left after captured logs.
|
|
86
|
+
* @param maxOutputBytes - the configured cap named in an overflow diagnostic.
|
|
87
|
+
* @returns a bounded exception or fixed output-limit fragment.
|
|
88
|
+
*/
|
|
89
|
+
export declare function prepareException(error: unknown, remainingOutputBytes: number, maxOutputBytes?: number): Omit<DoneMessage, 'type'>;
|
|
90
|
+
/** One awaited binding call's settlement handles, keyed by call id in the pending map. */
|
|
91
|
+
export interface PendingCall {
|
|
92
|
+
resolve(value: unknown): void;
|
|
93
|
+
reject(error: Error): void;
|
|
94
|
+
}
|
|
95
|
+
/** Constructor type for one program-visible binding rejection class. */
|
|
96
|
+
export type BindingErrorConstructor = new (memberName: string, message: string) => Error;
|
|
97
|
+
/**
|
|
98
|
+
* Build each declared error class once so calls and `instanceof` share constructor identity.
|
|
99
|
+
* @param data - binding namespace declarations from the boot payload.
|
|
100
|
+
* @returns constructors keyed by their owning namespace global.
|
|
101
|
+
*/
|
|
102
|
+
export declare function makeBindingErrorClasses(data: Pick<ProgramBootData, 'namespaces'>): Map<string, BindingErrorConstructor>;
|
|
103
|
+
/**
|
|
104
|
+
* Route host replies into the pending-call map: each reply settles its call
|
|
105
|
+
* at most once, and a reply for an unknown id (stray, or a duplicate answer
|
|
106
|
+
* to an id already settled) is ignored. Shared wiring between
|
|
107
|
+
* {@link runProgram} and the tests that exercise {@link makeNamespaces}
|
|
108
|
+
* standalone.
|
|
109
|
+
* @param port - the port whose `message` events carry the replies.
|
|
110
|
+
* @param pending - the id-keyed map of unsettled binding calls.
|
|
111
|
+
*/
|
|
112
|
+
export declare function wireReplies(port: BootstrapPort, pending: Map<number, PendingCall>): void;
|
|
113
|
+
/**
|
|
114
|
+
* Build the binding namespace objects the program sees: one null-prototype global per
|
|
115
|
+
* namespace, each declared name an own enumerable async function that bridges over the port
|
|
116
|
+
* (`__proto__`/`constructor`/`toString` are ordinary keys, never prototype collisions).
|
|
117
|
+
* Lossy arguments reject before posting; clone failures and host failure
|
|
118
|
+
* replies reject only the corresponding call.
|
|
119
|
+
*
|
|
120
|
+
* @param data - the boot payload's namespace declarations (globals + names).
|
|
121
|
+
* @param port - the port binding calls are posted to.
|
|
122
|
+
* @param pending - the id-keyed map each posted call parks its handles in.
|
|
123
|
+
* @param nextId - the shared mutable id counter (program-issued correlation ids).
|
|
124
|
+
* @param errorClasses - per-namespace constructors shared with program globals.
|
|
125
|
+
* @returns one namespace object per declaration, in declaration order.
|
|
126
|
+
*/
|
|
127
|
+
export declare function makeNamespaces(data: Pick<ProgramBootData, 'namespaces'>, port: BootstrapPort, pending: Map<number, PendingCall>, nextId: {
|
|
128
|
+
value: number;
|
|
129
|
+
}, errorClasses?: Map<string, BindingErrorConstructor>): Record<string, unknown>[];
|
|
130
|
+
/**
|
|
131
|
+
* Run one strict async-function body, allowing top-level `await` and `return`, and post exactly
|
|
132
|
+
* one terminal {@link DoneMessage}; a thrown program error becomes its `error` field.
|
|
133
|
+
* @param port - host message port or test double.
|
|
134
|
+
* @param data - the boot payload the host sent.
|
|
135
|
+
* @param streams - stdout/stderr objects captured as program logs.
|
|
136
|
+
* @returns after posting the done message.
|
|
137
|
+
*/
|
|
138
|
+
export declare function runProgram(port: BootstrapPort, data: ProgramBootData, streams: {
|
|
139
|
+
stdout: PatchableStream;
|
|
140
|
+
stderr: PatchableStream;
|
|
141
|
+
}): Promise<void>;
|
|
142
|
+
export {};
|
|
143
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Duplex } from 'node:stream';
|
|
2
|
+
/** One co-shipped process channel; the consumer owns frame validation and terminal outcomes. */
|
|
3
|
+
export declare class JsonChannel {
|
|
4
|
+
private readonly stream;
|
|
5
|
+
private readonly maxBytes;
|
|
6
|
+
private readonly receive;
|
|
7
|
+
private readonly failure;
|
|
8
|
+
private readonly header;
|
|
9
|
+
private headerBytes;
|
|
10
|
+
private payload;
|
|
11
|
+
private payloadBytes;
|
|
12
|
+
private queuedBytes;
|
|
13
|
+
private closed;
|
|
14
|
+
private readonly writes;
|
|
15
|
+
constructor(stream: Duplex, maxBytes: number, receive: (message: unknown, bytes: number) => void, failure: (error: Error, kind: 'io' | 'protocol') => void);
|
|
16
|
+
private readonly onError;
|
|
17
|
+
private readonly onClose;
|
|
18
|
+
private readonly onEnd;
|
|
19
|
+
private readonly onData;
|
|
20
|
+
/**
|
|
21
|
+
* Submit a bounded frame immediately and await the stream's write receipt.
|
|
22
|
+
* @param message - JSON-only co-shipped protocol value.
|
|
23
|
+
* @returns Resolves when this frame has been written, or rejects after transport failure.
|
|
24
|
+
*/
|
|
25
|
+
send(message: unknown): Promise<void>;
|
|
26
|
+
private finishWrites;
|
|
27
|
+
/** Stop reads and close the owned endpoint; pending writes reject on closure. */
|
|
28
|
+
close(): void;
|
|
29
|
+
/** Wait for accepted writes to finish or fail. */
|
|
30
|
+
drain(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Startup variables required by native executables before model evaluation. */
|
|
2
|
+
/** Native executable search, Windows system paths, and sandbox temporary paths retained in the OS environment. */
|
|
3
|
+
export declare const STARTUP_ENVIRONMENT_NAMES: ReadonlySet<string>;
|
|
4
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Context } from '@deepseek-ai/cordis';
|
|
2
|
+
import z from '@deepseek-ai/schemastery';
|
|
3
|
+
import { PtcRuntime } from '@deepseek-ai/dsh-ptc-runtime';
|
|
4
|
+
import type { PtcRunRequest, PtcRunResult, PtcRunSpec } from '@deepseek-ai/dsh-ptc-runtime';
|
|
5
|
+
import type { SandboxMode } from '@deepseek-ai/dsh-sandbox';
|
|
6
|
+
import type { LaunchConfig } from './launch.ts';
|
|
7
|
+
/** Deployment-varying runtime bounds and launch choices. */
|
|
8
|
+
export interface Config extends LaunchConfig {
|
|
9
|
+
/** Default elapsed deadline, including nested tool and approval waits. */
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
/** Maximum numeric elapsed budget accepted by resolve. */
|
|
12
|
+
maxTimeoutMs?: number;
|
|
13
|
+
/** Combined serialized logs, completion and diagnostic byte cap. */
|
|
14
|
+
maxOutputBytes?: number;
|
|
15
|
+
/** V8 old-generation heap limit in MiB; native allocations are excluded. */
|
|
16
|
+
maxOldGenerationSizeMb?: number;
|
|
17
|
+
/** Maximum control frame, outstanding argument and queued control-output bytes. */
|
|
18
|
+
maxMessageBytes?: number;
|
|
19
|
+
/** Maximum simultaneous host binding calls accepted from a program. */
|
|
20
|
+
maxPendingCalls?: number;
|
|
21
|
+
/** Managed process termination and output-drain grace in milliseconds. */
|
|
22
|
+
graceMs?: number;
|
|
23
|
+
}
|
|
24
|
+
/** Node provider; direct file effects use the same sandbox service as Bash. */
|
|
25
|
+
export declare class NodePtcRuntime extends PtcRuntime {
|
|
26
|
+
static inject: string[];
|
|
27
|
+
static Config: z<Config>;
|
|
28
|
+
readonly language = "typescript";
|
|
29
|
+
readonly isolation = "process";
|
|
30
|
+
get executionInstructions(): string;
|
|
31
|
+
private readonly config;
|
|
32
|
+
private readonly live;
|
|
33
|
+
private disposed;
|
|
34
|
+
constructor(ctx: Context, config: Config);
|
|
35
|
+
get sandboxMode(): SandboxMode;
|
|
36
|
+
get timeout(): {
|
|
37
|
+
defaultMs: number;
|
|
38
|
+
maxMs: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Resolve an execution under explicit or deployment policy.
|
|
42
|
+
* @param request - Program, bindings, optional cwd/deadline, and resolved authority.
|
|
43
|
+
* @returns Complete execution inputs with a capped numeric budget or an explicit null deadline.
|
|
44
|
+
*/
|
|
45
|
+
resolve(request: PtcRunRequest): PtcRunSpec;
|
|
46
|
+
/**
|
|
47
|
+
* Run a resolved program in a fresh managed and confined Node process.
|
|
48
|
+
* @param spec - Inputs returned by resolve; missing authority is caller misuse.
|
|
49
|
+
* @returns Output and file-confinement facts after managed cleanup.
|
|
50
|
+
*/
|
|
51
|
+
run(spec: PtcRunSpec): Promise<PtcRunResult>;
|
|
52
|
+
private execute;
|
|
53
|
+
}
|
|
54
|
+
export default NodePtcRuntime;
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lossless-JSON snapshots for the dependency-free source bootstrap closure.
|
|
3
|
+
* @module @deepseek-ai/dsh-ptc-runtime-node/json-wire
|
|
4
|
+
*/
|
|
5
|
+
import type { PtcJsonValue } from '@deepseek-ai/dsh-ptc-runtime';
|
|
6
|
+
/**
|
|
7
|
+
* Validate and detach one process-boundary value without loading another
|
|
8
|
+
* workspace package at runtime. This mirrors the session-owned canonical
|
|
9
|
+
* JSON boundary while remaining safe to import from the unbuilt bootstrap.
|
|
10
|
+
* Its iterative traversal adds no JavaScript call-stack depth limit.
|
|
11
|
+
*
|
|
12
|
+
* @param value - the candidate completion value.
|
|
13
|
+
* @returns a detached lossless-JSON snapshot, or `undefined` when invalid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function snapshotPtcJsonValue(value: unknown): PtcJsonValue | undefined;
|
|
16
|
+
interface ArrayWireToken {
|
|
17
|
+
kind: 'array';
|
|
18
|
+
length: number;
|
|
19
|
+
}
|
|
20
|
+
interface ObjectWireToken {
|
|
21
|
+
kind: 'object';
|
|
22
|
+
keys: string[];
|
|
23
|
+
}
|
|
24
|
+
type PtcJsonToken = null | boolean | number | string | ArrayWireToken | ObjectWireToken;
|
|
25
|
+
/**
|
|
26
|
+
* A pre-order, bounded-depth transport for one lossless JSON value. Container
|
|
27
|
+
* markers and scalar leaves share one flat token array, so JSON serialization
|
|
28
|
+
* does not recurse through the value's application nesting.
|
|
29
|
+
*/
|
|
30
|
+
export type PtcJsonWire = PtcJsonToken[];
|
|
31
|
+
/**
|
|
32
|
+
* Flatten one validated JSON value for the process control channel.
|
|
33
|
+
* @param value - the lossless JSON value to transport.
|
|
34
|
+
* @returns a pre-order token stream whose own nesting is bounded.
|
|
35
|
+
*/
|
|
36
|
+
export declare function encodePtcJsonWire(value: PtcJsonValue): PtcJsonWire;
|
|
37
|
+
/**
|
|
38
|
+
* Rebuild one lossless JSON value from the flat process wire format.
|
|
39
|
+
* Malformed or incomplete traffic returns `undefined`; traversal is iterative
|
|
40
|
+
* and therefore independent of the transported value's application depth.
|
|
41
|
+
* @param input - untrusted message-port payload.
|
|
42
|
+
* @returns the detached JSON value, or `undefined` when the wire is invalid.
|
|
43
|
+
*/
|
|
44
|
+
export declare function decodePtcJsonWire(input: unknown): PtcJsonValue | undefined;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=json-wire.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileSystem } from '@deepseek-ai/dsh-fs';
|
|
2
|
+
/** Deployment-owned Node executable and optional preinstalled built bootstrap. */
|
|
3
|
+
export interface LaunchConfig {
|
|
4
|
+
/** Executable in the subprocess world; defaults to the current Node executable. */
|
|
5
|
+
nodeExecutable?: string;
|
|
6
|
+
/** Absolute preinstalled built bootstrap in the execution world. */
|
|
7
|
+
bootstrapPath?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Select explicit arguments without inheriting host loader or inspector flags.
|
|
11
|
+
* @param fs - Filesystem mapping host bootstrap assets into the process world.
|
|
12
|
+
* @param config - Optional preinstalled built bootstrap.
|
|
13
|
+
* @param maxMessageBytes - Validated frame and queued-write limit.
|
|
14
|
+
* @returns Arguments following the resolved Node executable.
|
|
15
|
+
*/
|
|
16
|
+
export declare function bootstrapArgs(fs: FileSystem, config: LaunchConfig, maxMessageBytes: number): string[];
|
|
17
|
+
//# sourceMappingURL=launch.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** JSON string-prefix accounting for the outer-output ledger. @module @deepseek-ai/dsh-ptc-runtime-node/output-json */
|
|
2
|
+
import type { PtcJsonValue } from '@deepseek-ai/dsh-ptc-runtime';
|
|
3
|
+
/**
|
|
4
|
+
* Measure one JSON string without materializing its complete escaped form.
|
|
5
|
+
* @param text - the candidate string.
|
|
6
|
+
* @param maxBytes - largest serialized size the caller can admit.
|
|
7
|
+
* @returns Exact serialized bytes, or `undefined` as soon as the cap is crossed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function jsonStringBytesUpTo(text: string, maxBytes: number): number | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Measure one lossless JSON value without allocating its serialized form.
|
|
12
|
+
* @param value - already validated lossless JSON.
|
|
13
|
+
* @param maxBytes - largest serialized size the caller can admit.
|
|
14
|
+
* @returns Exact serialized bytes, or `undefined` as soon as the cap is crossed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function jsonValueBytesUpTo(value: PtcJsonValue, maxBytes: number): number | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Return the longest code-point-aligned prefix whose JSON string encoding,
|
|
19
|
+
* including its surrounding quotes, fits `maxBytes`.
|
|
20
|
+
*
|
|
21
|
+
* @param text - the candidate string.
|
|
22
|
+
* @param maxBytes - serialized JSON-string bytes available.
|
|
23
|
+
* @returns the fitting prefix, or an empty string when even useful content cannot fit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function truncateJsonStringBytes(text: string, maxBytes: number): string;
|
|
26
|
+
//# sourceMappingURL=output-json.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Combined byte accounting for retained program output. */
|
|
2
|
+
import type { PtcJsonValue, PtcRunFailure, PtcRunResult } from '@deepseek-ai/dsh-ptc-runtime';
|
|
3
|
+
/** One run's combined outer-output ledger; binding values never enter it. */
|
|
4
|
+
export declare class OutputLedger {
|
|
5
|
+
private readonly maxBytes;
|
|
6
|
+
private bytes;
|
|
7
|
+
private entries;
|
|
8
|
+
constructor(maxBytes: number);
|
|
9
|
+
/** Admit one exact log entry, or report that the hard cap was crossed. */
|
|
10
|
+
admit(text: string, sink: string[]): boolean;
|
|
11
|
+
/** Finalize a successful absent-or-JSON completion against the combined cap. */
|
|
12
|
+
success(logs: string[], value?: PtcJsonValue): PtcRunResult;
|
|
13
|
+
/** Finalize a failure diagnostic, with output-limit taking precedence when combined bytes exceed the cap. */
|
|
14
|
+
failure(logs: string[], error: PtcRunFailure): PtcRunResult;
|
|
15
|
+
/** Build the explicit output-limit failure while retaining a fitting prefix of the final log. */
|
|
16
|
+
limit(logs: string[]): PtcRunResult;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=output-ledger.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Bounded drainage for raw process output after managed execution ends. */
|
|
2
|
+
import type { Readable } from 'node:stream';
|
|
3
|
+
/**
|
|
4
|
+
* Wait for queued bytes without letting an inherited descriptor retain a run forever.
|
|
5
|
+
* @param stream - Caller-owned raw process output, when provided.
|
|
6
|
+
* @param graceMs - Maximum wait after managed process termination.
|
|
7
|
+
* @returns Whether the complete stream ended without a transport error.
|
|
8
|
+
*/
|
|
9
|
+
export declare function drainOutput(stream: Readable | undefined, graceMs: number): Promise<boolean>;
|
|
10
|
+
//# sourceMappingURL=output-stream.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Node child execution over an inherited control channel; no Harness services run here. */
|
|
2
|
+
import type { Duplex } from 'node:stream';
|
|
3
|
+
import type { PatchableStream } from './bootstrap.ts';
|
|
4
|
+
/** Process-owned environment and output streams consumed by the child bootstrap. */
|
|
5
|
+
export interface ProgramProcess {
|
|
6
|
+
env: NodeJS.ProcessEnv;
|
|
7
|
+
stdout: PatchableStream;
|
|
8
|
+
stderr: PatchableStream;
|
|
9
|
+
exitCode: string | number | null | undefined;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Run one host-supplied program after the control handshake.
|
|
13
|
+
* @param stream - Inherited, already-adopted control endpoint.
|
|
14
|
+
* @param maxMessageBytes - Host-validated maximum frame and queued-write bytes.
|
|
15
|
+
* @param processState - Environment, output streams and exit status of this Node child.
|
|
16
|
+
* @returns After control output flushes and host shutdown is observed, or transport failure closes the channel.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runNodeMain(stream: Duplex, maxMessageBytes: number, processState: ProgramProcess): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON message vocabulary carried by the bounded process channel. The host validates every
|
|
3
|
+
* message because model code can write directly to the inherited descriptor.
|
|
4
|
+
* @module @deepseek-ai/dsh-ptc-runtime-node/src/protocol
|
|
5
|
+
*/
|
|
6
|
+
import type { PtcJsonWire } from './json-wire.ts';
|
|
7
|
+
/** What the host hands the program at spawn, after the readiness handshake. */
|
|
8
|
+
export interface ProgramBootData {
|
|
9
|
+
/** The type-stripped (plain JS) program body. */
|
|
10
|
+
code: string;
|
|
11
|
+
/** Binding namespaces to materialize; functions themselves stay host-side. */
|
|
12
|
+
namespaces: {
|
|
13
|
+
global: string;
|
|
14
|
+
names: string[];
|
|
15
|
+
errorClass?: {
|
|
16
|
+
name: string;
|
|
17
|
+
memberNameProperty: string;
|
|
18
|
+
};
|
|
19
|
+
}[];
|
|
20
|
+
/** Hard cap for the combined serialized outer logs plus completion value or failure diagnostic. */
|
|
21
|
+
maxOutputBytes: number;
|
|
22
|
+
}
|
|
23
|
+
/** Program → host: one bridged binding call. */
|
|
24
|
+
interface CallMessage {
|
|
25
|
+
type: 'call';
|
|
26
|
+
/** Program-issued correlation id; the host answers each id at most once and ignores duplicates. */
|
|
27
|
+
id: number;
|
|
28
|
+
/** The namespace global the call targets. */
|
|
29
|
+
global: string;
|
|
30
|
+
/** The function name within the namespace. */
|
|
31
|
+
name: string;
|
|
32
|
+
/** The single argument as a flat lossless-JSON wire value. */
|
|
33
|
+
args: PtcJsonWire;
|
|
34
|
+
}
|
|
35
|
+
/** Program → host: captured text, streamed eagerly so output survives a mid-run termination (timeout, abort, OOM). */
|
|
36
|
+
interface LogMessage {
|
|
37
|
+
type: 'log';
|
|
38
|
+
text: string;
|
|
39
|
+
}
|
|
40
|
+
/** Program → host: program-side capture or completion measurement exceeded the outer cap. */
|
|
41
|
+
interface OutputLimitMessage {
|
|
42
|
+
type: 'output-limit';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Program → host: the program settled. `error` carries a program exception,
|
|
46
|
+
* invalid completion, or output overflow (budgets, aborts, and substrate death
|
|
47
|
+
* are observed host-side). `value` is present only on a clean completion that
|
|
48
|
+
* produced one, as a flat wire value already lossless and admitted against
|
|
49
|
+
* the remaining combined output cap. Logs are NOT carried here — they streamed
|
|
50
|
+
* eagerly as {@link LogMessage}s.
|
|
51
|
+
*/
|
|
52
|
+
export interface DoneMessage {
|
|
53
|
+
type: 'done';
|
|
54
|
+
value?: PtcJsonWire;
|
|
55
|
+
error?: {
|
|
56
|
+
kind: 'exception' | 'invalid-output' | 'output-limit';
|
|
57
|
+
message: string;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Every message the program sends. */
|
|
61
|
+
export type ProgramToHost = CallMessage | LogMessage | OutputLimitMessage | DoneMessage;
|
|
62
|
+
/** Host → program: the answer to one {@link CallMessage}. */
|
|
63
|
+
export type ReplyMessage = {
|
|
64
|
+
type: 'reply';
|
|
65
|
+
id: number;
|
|
66
|
+
ok: true;
|
|
67
|
+
value: PtcJsonWire;
|
|
68
|
+
} | {
|
|
69
|
+
type: 'reply';
|
|
70
|
+
id: number;
|
|
71
|
+
ok: false;
|
|
72
|
+
message: string;
|
|
73
|
+
};
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=protocol.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-ptc-runtime-node",
|
|
3
|
+
"description": "Sandboxed Node process implementation of the DeepSeek Harness PTC execution capability",
|
|
4
|
+
"version": "0.1.6-alpha.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/ptc-runtime/ptc-runtime-node"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json",
|
|
22
|
+
"./process": {
|
|
23
|
+
"types": "./lib/types/process-entry.d.ts",
|
|
24
|
+
"default": "./lib/process.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"lib/index.js",
|
|
29
|
+
"lib/process.js",
|
|
30
|
+
"lib/types/**/*.d.ts"
|
|
31
|
+
],
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
35
|
+
"@deepseek-ai/dsh-ptc-runtime": "^0.1.6-alpha.1",
|
|
36
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
|
|
37
|
+
"@deepseek-ai/dsh-timeout": "^0.1.6-alpha.1",
|
|
38
|
+
"@deepseek-ai/dsh-fs": "^0.1.6-alpha.1",
|
|
39
|
+
"@deepseek-ai/dsh-subprocess": "^0.1.6-alpha.1",
|
|
40
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.1",
|
|
41
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.1"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.1",
|
|
45
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@deepseek-ai/dsh-ptc-runtime": "^0.1.6-alpha.1",
|
|
49
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.1",
|
|
50
|
+
"@deepseek-ai/dsh-timeout": "^0.1.6-alpha.1",
|
|
51
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
52
|
+
"@deepseek-ai/dsh-fs": "^0.1.6-alpha.1",
|
|
53
|
+
"@deepseek-ai/dsh-subprocess": "^0.1.6-alpha.1",
|
|
54
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.1",
|
|
55
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.1",
|
|
56
|
+
"@deepseek-ai/dsh-fs-local": "^0.1.6-alpha.1",
|
|
57
|
+
"@deepseek-ai/dsh-subprocess-local": "^0.1.6-alpha.1",
|
|
58
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.1",
|
|
59
|
+
"@deepseek-ai/dsh-sandbox-local": "^0.1.6-alpha.1"
|
|
60
|
+
}
|
|
61
|
+
}
|