Files
deepseek-harness/packages/ptc-runtime/ptc-runtime-node/src/config.ts
T
_Kerman 427d62d4a7 fix(ptc-runtime-node): fail fast on mismatched bootstraps and late replies
- Reject a control line that does not start with "{", so another
  release's length-prefixed frame fails as a protocol error instead of
  waiting for a newline until the deadline.
- Bump SSH_PROTOCOL_VERSION to 3: executable helpers embed the PTC
  worker, so an older helper is now rejected while connecting.
- Send a small error instead of a late binding result from a finished
  persistent evaluation, so it cannot overflow the pipe shared with
  the next evaluation.
- Leave per-call binding waits pending after the result instead of
  rejecting them; unawaited calls crashed the child and leaked the
  trace into the result logs.
- Pin birpc to 4.2.0 so the host and the bundled child agree, and
  regenerate THIRD_PARTY_NOTICES.md.
- Update stale frame wording.
2026-10-20 16:06:50 +08:00

62 lines
3.3 KiB
TypeScript

/** Execution mode and resource limits for the Node PTC provider. */
import z from '@deepseek-ai/schemastery'
import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout'
import type { LaunchConfig } from './launch.ts'
/** Deployment-varying runtime bounds and launch choices. */
export interface Config {
/** Worker invocation in the subprocess world; omitted selects the local carrier. */
launch?: LaunchConfig
/** per-call starts fresh processes; persistent-in-memory retains a REPL per owner under the same file policy. */
executionMode?: 'per-call' | 'persistent-in-memory'
/** Default elapsed deadline, including nested tool and approval waits. */
timeoutMs?: number
/** Maximum numeric elapsed budget accepted by resolve. */
maxTimeoutMs?: number
/** Combined serialized logs, completion and diagnostic byte cap. */
maxOutputBytes?: number
/** V8 old-generation heap limit in MiB; native allocations are excluded. */
maxOldGenerationSizeMb?: number
/** Maximum control message, outstanding binding-argument and queued control-output bytes. */
maxMessageBytes?: number
/** Maximum simultaneous host binding calls accepted from a program. */
maxPendingCalls?: number
/** Managed process termination and output-drain grace in milliseconds. */
graceMs?: number
}
/** Configuration after Loader defaults and executable selection. */
export type ResolvedConfig = Required<Config>
/** Loader defaults for the Node PTC provider. */
export const NodeConfig: z<Config> = z.object({
executionMode: z.union([z.const('per-call'), z.const('persistent-in-memory')]).default('per-call'),
timeoutMs: z.number().default(120_000),
maxTimeoutMs: z.number().default(600_000),
maxOutputBytes: z.number().default(67_108_864),
maxOldGenerationSizeMb: z.number().default(512),
maxMessageBytes: z.number().default(134_217_728),
maxPendingCalls: z.number().default(128),
graceMs: z.number().default(3_000),
launch: z.union([
z.object({ kind: z.const('node-script').required(), executable: z.string().required(), bootstrapPath: z.string() }),
z.object({ kind: z.const('embedded').required(), executable: z.string().required() }),
]),
})
/**
* Validate resolved Node limits and paths.
* @param config - Loader-defaulted fields with the selected executable.
*/
export function validateConfig(config: ResolvedConfig): void {
for (const [key, value] of Object.entries(config)) {
if (typeof value === 'number' && (!Number.isFinite(value) || value <= 0)) throw new Error(`ptc-runtime-node: ${key} must be positive and finite`)
}
for (const key of ['timeoutMs', 'maxTimeoutMs', 'graceMs'] as const) {
if (config[key] > MAX_TIMER_DELAY_MS) throw new Error(`ptc-runtime-node: ${key} exceeds the supported timer range`)
}
if (!Number.isSafeInteger(config.maxOutputBytes) || config.maxOutputBytes < 4) throw new Error('ptc-runtime-node: maxOutputBytes must be an integer of at least 4')
if (!Number.isSafeInteger(config.maxMessageBytes)) throw new Error('ptc-runtime-node: maxMessageBytes must be an integer')
if (!Number.isSafeInteger(config.maxPendingCalls)) throw new Error('ptc-runtime-node: maxPendingCalls must be an integer')
if (!Number.isSafeInteger(config.maxOldGenerationSizeMb)) throw new Error('ptc-runtime-node: maxOldGenerationSizeMb must be an integer')
}