ci: retain only Python release wheels

This commit is contained in:
Yichen Jiang
2026-07-13 17:02:56 +08:00
parent cdd11ac587
commit ef2754110a
11 changed files with 74 additions and 114 deletions
+56 -95
View File
@@ -8,16 +8,10 @@ name: Build single-exe
# the dsh-jsonrpc-agent-pkg closure manifest with @yao-pkg/pkg into
# dist-exe/.
#
# Each build leg uploads two artifacts (both tar.gz — tar keeps file modes,
# so the exe's executable bit survives; upload-artifact's zip transport
# does not preserve them):
# - dsh-jsonrpc-agent-pkg-<target> — the bare single-file exe, for
# consumers that want just the binary.
# - deepseek-harness-python-<target> — the whole python/ directory with
# that exe already embedded (the build script syncs it into the Python
# runtime package): unpack and both packages pip install as-is, the
# checked-in default runtime/cordis.yml is editable in place, and the
# embedded exe also runs directly.
# The run retains exactly the four wheels that make up one Python release:
# one platform-independent SDK wheel plus one native runtime wheel for each
# supported platform. The matrix still exercises the bare executable and
# source tree, but they are intermediate test inputs rather than artifacts.
#
# Two explicit triggers, deliberately no per-commit CI: the exe is a
# release-style deliverable, and the build (full pnpm build + pnpm deploy +
@@ -103,8 +97,36 @@ jobs:
echo "Matrix: $matrix"
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
build:
sdk-wheel:
needs: plan
name: deepseek_harness-0.0.0-py3-none-any.whl
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: Install Python build tooling
run: python -m pip install uv==0.11.23
- name: Build release-shaped SDK wheel
run: >-
python scripts/build-python-release.py
--package sdk
--tag python-v0.0.0
--output-dir dist-python
- uses: actions/upload-artifact@v6
with:
name: deepseek_harness-0.0.0-py3-none-any.whl
path: dist-python/deepseek_harness-0.0.0-py3-none-any.whl
if-no-files-found: error
build:
needs: [plan, sdk-wheel]
name: ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
timeout-minutes: 45
@@ -163,7 +185,7 @@ jobs:
- name: Build single-exe
run: pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets=${{ matrix.target }}
- name: Resolve platform artifact names
- name: Resolve platform outputs
id: runtime
env:
TARGET: ${{ matrix.target }}
@@ -172,8 +194,15 @@ jobs:
platform="${TARGET#node24-}"
exe="$PWD/dist-exe/dsh-jsonrpc-agent-pkg-$platform"
[ -x "$exe" ] || { echo "::error::$exe missing or not executable"; exit 1; }
case "$platform" in
linux-x64) wheel=deepseek_harness_runtime_bin-0.0.0-py3-none-manylinux_2_28_x86_64.whl ;;
linux-arm64) wheel=deepseek_harness_runtime_bin-0.0.0-py3-none-manylinux_2_28_aarch64.whl ;;
macos-arm64) wheel=deepseek_harness_runtime_bin-0.0.0-py3-none-macosx_11_0_arm64.whl ;;
*) echo "::error::Unsupported runtime platform $platform"; exit 1 ;;
esac
echo "platform=$platform" >> "$GITHUB_OUTPUT"
echo "exe=$exe" >> "$GITHUB_OUTPUT"
echo "wheel=$wheel" >> "$GITHUB_OUTPUT"
- name: Full-turn SDK, custom cordis, and direct-binary smoke
run: >-
@@ -182,19 +211,19 @@ jobs:
--scenario all
--exe "${{ steps.runtime.outputs.exe }}"
- name: Build release-shaped SDK and runtime wheels
run: |
set -euo pipefail
python scripts/build-python-release.py \
--package sdk \
--tag python-v0.0.0 \
--output-dir dist-python
python scripts/build-python-release.py \
--package runtime \
--tag python-v0.0.0 \
--platform "${{ steps.runtime.outputs.platform }}" \
--runtime-exe "${{ steps.runtime.outputs.exe }}" \
--output-dir dist-python
- name: Build release-shaped runtime wheel
run: >-
python scripts/build-python-release.py
--package runtime
--tag python-v0.0.0
--platform "${{ steps.runtime.outputs.platform }}"
--runtime-exe "${{ steps.runtime.outputs.exe }}"
--output-dir dist-python
- uses: actions/download-artifact@v8
with:
name: deepseek_harness-0.0.0-py3-none-any.whl
path: dist-python
- name: Install only the SDK into a clean venv and run zero-config
run: |
@@ -235,76 +264,8 @@ jobs:
/tmp/dsh-sdk/bin/python /work/scripts/smoke-python-runtime.py --scenario sdk-default
'
# The bare exe ships inside a tar.gz (the mode-preservation note in
# the header): uploading dist-exe/ bare would hand consumers a 0644
# file that subprocess.Popen refuses to run.
- name: Pack bare exe
id: pack-exe
env:
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
exe_tar="dsh-jsonrpc-agent-pkg-${TARGET}.tar.gz"
tar -czf "$exe_tar" -C dist-exe .
ls -lh "$exe_tar"
echo "tar=$exe_tar" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v6
with:
name: dsh-jsonrpc-agent-pkg-${{ matrix.target }}
path: ${{ steps.pack-exe.outputs.tar }}
if-no-files-found: error
# After the build step, python/ is already in its complete
# distributable shape — the script synced this leg's exe into
# python/sdk-runtime/src/deepseek_harness_runtime/runtime/ next to the
# checked-in default cordis.yml — so packing is all that is left.
# Everything goes under one top-level deepseek-harness-python/
# directory so unpacking never scatters files.
#
# Excluded: runtime/node/ (dev-only node-mode carrier, ~140MB) plus
# __pycache__ / .pytest_cache / .venv / node_modules anywhere (install
# or test leftovers); uv.lock stays in.
#
# Portability: GNU tar (ubuntu) and bsdtar (macos) both accept
# `tar -czf out.tar.gz --exclude=… -C <parent> <dir>` and both treat
# an excluded directory as pruned (no descent). The top-level rename
# is done by copying into a temp dir first — GNU --transform / BSD -s
# are single-implementation flags.
- name: Pack Python SDK bundle
id: pack
env:
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
platform_arch="${TARGET#*-}" # node24-macos-arm64 -> macos-arm64
exe="python/sdk-runtime/src/deepseek_harness_runtime/runtime/dsh-jsonrpc-agent-pkg-${platform_arch}"
if [ ! -x "$exe" ]; then
echo "::error::$exe missing or not executable — the build step did not sync this leg's exe into the Python runtime package; refusing to pack a half-empty bundle."
exit 1
fi
staging="$(mktemp -d)"
cp -R python "$staging/deepseek-harness-python"
bundle="deepseek-harness-python-${platform_arch}.tar.gz"
tar -czf "$bundle" \
--exclude='deepseek-harness-python/sdk-runtime/src/deepseek_harness_runtime/runtime/node' \
--exclude='__pycache__' \
--exclude='.pytest_cache' \
--exclude='.venv' \
--exclude='node_modules' \
-C "$staging" deepseek-harness-python
rm -rf "$staging"
ls -lh "$bundle"
echo "bundle=$bundle" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v6
with:
name: deepseek-harness-python-${{ matrix.target }}
path: ${{ steps.pack.outputs.bundle }}
if-no-files-found: error
- uses: actions/upload-artifact@v6
with:
name: deepseek-harness-wheels-${{ matrix.target }}
path: dist-python/*.whl
name: ${{ steps.runtime.outputs.wheel }}
path: dist-python/${{ steps.runtime.outputs.wheel }}
if-no-files-found: error
@@ -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
2026-07-10-single-file-executable-sdk-runtime-distribution.md: 0e463a23227bfb8f8eef5ee1a21bcddd9151c8e4
2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 2ce32f9bba20e85fa67559389be9d2d5c7e60cee
2026-07-10-single-file-executable-sdk-runtime-distribution.md: 474a7af7f2cfe9177dec779e3eb50fd6034e806d
2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md: 1f436d63fc91420c6da6d92e32bd16d5936ced5d
@@ -40,9 +40,9 @@ The deploy root is [`python/sdk-runtime/package.json`](../../../../python/sdk-ru
### Build pipeline and artifacts
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts): runtime closure verification → `pnpm run build` → (after clearing) `pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **directly into** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/` → inject the pkg configuration (`bin` points at `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js` inside the closure, `assets` is a full glob — dynamic import is invisible to pkg's static analysis, so everything must be packed in explicitly) → one `pkg --sea` per target → the artifacts `dsh-jsonrpc-agent-pkg-<platform>-<arch>` land in `dist-exe/` (the CI artifact) and are copied back into the runtime directory. All four deploy flags are grounded in measurement: `--legacy` is the mandatory path with inject-workspace-packages off; hoisted yields a zero-symlink file tree (most stable for the pkg VFS, physically guaranteeing a single cordis instance); disabling automatic peer installation keeps unpublished package names from triggering registry resolution; link-workspace-packages points the closure at workspace/vendor sources.
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts): runtime closure verification → `pnpm run build` → (after clearing) `pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **directly into** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/` → inject the pkg configuration (`bin` points at `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js` inside the closure, `assets` is a full glob — dynamic import is invisible to pkg's static analysis, so everything must be packed in explicitly) → one `pkg --sea` per target → the executables `dsh-jsonrpc-agent-pkg-<platform>-<arch>` land in `dist-exe/` and are copied back into the runtime directory. CI treats them as intermediate test inputs and retains their platform wheels. All four deploy flags are grounded in measurement: `--legacy` is the mandatory path with inject-workspace-packages off; hoisted yields a zero-symlink file tree (most stable for the pkg VFS, physically guaranteeing a single cordis instance); disabling automatic peer installation keeps unpublished package names from triggering registry resolution; link-workspace-packages points the closure at workspace/vendor sources.
CI: [`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml), triggered explicitly only — `workflow_dispatch`, or the `build-exe` label on a pull request; native builds on the three platforms linux-x64 / linux-arm64 (`ubuntu-24.04-arm`) / macos-arm64, with `~/.pkg-cache` cached and artifacts uploaded per platform; macOS ad-hoc signing is handled by pkg. Each leg drives a mock SSE model through the SDK with the default config and a custom `cordis.yml`, drives the exe directly over NDJSON JSON-RPC, verifies the JSONL and final response, and installs release-shaped wheels into a clean venv without `runtime_bin`; Linux additionally inspects GLIBC requirements and runs in a manylinux 2.28 container. [`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) accepts only `python-vX.Y.Z` tag pipelines, builds one SDK wheel and three native runtime wheels, then a single serialized job checks and publishes all four to the project PyPI registry. Windows is a non-goal.
CI: [`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml), triggered explicitly only — `workflow_dispatch`, or the `build-exe` label on a pull request; native builds on the three platforms linux-x64 / linux-arm64 (`ubuntu-24.04-arm`) / macos-arm64, with `~/.pkg-cache` cached; macOS ad-hoc signing is handled by pkg. Each leg drives a mock SSE model through the SDK with the default config and a custom `cordis.yml`, drives the exe directly over NDJSON JSON-RPC, verifies the JSONL and final response, and installs release-shaped wheels into a clean venv without `runtime_bin`; Linux additionally inspects GLIBC requirements and runs in a manylinux 2.28 container. The run retains only four artifacts, each containing one release file: the platform-independent SDK wheel and the three native runtime wheels; bare executables and source bundles remain intermediate test inputs. [`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) accepts only `python-vX.Y.Z` tag pipelines, builds one SDK wheel and three native runtime wheels, then a single serialized job checks and publishes all four to the project PyPI registry. Windows is a non-goal.
### Python SDK distribution: two carriers, exe for production, node for development
@@ -62,7 +62,7 @@ The exe's "must be explicitly configured" hard semantic is unchanged; the zero-c
## Testing
The verification surface has three tiers. Mechanism tier: the measured conclusions for the `--sea` chain are embedded in the Decision sections (ESM dynamic import inside the VFS, single cordis instance, fail-loud config chain, `node:sqlite`, macOS ad-hoc signing runs). SDK tier: the complete keyless pytest suite covers the client protocol against a fake runtime peer, subprocess cleanup, absolute cwd propagation, dual-carrier launch, and carrier resolution; root CI runs it on Python 3.10. End-to-end tier: every platform artifact completes a turn against a mock endpoint through the default SDK path, a custom config, and the direct binary protocol, with final text and JSONL checked; its platform wheel is then installed in a clean venv and run without `runtime_bin`. The JSON-RPC protocol is not part of the ACP snapshot system, so there is no snapshot tier (an explicitly named gap, not an oversight).
The verification surface has three tiers. Mechanism tier: the measured conclusions for the `--sea` chain are embedded in the Decision sections (ESM dynamic import inside the VFS, single cordis instance, fail-loud config chain, `node:sqlite`, macOS ad-hoc signing runs). SDK tier: the complete keyless pytest suite covers the client protocol against a fake runtime peer, subprocess cleanup, absolute cwd propagation, dual-carrier launch, and carrier resolution; root CI runs it on Python 3.10. End-to-end tier: every platform build completes a turn against a mock endpoint through the default SDK path, a custom config, and the direct binary protocol, with final text and JSONL checked; its platform wheel is then installed in a clean venv and run without `runtime_bin`. The JSON-RPC protocol is not part of the ACP snapshot system, so there is no snapshot tier (an explicitly named gap, not an oversight).
Manual-driving caveat: the bin treats stdin EOF as "the client is gone" and disposes immediately, so a short-lived pipe aborts an in-flight turn — pipe-driven runs must keep stdin open until the turn ends.
@@ -40,9 +40,9 @@ deploy root 是 [`python/sdk-runtime/package.json`](../../../../python/sdk-runti
### 构建管线与产物
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts)runtime 闭包校验 → `pnpm run build` →(清空后)`pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **直落** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/`→ 注入 pkg 配置(`bin` 指闭包内 `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js``assets` 全量 glob——动态 import 对 pkg 静态分析不可见,必须显式全量打入)→ 每 target 一次 `pkg --sea`产物 `dsh-jsonrpc-agent-pkg-<platform>-<arch>``dist-exe/`CI artifact并拷回 runtime 目录。deploy 四 flag 均有实测依据:`--legacy` 是未开 inject-workspace-packages 时的必选路径;hoisted 产出零符号链接文件树(pkg VFS 最稳、物理保证 cordis 单实例);关 peer 自动安装避免未发布包名触发 registry 解析;link-workspace-packages 让闭包指向 workspace/vendor 源。
[`scripts/build-exe-for-python-sdk.ts`](../../../../scripts/build-exe-for-python-sdk.ts)runtime 闭包校验 → `pnpm run build` →(清空后)`pnpm --filter dsh-jsonrpc-agent-pkg deploy --legacy --prod --config.node-linker=hoisted --config.auto-install-peers=false --config.link-workspace-packages=true` **直落** `python/sdk-runtime/src/deepseek_harness_runtime/runtime/node/`→ 注入 pkg 配置(`bin` 指闭包内 `node_modules/@deepseek-ai/dsh-jsonrpc-agent/lib/bin.js``assets` 全量 glob——动态 import 对 pkg 静态分析不可见,必须显式全量打入)→ 每 target 一次 `pkg --sea`可执行文件 `dsh-jsonrpc-agent-pkg-<platform>-<arch>``dist-exe/` 并拷回 runtime 目录。CI 把它们作为测试中间输入,只保留对应的平台 wheel。deploy 四 flag 均有实测依据:`--legacy` 是未开 inject-workspace-packages 时的必选路径;hoisted 产出零符号链接文件树(pkg VFS 最稳、物理保证 cordis 单实例);关 peer 自动安装避免未发布包名触发 registry 解析;link-workspace-packages 让闭包指向 workspace/vendor 源。
CI[`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml),仅显式触发——`workflow_dispatch` 手动派发,或给 PR 打 `build-exe` 标签;linux-x64 / linux-arm64`ubuntu-24.04-arm`/ macos-arm64 三平台原生构建,`~/.pkg-cache` 缓存,artifact 按平台上传macOS ad-hoc 签名由 pkg 处理。每个平台都以 mock SSE 模型分别通过默认配置和自定义 `cordis.yml` 驱动 SDK,再以 NDJSON JSON-RPC 直接驱动 exe,校验 JSONL 与最终响应,最后把 release 形态的 wheel 安装到干净 venv 中并在不传 `runtime_bin` 的情况下运行;Linux 还检查 GLIBC 依赖并在 manylinux 2.28 容器中运行。[`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) 只接受 `python-vX.Y.Z` tag 流水线,构建一个 SDK wheel 与 3 个原生 runtime wheel,再由单个串行 job 校验并发布这 4 个文件到项目 PyPI 注册表。Windows 是非目标。
CI[`.github/workflows/build-exe-for-python-sdk.yml`](../../../../.github/workflows/build-exe-for-python-sdk.yml),仅显式触发——`workflow_dispatch` 手动派发,或给 PR 打 `build-exe` 标签;linux-x64 / linux-arm64`ubuntu-24.04-arm`/ macos-arm64 三平台原生构建,并缓存 `~/.pkg-cache`macOS ad-hoc 签名由 pkg 处理。每个平台都以 mock SSE 模型分别通过默认配置和自定义 `cordis.yml` 驱动 SDK,再以 NDJSON JSON-RPC 直接驱动 exe,校验 JSONL 与最终响应,最后把 release 形态的 wheel 安装到干净 venv 中并在不传 `runtime_bin` 的情况下运行;Linux 还检查 GLIBC 依赖并在 manylinux 2.28 容器中运行。整次运行只保留 4 个产物,每个只含一个发布文件:平台无关的 SDK wheel 与 3 个原生 runtime wheel;裸 exe 和源码 bundle 只作为测试中间输入。[`.gitlab-ci.yml`](../../../../.gitlab-ci.yml) 只接受 `python-vX.Y.Z` tag 流水线,构建一个 SDK wheel 与 3 个原生 runtime wheel,再由单个串行 job 校验并发布这 4 个文件到项目 PyPI 注册表。Windows 是非目标。
### Python SDK 分发:双载体,exe 为生产、node 为开发
@@ -62,7 +62,7 @@ exe「必须显式配置」的硬语义不变;零配置体验由 wrapper 恢
## 测试
验证面分三层。机制层:`--sea` 链路的实测结论内嵌在「决策」各节(VFS 内 ESM 动态 import、cordis 单实例、fail-loud 配置链路、`node:sqlite`、macOS ad-hoc 签名可运行)。SDK 层:完整的 keyless pytest 套件以假运行时对端覆盖客户端协议、子进程清理、绝对 cwd 传递、双载体启动与载体解析;根 CI 在 Python 3.10 上运行全部用例。端到端层:每个平台产物都通过默认 SDK 路径、自定义配置和直接二进制协议对着 mock 端点完成一个轮次,并校验最终文本与 JSONL;随后把平台 wheel 安装进干净 venv,在不传 `runtime_bin` 的情况下运行。JSON-RPC 协议不在 ACP snapshot 体系内,无 snapshot 层(点名后的明确空缺,非遗漏)。
验证面分三层。机制层:`--sea` 链路的实测结论内嵌在「决策」各节(VFS 内 ESM 动态 import、cordis 单实例、fail-loud 配置链路、`node:sqlite`、macOS ad-hoc 签名可运行)。SDK 层:完整的 keyless pytest 套件以假运行时对端覆盖客户端协议、子进程清理、绝对 cwd 传递、双载体启动与载体解析;根 CI 在 Python 3.10 上运行全部用例。端到端层:每个平台构建都通过默认 SDK 路径、自定义配置和直接二进制协议对着 mock 端点完成一个轮次,并校验最终文本与 JSONL;随后把平台 wheel 安装进干净 venv,在不传 `runtime_bin` 的情况下运行。JSON-RPC 协议不在 ACP snapshot 体系内,无 snapshot 层(点名后的明确空缺,非遗漏)。
手工驱动注意:bin 视 stdin EOF 为「客户端已走」并立即 dispose,短命管道会中止在飞回合——管道驱动必须保持 stdin 打开到回合结束。
+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
README.md: a55b3b90bcb2329f58f063edc7edc733bad030d1
README.zh.md: f99cf2302d9dbad36fff1616ae33b40b8bb02f4e
README.md: 2e2e3bff7e6903a1183cc445f590ecb327b92e65
README.zh.md: f14dad4688ed3c54f46ae28475779b0a8d163ae0
+1 -1
View File
@@ -22,7 +22,7 @@ pnpm exec tsx scripts/build-exe-for-python-sdk.ts --skip-build # lib/ artifac
pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets=node24-linux-x64,node24-linux-arm64,node24-macos-arm64
```
Products land in `dist-exe/` (CI artifact shape) and are synced into this package at `sdk-runtime/src/deepseek_harness_runtime/runtime/dsh-jsonrpc-agent-pkg-<platform>-<arch>` (platform: `linux`/`macos`; arch: `x64`/`arm64`) — after a build the SDK finds the executable with no further setup. Alternatively, download the platform artifact from the `build-exe-for-python-sdk` CI workflow (manual dispatch, or the `build-exe` PR label) and place it at that same path. Which plugins the exe bundles and how the carriers are organized: [sdk-runtime README](sdk-runtime/README.md); the build also refreshes the dev-only node carrier (see "against the Node source" below).
Products land in `dist-exe/` and are synced into this package at `sdk-runtime/src/deepseek_harness_runtime/runtime/dsh-jsonrpc-agent-pkg-<platform>-<arch>` (platform: `linux`/`macos`; arch: `x64`/`arm64`) — after a local build the SDK finds the executable with no further setup. The `build-exe-for-python-sdk` CI workflow (manual dispatch, or the `build-exe` PR label) exercises the same binaries but retains only the four release wheels. Which plugins the exe bundles and how the carriers are organized: [sdk-runtime README](sdk-runtime/README.md); the build also refreshes the dev-only node carrier (see "against the Node source" below).
## Validating the SDK against the executable
+1 -1
View File
@@ -22,7 +22,7 @@ pnpm exec tsx scripts/build-exe-for-python-sdk.ts --skip-build # lib/ artifac
pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets=node24-linux-x64,node24-linux-arm64,node24-macos-arm64
```
产物落入 `dist-exe/`CI 产物形态),并同步进本包的 `sdk-runtime/src/deepseek_harness_runtime/runtime/dsh-jsonrpc-agent-pkg-<platform>-<arch>`platform`linux`/`macos`arch`x64`/`arm64`),构建完成后 SDK 不需要额外设置就能找到可执行文件。也可以从 `build-exe-for-python-sdk` CI workflow(手动触发,或给 PR 打 `build-exe` 标签)下载对应平台的产物放到同一路径。exe 内置哪些插件、载体如何组织,见 [sdk-runtime README](sdk-runtime/README.md);构建还会顺带刷新仅供开发用的 node 载体(见下文「对着 Node 源码运行」)。
产物落入 `dist-exe/`,并同步进本包的 `sdk-runtime/src/deepseek_harness_runtime/runtime/dsh-jsonrpc-agent-pkg-<platform>-<arch>`platform`linux`/`macos`arch`x64`/`arm64`),本地构建完成后 SDK 不需要额外设置就能找到可执行文件。`build-exe-for-python-sdk` CI 工作流(手动触发,或给 PR 打 `build-exe` 标签)会测试同样的二进制,但只保留 4 个发布 wheel。exe 内置哪些插件、载体如何组织,见 [sdk-runtime README](sdk-runtime/README.md);构建还会顺带刷新仅供开发用的 node 载体(见下文「对着 Node 源码运行」)。
## 用可执行文件验证 SDK
+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
README.md: ee7c8d5254bd1b1c1e9ba06c8c9ba0c6e8dfcacc
README.zh.md: d3c44bf34c686e1aee7157b8b5d4d5b4d14bb053
README.md: 1a63f76f62b95cb36f53e3f8ff42898b26122d05
README.zh.md: b214ed5e6d25a013def5429b92a14b7393f1e028
+1 -1
View File
@@ -13,7 +13,7 @@ Two carriers coexist under `src/deepseek_harness_runtime/runtime/`, both injecte
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.
Missing carriers raise `FileNotFoundError` naming the acquisition routes: build via `scripts/build-exe-for-python-sdk.ts` in a deepseek-harness checkout, or download the platform artifact of the `build-exe-for-python-sdk` CI workflow (a tar.gz — tar preserves the executable bit) and unpack it into the runtime directory. Acquisition strategy is deliberately separate from the lookup interface, so an on-demand download can replace it later without touching callers.
Missing carriers raise `FileNotFoundError` naming the 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. 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 executable. The fixed tags are `py3-none-manylinux_2_28_x86_64`, `py3-none-manylinux_2_28_aarch64`, and `py3-none-macosx_11_0_arm64`; the build hook rejects `py3-none-any`, absent or multiple executables, and unsupported platform tags. Stable `python-vX.Y.Z` releases use the same `X.Y.Z` for this package and the SDK.
+1 -1
View File
@@ -13,7 +13,7 @@ Python SDK 的运行时载体包(dist 名 `deepseek-harness-runtime-bin`,模
两种载体承载相同的内容,且只定义一次:本包根目录的 [package.json](package.json) 是 single-exe 流水线的 deploy root——一份零代码的纯依赖 manifest,其依赖闭包既是编译进 exe 的插件集,也是物化到 `runtime/node/` 的文件树。往分发物里加插件,就是在那里加一行依赖再重新构建。
载体缺失时抛出 `FileNotFoundError` 并写明获取途径:在 deepseek-harness 检出中经 `scripts/build-exe-for-python-sdk.ts` 构建,或下载 `build-exe-for-python-sdk` CI 工作流的对应平台产物(tar.gz——tar 保留可执行位)并解包到 runtime 目录。获取策略与查找接口刻意分离,之后可以换成按需下载而不动任何调用方。
载体缺失时抛出 `FileNotFoundError` 并写明获取途径:在 deepseek-harness 检出中经 `scripts/build-exe-for-python-sdk.ts` 构建,或安装 `build-exe-for-python-sdk` CI 工作流生成的对应平台 runtime wheel。该工作流只保留 wheel,不保留独立 exe 归档。获取策略与查找接口刻意分离,之后可以换成按需下载而不动任何调用方。
每个 wheel 只包含一个可执行文件。固定 tag 为 `py3-none-manylinux_2_28_x86_64``py3-none-manylinux_2_28_aarch64``py3-none-macosx_11_0_arm64`;构建钩子会拒绝 `py3-none-any`、可执行文件缺失或重复以及不支持的平台 tag。稳定的 `python-vX.Y.Z` 发布为本包和 SDK 使用同一个 `X.Y.Z`
@@ -35,9 +35,8 @@ _ARCH_TAGS = {"x86_64": "x64", "amd64": "x64", "arm64": "arm64", "aarch64": "arm
_EXE_ACQUISITION_HINT = (
"Two ways to get the executable: run `scripts/build-exe-for-python-sdk.ts` (via tsx) in a "
"deepseek-harness checkout, or download the platform artifact of the `build-exe-for-python-sdk` "
"CI workflow (a tar.gz — tar preserves the executable bit) and unpack it into this package's "
"runtime/ directory. For local development "
"deepseek-harness checkout, or install the matching `deepseek-harness-runtime-bin` platform "
"wheel retained by the `build-exe-for-python-sdk` CI workflow. For local development "
"against a repo source build, explicitly select the dev-only node carrier with "
f"{RUNTIME_MODE_ENV_VAR}=node (or resolve_bundled_launch_args('node'))."
)