Address the two standing review suggestions in this layer rather than deferring them to PR #4: - Extend tests/protocol-mirror.e2e.ts to read each py/protocol.py TypedDict's required/optional key set and assert it against the wire field names src/protocol.ts declares (global included, via functional TypedDict). The round-12 class of drift — a renamed/dropped field, or one side making a field optional the other requires — now fails a test instead of relying on review. Field types remain review-guarded (no mechanical TS/Python equivalent). - Drop the forward references to PR #4's internal mechanisms from this layer's prose: the "256 MiB frame ceiling" figure and the "(index.ts)" fd-3 pinning citation become an abstract "host-side inbound frame-size cap" so the JSDoc, spec, README, and Agent Note describe only what this layer owns. Update both README sides and the Agent Note (both languages) to state the mirror is now executable, and re-record their i18n pairings.
@deepseek-ai/dsh-code-runtime-python
English | 中文
CPython-subprocess implementation of the @deepseek-ai/dsh-code-runtime seam. Companion to @deepseek-ai/dsh-code-runtime-worker; trades the Node worker thread for a fresh python3 subprocess so model code is Python instead of TypeScript.
This package is built up across the code-runtime-python PR stack. This layer ships the wire protocol; the PythonCodeRuntime implementation that drives a python3 -I process over it lands on top of it.
Wire protocol
The host and the CPython subprocess exchange a versionless, JSON-lines protocol on the child's fd 3 — one JSON object per line, leaving stdout/stderr free for the program's own output. src/protocol.ts is the host side; py/protocol.py mirrors its message shapes and the shared truncation-marker text on the Python side.
- fd 3, not stdout — Node pins the channel positionally with
stdio: ['pipe','pipe','pipe','pipe']; the Python bootstrap reads the samePROTOCOL_FDconstant. JSON-lines framing. - Host treats every inbound frame as hostile — model code has full access to fd 3 and can post anything through it, so
validateChildFrameshape-validates and REBUILDS each frame before the host reads it: forged extra fields never ride along, a non-number call id can never be echoed into a reply, and junk drops toundefinedrather than throwing in the host's message handler. The Python side trusts host replies (the host is not model-controlled). - Lossless-JSON crossing — completion values and binding arguments cross as exact JSON.
encodeJsonPlainserializes aJSON.parse-produced value without recursion, so a deep value below the byte budget crosses intact instead of dying onJSON.stringify's stack limit;checkDoneValuemeters a forged completion value's byte length AND number losslessness in one traversal that rejects an over-budget payload before the incremental work it would add (escaped-string copy, enqueued children, per-keyJSON.stringify) — the frame's own width is already parsed and capped upstream by the host's fd-3 receive buffer, not re-bounded here;hasUnsafeIntegerTokenreads the raw frame text to catch an integer token thatJSON.parsewould silently round;hasNonLosslessNumberrejects a non-finite or negative-zero number in unboundedcall.args. Beyond-safe-range integral doubles serialize throughBigIntdigits so the exact integer crosses, not the roundedString()form. - Shared truncation marker —
logTruncationMarker(maxBytes)produces byte-identical text on both sides, so a truncated log run reads the same however the cap was hit. Thelogframe'struncatedflag distinguishes the child ledger's own marker from program output.
Model Experience
Indirectly, through Code Mode in dsh-tools, which renders this backend's exact completion value when it fits (or an explicit invalid-output / output-limit failure), plus the exact [dsh-code-runtime-python] log capture truncated at <maxLogBytes> bytes log marker, into a retained run_code result.
KV Cache effect
No direct invalidation; the named consumer owns any request-prefix changes.
Known Limitations and Deferred Work
- The cross-language guard covers the runtime-executed surfaces and the frame field shapes —
tests/protocol-mirror.e2e.tsspawns a realpython3and asserts, againstsrc/protocol.ts, bothPROTOCOL_FD/ the log truncation marker text AND eachTypedDict's required/optional wire field set inpy/protocol.py. What it does not compare is the field types (e.g. thatcpuSecondsis aninton both sides): comparing type declarations across TypeScript and Python has no mechanical equivalent here, so a type-level drift is still caught by review plus the backend's real-subprocess suite rather than this package's tests. - The
PythonCodeRuntimeimplementation and its Python-side JSON codec are not in this layer — they ship in the backend-core PR on top of this branch;src/index.tsre-exports only the protocol vocabulary until then.