Files
deepseek-harness/packages/ptc-runtime/ptc-runtime-node/src/launch.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

76 lines
4.1 KiB
TypeScript

/** Select source or built bootstrap assets in the mounted execution world. */
import { dirname, isAbsolute, resolve } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'
import type { FileSystem } from '@deepseek-ai/dsh-fs'
import { assertNever } from '@deepseek-ai/dsh-util-values'
/** Deployment-owned worker invocation in the subprocess execution world. */
export type LaunchConfig = {
/** Start a separately installed Node executable and JavaScript bootstrap. */
kind: 'node-script'
/** Executable name or path resolved by the subprocess provider. */
executable: string
/** Absolute preinstalled bootstrap; omitted maps this package's bootstrap into the execution world. */
bootstrapPath?: string
} | {
/** Start the private PTC worker embedded in a packaged executable. */
kind: 'embedded'
/** Packaged executable name or path resolved by the subprocess provider. */
executable: string
}
/**
* Resolve the local carrier default or validate an explicit execution-world invocation.
* @param config - explicit remote or local worker configuration; omitted selects this carrier.
* @returns the worker invocation without guessing from the execution world's paths.
*/
export function resolveLaunch(config?: LaunchConfig): LaunchConfig {
const launch: LaunchConfig = config ?? { kind: 'pkg' in process ? 'embedded' : 'node-script', executable: process.execPath }
if (launch.executable.length === 0) throw new Error('ptc-runtime-node: launch.executable must be non-empty')
if (launch.kind === 'node-script' && launch.bootstrapPath !== undefined && !isAbsolute(launch.bootstrapPath)) {
throw new Error('ptc-runtime-node: launch.bootstrapPath must be absolute')
}
return launch
}
/**
* Select explicit arguments without inheriting host loader or inspector flags.
* @param fs - Filesystem mapping host bootstrap assets into the process world.
* @param config - resolved worker invocation.
* @param maxMessageBytes - Validated message and queued-write limit.
* @param persistent - Select the in-memory REPL bootstrap instead of the one-shot evaluator.
* @returns Arguments following the resolved Node executable.
*/
export function bootstrapArgs(fs: Pick<FileSystem, 'processPathFromHostPath'>, config: LaunchConfig, maxMessageBytes: number, persistent = false): string[] {
switch (config.kind) {
case 'embedded':
if (persistent) throw new Error('Persistent PTC requires a node-script launch')
return [String(maxMessageBytes)]
case 'node-script': return scriptBootstrapArgs(fs, config.bootstrapPath, maxMessageBytes, persistent)
/* v8 ignore next -- Callers supply the resolved, closed LaunchConfig union. */
default: return assertNever(config)
}
}
function scriptBootstrapArgs(
fs: Pick<FileSystem, 'processPathFromHostPath'>, bootstrapPath: string | undefined, maxMessageBytes: number, persistent: boolean,
): string[] {
const moduleName = persistent ? 'persistent-process' : 'process'
if (bootstrapPath !== undefined) return [bootstrapPath, String(maxMessageBytes)]
const mapped = (path: string): string => {
const result = fs.processPathFromHostPath(path)
if (result === undefined) throw new Error(`PTC runtime bootstrap is unavailable in the subprocess execution world: ${path}`)
return result
}
/* v8 ignore next 3 -- built-lib.e2e.ts executes the bundled provider and sibling process.js under plain Node. */
if (!new URL(import.meta.url).pathname.endsWith('.ts')) {
return [mapped(fileURLToPath(new URL(`./${moduleName}.js`, import.meta.url))), String(maxMessageBytes)]
}
const entry = mapped(fileURLToPath(new URL(`./${moduleName}.ts`, import.meta.url)))
const subprocess = dirname(fileURLToPath(import.meta.resolve('@deepseek-ai/dsh-subprocess/package.json')))
const helper = mapped(resolve(subprocess, 'src/control.ts'))
const main = persistent ? 'runPersistentMain' : 'runNodeMain'
const source = `const {openInheritedControlChannel}=await import(${JSON.stringify(pathToFileURL(helper).href)});const {${main}}=await import(${JSON.stringify(pathToFileURL(entry).href)});await ${main}(openInheritedControlChannel(),${maxMessageBytes},process);`
return ['--input-type=module', '--eval', source]
}