mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
Merge remote-tracking branch 'origin/master' into codex/localized-chinese-doc-links
# Conflicts: # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md # .agents/notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.i18n.yaml # .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml # .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md # .agents/notes/implemented/bug-fix/2026-07-29-pnpm-setup-runner-isolation.i18n.yaml # .agents/notes/implemented/bug-fix/2026-07-29-pnpm-setup-runner-isolation.zh.md # .agents/notes/implemented/bug-fix/2026-08-18-request-image-payload-bound.i18n.yaml # .agents/notes/implemented/bug-fix/2026-08-18-request-image-payload-bound.zh.md # .agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml # .agents/notes/implemented/feature/2026-07-06-sandbox.zh.md # .agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml # .agents/notes/implemented/feature/2026-07-21-cross-session-references.i18n.yaml # .agents/notes/implemented/feature/2026-07-21-cross-session-references.zh.md # .agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.i18n.yaml # .agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.zh.md # .agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml # .agents/notes/implemented/feature/2026-07-31-permission-default-for-new-sessions.i18n.yaml # .agents/notes/implemented/feature/2026-08-03-web-search-source-scroll.i18n.yaml # .agents/notes/implemented/feature/2026-08-03-web-search-source-scroll.zh.md # .agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml # .agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md # .agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml # .agents/notes/implemented/feature/2026-08-05-agent-teams.zh.md # .agents/notes/implemented/feature/2026-08-11-workspace-sidebar-order-and-folding.i18n.yaml # .agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml # .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml # .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.zh.md # .agents/notes/implemented/process/2026-07-22-evidence-based-larger-hosted-runners.i18n.yaml # .agents/notes/implemented/process/2026-07-22-evidence-based-larger-hosted-runners.zh.md # .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.i18n.yaml # .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.zh.md # .agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml # .agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.zh.md # .agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml # .agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.zh.md # .agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml # README.i18n.yaml # README.zh.md # docs/architecture.i18n.yaml # docs/architecture.zh.md # docs/development.i18n.yaml # docs/development.zh.md # docs/persistence-catalog.i18n.yaml # docs/persistence-catalog.zh.md # docs/subsystems/README.i18n.yaml # docs/subsystems/README.zh.md # docs/subsystems/agent-team.i18n.yaml # docs/subsystems/agent-team.zh.md # docs/subsystems/client-modules.i18n.yaml # docs/subsystems/client-modules.zh.md # docs/subsystems/commands.i18n.yaml # docs/subsystems/commands.zh.md # docs/subsystems/persistence.i18n.yaml # docs/subsystems/persistence.zh.md # docs/subsystems/session-reference.i18n.yaml # docs/tool-catalog.i18n.yaml # docs/tool-catalog.zh.md # docs/user/guide/providers.i18n.yaml # docs/user/guide/providers.zh.md # packages/README.i18n.yaml # packages/README.zh.md # packages/bundle/web-app/README.i18n.yaml # packages/bundle/web-app/README.zh.md # packages/client/README.i18n.yaml # packages/client/README.zh.md # packages/client/connection/README.i18n.yaml # packages/client/connection/README.zh.md # packages/client/ui-conversation/README.i18n.yaml # packages/client/ui-conversation/README.zh.md # packages/client/ui-primitives/README.i18n.yaml # packages/client/ui-primitives/README.zh.md # packages/client/ui-sidebar/README.i18n.yaml # packages/client/ui-sidebar/README.zh.md # packages/client/ui-workspace/README.i18n.yaml # packages/client/ui-workspace/README.zh.md # packages/context/README.i18n.yaml # packages/context/README.zh.md # packages/core/agent-loop/README.i18n.yaml # packages/credentials/README.i18n.yaml # packages/credentials/README.zh.md # packages/experimental/agent-team/README.i18n.yaml # packages/experimental/agent-team/README.zh.md # packages/experimental/tool-agent-team/README.i18n.yaml # packages/experimental/tool-agent-team/README.zh.md # packages/host/frontend-static/README.i18n.yaml # packages/host/frontend-static/README.zh.md # packages/host/webserver/README.i18n.yaml # packages/host/webserver/README.zh.md # packages/interaction/commands/README.i18n.yaml # packages/interaction/commands/README.zh.md # packages/plan/plan-mode/README.i18n.yaml # packages/plan/plan-mode/README.zh.md # packages/sandbox/sandbox-local/README.i18n.yaml # packages/sandbox/sandbox-local/README.zh.md # packages/session/README.i18n.yaml # packages/session/README.zh.md # packages/session/session-persistence-sqlite/README.i18n.yaml # packages/session/session-persistence-sqlite/README.zh.md # packages/session/session-projection-cache/README.i18n.yaml # packages/session/session-projection-cache/README.zh.md # packages/shell/tool-pwsh/README.i18n.yaml # packages/shell/tool-pwsh/README.zh.md # packages/subagent/subagent-codex/README.i18n.yaml # packages/subagent/subagent-codex/README.zh.md # packages/subagent/subagent/README.i18n.yaml # packages/subagent/subagent/README.zh.md # packages/web/tool-web/README.i18n.yaml # packages/web/tool-web/README.zh.md # scripts/snapshots/translation-prompt-v4/request-response.expected.json
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/development.md
|
||||
development.md: fe62a109f2643afe0b9be1ed51b86be0b9fa731f
|
||||
development.zh.md: ae136c7ded80d9bd1f61128319dc6cccf4c71a85
|
||||
development.md: 617d030294dafa51aea513adb811bb5f377431c9
|
||||
development.zh.md: be2a6196aed13a4f748e1b178f34603bbd08e5ac
|
||||
|
||||
+10
-2
@@ -61,10 +61,18 @@ The root `package.json` version is authoritative for both Python distributions.
|
||||
Build the pure SDK wheel once and one runtime wheel on each native platform:
|
||||
|
||||
```sh
|
||||
version="$(node -p "require('./package.json').version")"
|
||||
version="$(python - <<'PY'
|
||||
import runpy
|
||||
|
||||
release = runpy.run_path("scripts/build-python-release.py")
|
||||
print(release["pep440_version"](release["repository_version"]()))
|
||||
PY
|
||||
)"
|
||||
python scripts/build-python-release.py --package sdk --output-dir dist-python
|
||||
python scripts/build-python-release.py --package runtime --platform macos-arm64 --runtime-exe dist-exe/dsh-jsonrpc-agent-pkg-macos-arm64 --output-dir dist-python
|
||||
pip install --find-links dist-python deepseek-harness-sdk=="$version"
|
||||
pip install \
|
||||
"dist-python/deepseek_harness_sdk-$version-py3-none-any.whl" \
|
||||
"dist-python/deepseek_harness_runtime_bin-$version-py3-none-macosx_14_0_arm64.whl"
|
||||
```
|
||||
|
||||
The runtime distribution is wheel-only. The release pipeline publishes three platform wheels with the pure SDK wheel: Linux x64, Linux arm64, and macOS 14 or newer on arm64. A `python-v<repository-version>` tag is accepted only when it matches the repository version; prerelease repository versions such as `0.0.1-rc.1` use their normalized PEP 440 spelling, such as `0.0.1rc1`, inside wheel filenames and metadata.
|
||||
|
||||
@@ -61,10 +61,18 @@ with DeepSeekHarness() as harness:
|
||||
纯 SDK wheel 包只需构建一次;每个原生平台分别构建一个运行时 wheel 包:
|
||||
|
||||
```sh
|
||||
version="$(node -p "require('./package.json').version")"
|
||||
version="$(python - <<'PY'
|
||||
import runpy
|
||||
|
||||
release = runpy.run_path("scripts/build-python-release.py")
|
||||
print(release["pep440_version"](release["repository_version"]()))
|
||||
PY
|
||||
)"
|
||||
python scripts/build-python-release.py --package sdk --output-dir dist-python
|
||||
python scripts/build-python-release.py --package runtime --platform macos-arm64 --runtime-exe dist-exe/dsh-jsonrpc-agent-pkg-macos-arm64 --output-dir dist-python
|
||||
pip install --find-links dist-python deepseek-harness-sdk=="$version"
|
||||
pip install \
|
||||
"dist-python/deepseek_harness_sdk-$version-py3-none-any.whl" \
|
||||
"dist-python/deepseek_harness_runtime_bin-$version-py3-none-macosx_14_0_arm64.whl"
|
||||
```
|
||||
|
||||
运行时分发包仅提供 wheel 包。发布流水线会连同纯 SDK wheel 包一起发布三个平台 wheel 包:Linux x64、Linux arm64 和 macOS 14 或更高版本的 arm64。只有与仓库版本匹配时,才接受 `python-v<repository-version>` 标签;`0.0.1-rc.1` 之类的仓库预发布版本在 wheel 包文件名和元数据中使用规范化的 PEP 440 写法,例如 `0.0.1rc1`。
|
||||
|
||||
@@ -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: 592ce091f3b6c4bc151dfdee9d313b7c970c95de
|
||||
README.zh.md: 0a29281a39c885bc3c40e017bdc9475e0065605f
|
||||
README.md: 597d69a803a7cd1204fd48456f8e1ba18d9786e5
|
||||
README.zh.md: 30dc6b2a34709ac76d16133be34f3d0c87f93b8a
|
||||
|
||||
@@ -8,19 +8,21 @@ 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>` (platform: `linux`/`macos`; arch: `x64`/`arm64`). macOS builds also ship the native `-spawn-helper` sibling that `node-pty` uses there. 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`) with a target-native ripgrep `-rg` sidecar. macOS builds also ship the native `-spawn-helper` sibling that `node-pty` uses there. 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-sdk-jsonrpc-demo/lib/packaged-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](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk-runtime/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.
|
||||
|
||||
The bundled plugin set includes `@deepseek-ai/dsh-mcp-client`, so an external Cordis config can connect to stdio or Streamable HTTP MCP servers and expose their tools to the model. The wheel does not bundle MCP server programs or credentials: a stdio config supplies its executable and arguments, while a Streamable HTTP config supplies its URL and headers. The bridge supports MCP tools; MCP Resources and Prompts remain unsupported.
|
||||
|
||||
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. 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.
|
||||
Each wheel contains exactly one runtime executable and its matching ripgrep `-rg` sidecar. The macOS wheel also contains its matching native spawn helper; any missing sidecar makes that installation incomplete and is a hard startup error, even for a selected Cordis composition that does not use filesystem-search or 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 executables, missing or extra sidecars, 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
|
||||
|
||||
- `resolve_bundled_launch_args(mode=None) -> tuple[str, ...]` — the argv tuple that launches the bundled runtime: `(exe_path,)` in exe mode, `(node_path, bin_js_path)` in node mode. Mode selection: explicit argument > `DSH_RUNTIME_MODE` env var (`exe` | `node`) > automatic. Automatic resolution finds the production exe ONLY — the dev-only node carrier must be opted into explicitly so a production deployment can never silently ride on a source build.
|
||||
- `bundled_runtime_path() -> Path` — the platform exe path (exe carrier only; on macOS it validates that the required sibling `-spawn-helper` is also installed). The node carrier has no single-path equivalent and launches via the argv tuple above.
|
||||
- `bundled_runtime_path() -> Path` — the platform exe path (exe carrier only); it validates the required sibling `-rg` sidecar on every platform and the `-spawn-helper` sidecar on macOS. The node carrier has no single-path equivalent and launches via the argv tuple above.
|
||||
- `bundled_default_config_path() -> Path` — the checked-in default config (see below).
|
||||
- `bundled_package_dir() -> Path` — the installed package data root.
|
||||
|
||||
|
||||
@@ -8,19 +8,21 @@ 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>`(platform:`linux`/`macos`;arch:`x64`/`arm64`)。macOS 构建还会随附 `node-pty` 在该平台使用的原生 `-spawn-helper` 伴随文件。目标机器无需安装 Node。这是唯一随 wheel 包分发的载体;本包不发布 sdist。
|
||||
- **exe(生产)**——单文件 Node 可执行程序 `dsh-jsonrpc-agent-pkg-<platform>-<arch>`(platform:`linux`/`macos`;arch:`x64`/`arm64`),以及匹配目标平台的 ripgrep `-rg` 伴随文件。macOS 构建还会随附 `node-pty` 在该平台使用的原生 `-spawn-helper` 伴随文件。目标机器无需安装 Node。这是唯一随 wheel 包分发的载体;本包不发布 sdist。
|
||||
- **node(仅限开发)**——`runtime/node/` 下的完整部署闭包(`package.json` + `node_modules/`),在系统 Node >= 22.19 上以 `node runtime/node/node_modules/@deepseek-ai/dsh-sdk-jsonrpc-demo/lib/packaged-bin.js` 执行。它是当前检出的源码构建,仅用于仓库本地的开发与验证;不会被自动选中,也不进入分发物。
|
||||
|
||||
两种载体承载相同的内容,且只定义一次:本包根目录的 [package.json](https://github.com/deepseek-ai/deepseek-harness/blob/master/python/sdk-runtime/package.json) 是 single-exe 流水线的部署根目录——一份零代码的纯依赖 manifest,其依赖闭包既是编译进 exe 的插件集,也是物化到 `runtime/node/` 的文件树。往分发物里加插件,就是在那里加一行依赖再重新构建。
|
||||
|
||||
内置插件集合包含 `@deepseek-ai/dsh-mcp-client`,因此外部 Cordis 配置可以连接 stdio 或 Streamable HTTP MCP server,并向模型提供这些 server 的工具。wheel 包不包含 MCP server 程序或凭据:stdio 配置需要提供可执行程序及其参数,Streamable HTTP 配置需要提供 URL 和请求头。该桥接仅支持 MCP 工具,尚不支持 MCP Resources 与 Prompts。
|
||||
|
||||
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 部署目标。本包的 `platforms.json` 统一定义仓库发行构建器与隔离构建钩子使用的固定标签和可执行文件名。构建钩子会拒绝 `py3-none-any`、不存在运行时文件、存在多个运行时文件、文件不可执行以及不支持的平台标签。仓库根目录的 `package.json` 为本包和 SDK 提供共同版本,`python-v<repository-version>` 发布标签必须与其匹配。
|
||||
每个 wheel 包只包含一个运行时可执行文件及其匹配的 ripgrep `-rg` 伴随文件。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
|
||||
|
||||
- `resolve_bundled_launch_args(mode=None) -> tuple[str, ...]`——启动内置运行时的 argv 元组:exe 模式下为 `(exe_path,)`,node 模式下为 `(node_path, bin_js_path)`。模式选择:显式参数 > `DSH_RUNTIME_MODE` 环境变量(`exe` | `node`)> 自动。自动解析只找生产 exe——仅限开发的 node 载体必须显式选用,从而生产部署绝不会悄悄跑在源码构建上。
|
||||
- `bundled_runtime_path() -> Path`——平台 exe 路径(仅 exe 载体,并会在 macOS 上校验必要的 `-spawn-helper` 伴随文件也已安装)。node 载体没有单一路径的等价物,经由上面的 argv 元组启动。
|
||||
- `bundled_runtime_path() -> Path`——平台 exe 路径(仅 exe 载体);它会在所有平台校验必要的 `-rg` 伴随文件,并在 macOS 上额外校验 `-spawn-helper` 伴随文件。node 载体没有单一路径的等价物,经由上面的 argv 元组启动。
|
||||
- `bundled_default_config_path() -> Path`——检入的默认配置(见下文)。
|
||||
- `bundled_package_dir() -> Path`——已安装包的数据根目录。
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ class RuntimeBuildHook(BuildHookInterface):
|
||||
expected_executable = matches[0][1]
|
||||
runtime_dir = Path(self.root) / "src" / "deepseek_harness_runtime" / "runtime"
|
||||
runtime_files = sorted(runtime_dir.glob("dsh-jsonrpc-agent-pkg-*") if runtime_dir.is_dir() else [])
|
||||
expected_files = [expected_executable]
|
||||
expected_files = [expected_executable, f"{expected_executable}-rg"]
|
||||
if "-macos-" in expected_executable:
|
||||
expected_files.append(f"{expected_executable}-spawn-helper")
|
||||
found_files = [path.name for path in runtime_files]
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"@deepseek-ai/dsh-agent": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-loop": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
|
||||
"@deepseek-ai/dsh-agent-tool-presentation": "workspace:^",
|
||||
"@deepseek-ai/dsh-app-boot": "workspace:^",
|
||||
"@deepseek-ai/dsh-attachment": "workspace:^",
|
||||
"@deepseek-ai/dsh-shell": "workspace:^",
|
||||
@@ -22,12 +23,14 @@
|
||||
"@deepseek-ai/dsh-brand": "workspace:^",
|
||||
"@deepseek-ai/dsh-code-runtime": "workspace:^",
|
||||
"@deepseek-ai/dsh-code-runtime-worker-thread": "workspace:^",
|
||||
"@deepseek-ai/dsh-command-compact": "workspace:^",
|
||||
"@deepseek-ai/dsh-command-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-commands": "workspace:^",
|
||||
"@deepseek-ai/dsh-compaction": "workspace:^",
|
||||
"@deepseek-ai/dsh-compaction-basic": "workspace:^",
|
||||
"@deepseek-ai/dsh-compaction-tool-result-pruner": "workspace:^",
|
||||
"@deepseek-ai/dsh-cordis-host-runner": "workspace:^",
|
||||
"@deepseek-ai/dsh-authorization": "workspace:^",
|
||||
"@deepseek-ai/dsh-credentials": "workspace:^",
|
||||
"@deepseek-ai/dsh-launch-environment": "workspace:^",
|
||||
"@deepseek-ai/dsh-fs": "workspace:^",
|
||||
@@ -46,9 +49,12 @@
|
||||
"@deepseek-ai/dsh-llm-deepseek": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm-pi-ai": "workspace:^",
|
||||
"@deepseek-ai/dsh-llm-retry": "workspace:^",
|
||||
"@deepseek-ai/dsh-mcp-client": "workspace:^",
|
||||
"@deepseek-ai/dsh-home-paths": "workspace:^",
|
||||
"@deepseek-ai/dsh-permission-presets": "workspace:^",
|
||||
"@deepseek-ai/dsh-plan-mode": "workspace:^",
|
||||
"@deepseek-ai/dsh-persona": "workspace:^",
|
||||
"@deepseek-ai/dsh-pwsh-local": "workspace:^",
|
||||
"@deepseek-ai/dsh-terminal": "workspace:^",
|
||||
"@deepseek-ai/dsh-terminal-bash": "workspace:^",
|
||||
"@deepseek-ai/dsh-repeat-tool-reminder": "workspace:^",
|
||||
@@ -71,6 +77,7 @@
|
||||
"@deepseek-ai/dsh-settings": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-skill-filesystem": "workspace:^",
|
||||
"@deepseek-ai/dsh-spill": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent-acp": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent-fork-in-process": "workspace:^",
|
||||
@@ -89,7 +96,9 @@
|
||||
"@deepseek-ai/dsh-tool-bash-persistent": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-cordis": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-fs": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-fs-search": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-goal": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-ralph": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-skill": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-str-replace-editor": "workspace:^",
|
||||
"@deepseek-ai/dsh-tool-subagent": "workspace:^",
|
||||
|
||||
@@ -5,8 +5,8 @@ Two runtime carriers coexist under ``runtime/``, both injected by the repo's
|
||||
|
||||
- **exe (production)**: single-file Node executables named
|
||||
``dsh-jsonrpc-agent-pkg-<platform>-<arch>`` (platform in {linux, macos}, arch in
|
||||
{x64, arm64}); macOS also uses a sibling ``-spawn-helper``. The target machine
|
||||
needs no Node installation.
|
||||
{x64, arm64}) with a sibling ``-rg`` executable; macOS also uses a sibling
|
||||
``-spawn-helper``. The target machine needs no Node installation.
|
||||
- **node (dev-only)**: the full deploy closure under ``runtime/node/``
|
||||
(``package.json`` + ``node_modules/``), executed as ``node
|
||||
runtime/node/node_modules/@deepseek-ai/dsh-sdk-jsonrpc-demo/lib/packaged-bin.js`` on a
|
||||
@@ -71,10 +71,11 @@ def bundled_runtime_path() -> Path:
|
||||
"""Absolute path of the bundled single-file runtime executable for the current platform.
|
||||
|
||||
Raises FileNotFoundError when the platform is unsupported, the executable
|
||||
has not been placed into this package, or the required macOS spawn helper is
|
||||
missing; the message names the acquisition routes (acquisition strategy is
|
||||
deliberately separate from this lookup interface, so an on-demand download
|
||||
can replace it without touching callers).
|
||||
has not been placed into this package, the required ripgrep sidecar is
|
||||
missing, or the required macOS spawn helper is missing; the message names
|
||||
the acquisition routes (acquisition strategy is deliberately separate from
|
||||
this lookup interface, so an on-demand download can replace it without
|
||||
touching callers).
|
||||
"""
|
||||
tag = _current_platform_tag()
|
||||
path = bundled_package_dir() / "runtime" / f"dsh-jsonrpc-agent-pkg-{tag}"
|
||||
@@ -83,6 +84,12 @@ def bundled_runtime_path() -> Path:
|
||||
f"deepseek-harness-runtime-bin is missing the runtime executable at {path}. "
|
||||
+ _EXE_ACQUISITION_HINT
|
||||
)
|
||||
ripgrep = Path(f"{path}-rg")
|
||||
if not ripgrep.is_file():
|
||||
raise FileNotFoundError(
|
||||
f"deepseek-harness-runtime-bin is missing the ripgrep sidecar at {ripgrep}. "
|
||||
+ _EXE_ACQUISITION_HINT
|
||||
)
|
||||
if tag.startswith("macos-"):
|
||||
helper = Path(f"{path}-spawn-helper")
|
||||
if not helper.is_file():
|
||||
|
||||
@@ -92,6 +92,10 @@ def test_stage_runtime_copies_platform_payload(
|
||||
executable.write_bytes(b"runtime")
|
||||
executable.chmod(0o755)
|
||||
expected = {executable.name: b"runtime"}
|
||||
ripgrep = Path(f"{executable}-rg")
|
||||
ripgrep.write_bytes(b"ripgrep")
|
||||
ripgrep.chmod(0o755)
|
||||
expected[ripgrep.name] = b"ripgrep"
|
||||
if with_helper:
|
||||
spawn_helper = Path(f"{executable}-spawn-helper")
|
||||
spawn_helper.write_bytes(b"helper")
|
||||
|
||||
@@ -51,7 +51,10 @@ def test_runtime_requires_spawn_helper_only_on_macos(
|
||||
runtime_dir.mkdir()
|
||||
linux = runtime_dir / "dsh-jsonrpc-agent-pkg-linux-x64"
|
||||
linux.touch()
|
||||
(runtime_dir / "dsh-jsonrpc-agent-pkg-macos-arm64").touch()
|
||||
Path(f"{linux}-rg").touch()
|
||||
macos = runtime_dir / "dsh-jsonrpc-agent-pkg-macos-arm64"
|
||||
macos.touch()
|
||||
Path(f"{macos}-rg").touch()
|
||||
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
||||
|
||||
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "macos-arm64")
|
||||
@@ -59,3 +62,16 @@ def test_runtime_requires_spawn_helper_only_on_macos(
|
||||
runtime.bundled_runtime_path()
|
||||
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "linux-x64")
|
||||
assert runtime.bundled_runtime_path() == linux
|
||||
|
||||
|
||||
def test_runtime_requires_ripgrep_sidecar(
|
||||
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
runtime_dir = tmp_path / "runtime"
|
||||
runtime_dir.mkdir()
|
||||
(runtime_dir / "dsh-jsonrpc-agent-pkg-linux-x64").touch()
|
||||
monkeypatch.setattr(runtime, "bundled_package_dir", lambda: tmp_path)
|
||||
monkeypatch.setattr(runtime, "_current_platform_tag", lambda: "linux-x64")
|
||||
|
||||
with pytest.raises(FileNotFoundError, match="ripgrep sidecar"):
|
||||
runtime.bundled_runtime_path()
|
||||
|
||||
@@ -30,3 +30,44 @@ def test_child_prompt_precedes_runtime_context(prompt_name: str, expected: str)
|
||||
for chunk in chunks
|
||||
for choice in chunk.get("choices", [])
|
||||
)
|
||||
|
||||
|
||||
def test_mcp_smoke_requests_the_discovered_tool() -> None:
|
||||
chunks = SMOKE["completion_chunks"]({
|
||||
"messages": [{"role": "user", "content": SMOKE["MCP_PROMPT"]}],
|
||||
"tools": [{"type": "function", "function": {"name": "mcp__fixture__add"}}],
|
||||
})
|
||||
|
||||
calls = [
|
||||
call
|
||||
for chunk in chunks
|
||||
for choice in chunk.get("choices", [])
|
||||
for call in choice.get("delta", {}).get("tool_calls", [])
|
||||
]
|
||||
assert calls[0]["function"] == {
|
||||
"name": "mcp__fixture__add",
|
||||
"arguments": '{"a": 19, "b": 23}',
|
||||
}
|
||||
|
||||
|
||||
def test_mcp_smoke_accepts_the_external_server_result() -> None:
|
||||
chunks = SMOKE["completion_chunks"]({
|
||||
"messages": [
|
||||
{"role": "user", "content": SMOKE["MCP_PROMPT"]},
|
||||
{
|
||||
"role": "assistant",
|
||||
"tool_calls": [{
|
||||
"id": "mcp-add",
|
||||
"type": "function",
|
||||
"function": {"name": "mcp__fixture__add", "arguments": '{}'},
|
||||
}],
|
||||
},
|
||||
{"role": "tool", "tool_call_id": "mcp-add", "content": "42"},
|
||||
],
|
||||
})
|
||||
|
||||
assert any(
|
||||
choice.get("delta", {}).get("content") == SMOKE["MCP_TEXT"]
|
||||
for chunk in chunks
|
||||
for choice in chunk.get("choices", [])
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user