Introduce @deepseek-ai/dsh-code-runtime-python with the versionless JSON-lines protocol between the Node host and the CPython subprocess: the host-side hostile-frame codec (validateChildFrame, encodeJsonPlain, checkDoneValue, hasUnsafeIntegerToken, hasNonLosslessNumber, logTruncationMarker) and the Python-side wire-vocabulary mirror (py/protocol.py). This is the protocol layer of the code-runtime-python stack, split from #436 and based on the multi-language seam extension. The PythonCodeRuntime implementation and its Python JSON codec land in the backend-core PR on top of this branch. Ship the minimal buildable package skeleton (package.json, tsconfig, tsdown, barrel index, invariant companion, bilingual README) because the workspace-constraint, coverage, and invariant-topology gates require the package to exist and build the moment its directory does; the backend-core PR extends those files rather than creating them. Align py/protocol.py with src/protocol.ts (the round-12 review of #436 found LogMessage.truncated, DoneMessage.error.kind, and Namespace.errorClass stale) and guard the two runtime-executed surfaces (PROTOCOL_FD and the log truncation marker) with a real-python3 cross-language mirror e2e test.
2.9 KiB
@deepseek-ai/dsh-code-runtime-python
English | 中文
@deepseek-ai/dsh-code-runtime seam 的 CPython 子进程实现。与 @deepseek-ai/dsh-code-runtime-worker 配套;以全新的 python3 子进程取代 Node worker 线程,让模型代码从 TypeScript 换成 Python。
本包分多个 code-runtime-python PR 逐层搭建。本层交付 wire protocol;在其之上驱动 python3 -I 进程的 PythonCodeRuntime 实现随后落地。
Wire protocol
host 与 CPython 子进程在子进程的 fd 3 上交换一个无版本号的 JSON-lines 协议——每行一个 JSON 对象,让 stdout/stderr 空出给程序自己的输出。src/protocol.ts 是 host 侧;py/protocol.py 在 Python 侧镜像其帧词汇与共享的截断标记文本。
- fd 3,而非 stdout —— Node 通过
stdio: ['pipe','pipe','pipe','pipe']按位置钉住通道;Python bootstrap 读取相同的PROTOCOL_FD常量。JSON-lines 帧。 - host 把每个入站帧当作敌意输入 —— 模型代码对 fd 3 有完全访问权、可通过它发送任意内容,所以
validateChildFrame在 host 读取前对每个帧做形状校验并重建:伪造的额外字段绝不随行,非数字的 call id 绝不会被回显进 reply,垃圾降为undefined被丢弃,而不是在 host 的 message handler 里抛错。Python 侧信任 host 回复(host 不受模型控制)。 - lossless-JSON 穿越 —— 完成值与 binding 参数以精确 JSON 穿越。
encodeJsonPlain无递归地序列化一个JSON.parse产出的值,使低于字节预算的深层值能完整穿越,而不是死在JSON.stringify的栈限制上;checkDoneValue在一次有界遍历中同时计量伪造完成值的字节长度与数字无损性,在把子节点入栈之前就拒绝超预算 payload;hasUnsafeIntegerToken读取原始帧文本,捕获JSON.parse会静默舍入的整数 token;hasNonLosslessNumber拒绝无字节上限的call.args中的非有限数或负零。超出安全范围的整数型 double 通过BigInt数字序列化,穿越的是精确整数而非String()的舍入形式。 - 共享截断标记 ——
logTruncationMarker(maxBytes)在两侧产出逐字节一致的文本,使被截断的日志运行无论从哪侧触达上限都读起来一致。log帧的truncated标志把子进程 ledger 自身的标记与程序输出区分开。
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.