fix: address Python release review feedback
This commit is contained in:
@@ -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: 0774ad206b366c59c40edf21c0cdb9b3993510f9
|
||||
README.zh.md: bbe9f871b183bc83e1113594dfd29e1f81e06ac2
|
||||
README.md: 71dedf4cb8064d55bd64b32008b452158a1b154f
|
||||
README.zh.md: 83c99ed33b2a4ffe00bcb3fe670be455664bfa18
|
||||
@@ -1,6 +1,6 @@
|
||||
# DeepSeek Harness Runtime Wheel
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
English | [中文](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk-runtime/README.zh.md)
|
||||
|
||||
Runtime carrier package for the Python SDK (dist `deepseek-harness-runtime-bin`, module `deepseek_harness_runtime`): it locates the bundled runtime binaries the `deepseek-harness-sdk` client spawns, and ships the default configuration behind zero-config runs.
|
||||
|
||||
@@ -15,7 +15,7 @@ Both carriers hold the same content, defined once: the [package.json](https://gi
|
||||
|
||||
A missing exe raises `FileNotFoundError` naming both acquisition routes: build via `scripts/build-exe-for-python-sdk.ts` in a deepseek-harness checkout, or install the matching platform runtime wheel produced by the `build-exe-for-python-sdk` CI workflow. A missing dev-only node carrier names its sole route, the build script. The workflow retains wheels rather than standalone executable archives. Acquisition strategy is deliberately separate from the lookup interface, so an on-demand download can replace it later without touching callers.
|
||||
|
||||
Each wheel contains exactly one runtime executable. The macOS wheel also contains its matching native spawn helper; a missing sidecar makes that installation incomplete and is a hard startup error, even for a selected Cordis composition that does not use PTY tools. Linux wheels contain no spawn helper because `node-pty` uses the staged `pty.node` addon directly. The fixed tags are `py3-none-manylinux_2_28_x86_64`, `py3-none-manylinux_2_28_aarch64`, and `py3-none-macosx_14_0_arm64`; the macOS tag conservatively matches the bundled Node 24 executable's macOS 13.5 deployment target. The build hook rejects `py3-none-any`, absent or multiple runtime files, non-executable files, and unsupported platform tags. The repository root `package.json` supplies the shared version for this package and the SDK, and a `python-v<repository-version>` release tag must match it.
|
||||
Each wheel contains exactly one runtime executable. The macOS wheel also contains its matching native spawn helper; a missing sidecar makes that installation incomplete and is a hard startup error, even for a selected Cordis composition that does not use PTY tools. Linux wheels contain no spawn helper because `node-pty` uses the staged `pty.node` addon directly. The fixed tags are `py3-none-manylinux_2_28_x86_64`, `py3-none-manylinux_2_28_aarch64`, and `py3-none-macosx_14_0_arm64`; the macOS tag conservatively matches the bundled Node 24 executable's macOS 13.5 deployment target. This package's `platforms.json` owns the fixed tag and executable-name pairs used by both the repository release builder and the isolated build hook. The build hook rejects `py3-none-any`, absent or multiple runtime files, non-executable files, and unsupported platform tags. The repository root `package.json` supplies the shared version for this package and the SDK, and a `python-v<repository-version>` release tag must match it.
|
||||
|
||||
## Resolution API
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# DeepSeek Harness 运行时 wheel 包
|
||||
|
||||
[English](README.md) | 中文
|
||||
[English](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk-runtime/README.md) | 中文
|
||||
|
||||
Python SDK 的运行时载体包(分发名 `deepseek-harness-runtime-bin`,模块名 `deepseek_harness_runtime`):它定位 `deepseek-harness-sdk` 客户端要 spawn 的内置运行时二进制,并附带支撑零配置运行的默认配置。
|
||||
|
||||
@@ -15,7 +15,7 @@ Python SDK 的运行时载体包(分发名 `deepseek-harness-runtime-bin`,
|
||||
|
||||
exe 缺失时抛出 `FileNotFoundError`,并写明两种获取途径:在 deepseek-harness 检出中经 `scripts/build-exe-for-python-sdk.ts` 构建,或安装 `build-exe-for-python-sdk` CI 工作流生成的对应平台运行时 wheel 包。仅限开发的 node 载体缺失时只提示构建脚本这一条途径。该工作流只保留 wheel 包,不保留独立 exe 归档。获取策略与查找接口刻意分离,之后可以换成按需下载而不改动任何调用方。
|
||||
|
||||
每个 wheel 包只包含一个运行时可执行文件。macOS wheel 包还包含与其匹配的原生 spawn helper;缺少伴随文件意味着该安装不完整,并会在启动时硬失败,即使所选 Cordis 组合不使用 PTY 工具也是如此。Linux wheel 包不包含 spawn helper,因为 `node-pty` 直接使用暂存的 `pty.node` 原生插件。固定标签为 `py3-none-manylinux_2_28_x86_64`、`py3-none-manylinux_2_28_aarch64` 与 `py3-none-macosx_14_0_arm64`;macOS 标签保守匹配内置 Node 24 可执行文件的 macOS 13.5 部署目标。构建钩子会拒绝 `py3-none-any`、不存在运行时文件、存在多个运行时文件、文件不可执行以及不支持的平台标签。仓库根目录的 `package.json` 为本包和 SDK 提供共同版本,`python-v<repository-version>` 发布标签必须与其匹配。
|
||||
每个 wheel 包只包含一个运行时可执行文件。macOS wheel 包还包含与其匹配的原生 spawn helper;缺少伴随文件意味着该安装不完整,并会在启动时硬失败,即使所选 Cordis 组合不使用 PTY 工具也是如此。Linux wheel 包不包含 spawn helper,因为 `node-pty` 直接使用暂存的 `pty.node` 原生插件。固定标签为 `py3-none-manylinux_2_28_x86_64`、`py3-none-manylinux_2_28_aarch64` 与 `py3-none-macosx_14_0_arm64`;macOS 标签保守匹配内置 Node 24 可执行文件的 macOS 13.5 部署目标。本包的 `platforms.json` 统一定义仓库发行构建器与隔离构建钩子使用的固定标签和可执行文件名。构建钩子会拒绝 `py3-none-any`、不存在运行时文件、存在多个运行时文件、文件不可执行以及不支持的平台标签。仓库根目录的 `package.json` 为本包和 SDK 提供共同版本,`python-v<repository-version>` 发布标签必须与其匹配。
|
||||
|
||||
## 解析 API
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import stat
|
||||
@@ -8,11 +9,30 @@ from pathlib import Path
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
|
||||
|
||||
_PLATFORMS = {
|
||||
"linux-x64": ("manylinux_2_28_x86_64", "dsh-jsonrpc-agent-pkg-linux-x64"),
|
||||
"linux-arm64": ("manylinux_2_28_aarch64", "dsh-jsonrpc-agent-pkg-linux-arm64"),
|
||||
"macos-arm64": ("macosx_14_0_arm64", "dsh-jsonrpc-agent-pkg-macos-arm64"),
|
||||
}
|
||||
def _load_platforms() -> dict[str, tuple[str, str]]:
|
||||
"""Load and validate the platform manifest inside an isolated wheel build."""
|
||||
path = Path(__file__).with_name("platforms.json")
|
||||
try:
|
||||
payload = json.loads(path.read_text())
|
||||
except (OSError, json.JSONDecodeError) as error:
|
||||
raise RuntimeError(f"could not read runtime platform manifest from {path}") from error
|
||||
if not isinstance(payload, dict) or not payload:
|
||||
raise RuntimeError(f"{path} must contain a non-empty platform object")
|
||||
platforms: dict[str, tuple[str, str]] = {}
|
||||
for name, raw in payload.items():
|
||||
if (
|
||||
not isinstance(name, str)
|
||||
or not isinstance(raw, dict)
|
||||
or set(raw) != {"tag", "executable"}
|
||||
or not isinstance(raw["tag"], str)
|
||||
or not isinstance(raw["executable"], str)
|
||||
):
|
||||
raise RuntimeError(f"{path} platform entries must contain string tag and executable fields")
|
||||
platforms[name] = (raw["tag"], raw["executable"])
|
||||
return platforms
|
||||
|
||||
|
||||
_PLATFORMS = _load_platforms()
|
||||
|
||||
|
||||
def _host_platform_tag() -> str:
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"linux-x64": {
|
||||
"tag": "manylinux_2_28_x86_64",
|
||||
"executable": "dsh-jsonrpc-agent-pkg-linux-x64"
|
||||
},
|
||||
"linux-arm64": {
|
||||
"tag": "manylinux_2_28_aarch64",
|
||||
"executable": "dsh-jsonrpc-agent-pkg-linux-arm64"
|
||||
},
|
||||
"macos-arm64": {
|
||||
"tag": "macosx_14_0_arm64",
|
||||
"executable": "dsh-jsonrpc-agent-pkg-macos-arm64"
|
||||
}
|
||||
}
|
||||
@@ -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/README.md
|
||||
README.md: 649dbed7afa0f11177f87984033aa58ac7d8ac2e
|
||||
README.zh.md: 75e6ba91152af527395fa53903e53fd0d056bdb5
|
||||
README.md: 0f91f3d9b5e770852a0c1e638b1506a14b8d65c0
|
||||
README.zh.md: a3adb241f5d27b49ecab2f1541dfd9775a34a24f
|
||||
@@ -1,6 +1,6 @@
|
||||
# DeepSeek Harness Python SDK
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
English | [中文](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk/README.zh.md)
|
||||
|
||||
Python subprocess SDK for driving DeepSeek Harness over JSON-RPC stdio. The
|
||||
runtime inherits normal DeepSeek Harness environment variables such as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# DeepSeek Harness Python SDK
|
||||
|
||||
[English](README.md) | 中文
|
||||
[English](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk/README.md) | 中文
|
||||
|
||||
通过 JSON-RPC stdio 驱动 DeepSeek Harness 的 Python 子进程 SDK。运行时继承常规的 DeepSeek Harness 环境变量(如 `DEEPSEEK_BASE_URL` 与 `DEEPSEEK_API_KEY`),调用方可以直接使用真实模型端点,也可以把这些变量指向本地代理。
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Tests for macOS runtime wheel deployment-target validation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import runpy
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
SCRIPT = ROOT / "scripts" / "check-macos-deployment-target.py"
|
||||
checker = SimpleNamespace(**runpy.run_path(str(SCRIPT)))
|
||||
|
||||
|
||||
def test_otool_parser_uses_the_newest_macho_slice() -> None:
|
||||
output = """
|
||||
cmd LC_BUILD_VERSION
|
||||
minos 11.0
|
||||
cmd LC_BUILD_VERSION
|
||||
minos 13.5
|
||||
"""
|
||||
|
||||
assert checker.parse_otool_deployment_target(output) == (13, 5)
|
||||
|
||||
|
||||
def test_otool_parser_requires_a_deployment_target() -> None:
|
||||
with pytest.raises(ValueError, match="contains no LC_BUILD_VERSION"):
|
||||
checker.parse_otool_deployment_target("Load command 0\n")
|
||||
|
||||
|
||||
def test_wheel_tag_rejects_a_newer_executable_target() -> None:
|
||||
checker.ensure_compatible(Path("runtime"), (13, 5), "macosx_14_0_arm64")
|
||||
|
||||
with pytest.raises(RuntimeError, match="requires macOS 14.1"):
|
||||
checker.ensure_compatible(Path("spawn-helper"), (14, 1), "macosx_14_0_arm64")
|
||||
@@ -61,6 +61,14 @@ def test_macos_wheel_tag_does_not_claim_unsupported_node_platforms() -> None:
|
||||
assert build_python_release.PLATFORMS["macos-arm64"][0] == "macosx_14_0_arm64"
|
||||
|
||||
|
||||
def test_platform_manifest_rejects_incomplete_entries(tmp_path: Path) -> None:
|
||||
manifest = tmp_path / "platforms.json"
|
||||
manifest.write_text('{"macos-arm64":{"tag":"macosx_14_0_arm64"}}\n')
|
||||
|
||||
with pytest.raises(ValueError, match="tag and executable fields"):
|
||||
build_python_release.load_platforms(manifest)
|
||||
|
||||
|
||||
def test_stage_sdk_keeps_distribution_module_and_runtime_pin_distinct(tmp_path: Path) -> None:
|
||||
destination = tmp_path / "staging"
|
||||
|
||||
@@ -96,6 +104,9 @@ def test_stage_runtime_copies_platform_payload(
|
||||
assert {path.name: path.read_bytes() for path in runtime_dir.glob("dsh-jsonrpc-agent-pkg-*")} == expected
|
||||
pyproject = (destination / "pyproject.toml").read_text()
|
||||
assert 'license-files = ["LICENSE", "THIRD_PARTY_NOTICES.md"]' in pyproject
|
||||
assert (destination / "platforms.json").read_bytes() == (
|
||||
ROOT / "python" / "sdk-runtime" / "platforms.json"
|
||||
).read_bytes()
|
||||
assert (destination / "LICENSE").read_bytes() == (ROOT / "LICENSE").read_bytes()
|
||||
assert (destination / "THIRD_PARTY_NOTICES.md").read_bytes() == (
|
||||
ROOT / "THIRD_PARTY_NOTICES.md"
|
||||
|
||||
Reference in New Issue
Block a user