fix(build): stage platform-specific PTY artifacts

This commit is contained in:
Tianyi Cui
2026-07-29 22:44:19 +08:00
parent 7fdde06cf9
commit c0bd88430a
14 changed files with 141 additions and 105 deletions
+2 -2
View File
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write python/sdk-runtime/README.md
README.md: 0869b4a9dce0e261b168f21c90a80faf81ea4a64
README.zh.md: 3f2342c4c66e24b8213c78d4e7530c3360497022
README.md: 29ffc1dcc3ec3b273ccaee64734739f3c4f34b9c
README.zh.md: d79c87090867c60e09c50016bad4797170b34400
+1 -1
View File
@@ -8,7 +8,7 @@ Runtime carrier package for the Python SDK (dist `deepseek-harness-runtime-bin`,
Two carriers coexist under `src/deepseek_harness_runtime/runtime/`, both injected by the repo's `scripts/build-exe-for-python-sdk.ts` build and both gitignored:
- **exe (production)** — a single-file Node executable `dsh-jsonrpc-agent-pkg-<platform>-<arch>` plus its native `-spawn-helper` sibling (platform: `linux`/`macos`; arch: `x64`/`arm64`). The helper is required by `node-pty`; both files are built as one runtime product, and ELF or thin Mach-O headers must match the target. No Node installation is needed on the target machine. This is the only carrier that ships in wheel distributions; this package does not publish sdists.
- **exe (production)** — a single-file Node executable `dsh-jsonrpc-agent-pkg-<platform>-<arch>` (platform: `linux`/`macos`; arch: `x64`/`arm64`). macOS builds also ship the native `-spawn-helper` sibling that `node-pty` uses there, and its thin Mach-O header must match the target. No Node installation is needed on the target machine. This is the only carrier that ships in wheel distributions; this package does not publish sdists.
- **node (dev-only)** — the full deploy closure under `runtime/node/` (`package.json` + `node_modules/`), executed as `node runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-demo/lib/bin.js` on a system Node >= 22.19. It is the current checkout's source build, meant for repo-local development and verification only; it is never selected automatically and is excluded from distributions.
Both carriers hold the same content, defined once: the [package.json](package.json) at this package's root is the deploy root of the single-exe pipeline — a pure dependency manifest (no code of its own) whose dependency closure IS both the plugin set compiled into the exe and the tree materialized into `runtime/node/`. Adding a plugin to the distribution means adding one dependency line there and rebuilding.
+1 -1
View File
@@ -8,7 +8,7 @@ Python SDK 的运行时载体包(分发名 `deepseek-harness-runtime-bin`
两种载体并存于 `src/deepseek_harness_runtime/runtime/` 之下,均由仓库的 `scripts/build-exe-for-python-sdk.ts` 构建注入,且均被 git 忽略:
- **exe(生产)**——单文件 Node 可执行程序 `dsh-jsonrpc-agent-pkg-<platform>-<arch>` 及其原生 `-spawn-helper` 伴随文件platform`linux`/`macos`arch`x64`/`arm64`)。`node-pty` 需要该 helper;两者作为一个运行时产物构建,且 ELF 或 thin Mach-O 文件头必须与目标匹配。目标机器无需安装 Node。这是唯一随 wheel 包分发的载体;本包不发布 sdist。
- **exe(生产)**——单文件 Node 可执行程序 `dsh-jsonrpc-agent-pkg-<platform>-<arch>`platform`linux`/`macos`arch`x64`/`arm64`)。macOS 构建还会随附 `node-pty` 在该平台使用的原生 `-spawn-helper` 伴随文件,其 thin Mach-O 文件头必须与目标匹配。目标机器无需安装 Node。这是唯一随 wheel 包分发的载体;本包不发布 sdist。
- **`node`(仅限开发)**——`runtime/node/` 下的完整部署闭包(`package.json` + `node_modules/`),在系统 Node >= 22.19 上以 `node runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-demo/lib/bin.js` 执行。它是当前检出的源码构建,仅用于仓库本地的开发与验证;不会被自动选中,也不进入分发物。
两种载体承载相同的内容,且只定义一次:本包根目录的 [package.json](package.json) 是 single-exe 流水线的部署根目录——一份零代码的纯依赖 manifest,其依赖闭包既是编译进 exe 的插件集,也是物化到 `runtime/node/` 的文件树。往分发物里加插件,就是在那里加一行依赖再重新构建。
+12 -17
View File
@@ -17,26 +17,18 @@ _SPAWN_HELPER_SUFFIX = "-spawn-helper"
def _spawn_helper_binary_target(header: bytes) -> str | None:
if (
len(header) >= 20
and header[:4] == b"\x7fELF"
and header[4] == 2
and header[5] == 1
):
machine = int.from_bytes(header[18:20], "little")
if machine == 62:
return "linux-x64"
if machine == 183:
return "linux-arm64"
if len(header) >= 8 and header[:4] == b"\xcf\xfa\xed\xfe":
if int.from_bytes(header[4:8], "little") == 0x0100000C:
cpu_type = int.from_bytes(header[4:8], "little")
if cpu_type == 0x01000007:
return "macos-x64"
if cpu_type == 0x0100000C:
return "macos-arm64"
return None
def _validate_spawn_helper(path: Path, expected_target: str) -> None:
with path.open("rb") as helper:
actual_target = _spawn_helper_binary_target(helper.read(20))
actual_target = _spawn_helper_binary_target(helper.read(8))
if actual_target != expected_target:
raise RuntimeError(
f"runtime spawn helper binary mismatch: expected {expected_target}, "
@@ -84,15 +76,18 @@ class RuntimeBuildHook(BuildHookInterface):
f"runtime wheel {platform_tag} must contain only {expected_executable}; found {found}"
)
expected_helper = f"{expected_executable}{_SPAWN_HELPER_SUFFIX}"
if [path.name for path in helpers] != [expected_helper]:
expected_helpers = [expected_helper] if expected_target.startswith("macos-") else []
if [path.name for path in helpers] != expected_helpers:
expected = ", ".join(expected_helpers) or "none"
found = ", ".join(path.name for path in helpers) or "none"
raise RuntimeError(
f"runtime wheel {platform_tag} must contain only {expected_helper}; found {found}"
f"runtime wheel {platform_tag} helper payload mismatch: expected {expected}; found {found}"
)
for executable in [executables[0], helpers[0]]:
for executable in [executables[0], *helpers]:
if executable.stat().st_mode & stat.S_IXUSR == 0:
raise RuntimeError(f"runtime executable is not executable: {executable}")
_validate_spawn_helper(helpers[0], expected_target)
if helpers:
_validate_spawn_helper(helpers[0], expected_target)
build_data["pure_python"] = False
build_data["infer_tag"] = False