DSH / Atlas
2026-08-23implementedarchitecturearchived 2026-09-04

Python SDK runtime through the dsh profile launcher

通过 dsh profile 启动器运行 Python SDK 运行时

The Python SDK distributed a private Node application that booted a complete external `cordis.yml`, while every other supported application entered through `dsh` profiles. That exception duplicated environment loading, configuration ownership, plugin resolution, shutdown, artifact names, and test paths. It also made SDK customization an all-or-nothing application tree: a caller replacing one plugin had to own the JSO

English

Problem

The Python SDK distributed a private Node application that booted a complete external cordis.yml, while every other supported application entered through dsh profiles. That exception duplicated environment loading, configuration ownership, plugin resolution, shutdown, artifact names, and test paths. It also made SDK customization an all-or-nothing application tree: a caller replacing one plugin had to own the JSON-RPC server and every unrelated deployment row.

A normal profile cannot be adopted only at the Python wrapper. The runtime executable must contain the dsh CLI, shipped profile and bundle files, native libraries, and a module-resolution path that works when profile files and external plugins live outside pkg's virtual filesystem.

Decision

One application launcher

The runtime executable packages @deepseek-ai/dsh and runs its ordinary command grammar. The Python client selects --profile sdk by default, forwards ordered absolute --patch paths, and may select another dsh executable or profile. The runnable minimal example selects the shipped sdk-minimal profile. The private @deepseek-ai/dsh-sdk-python-runtime application package and checked-in runtime cordis.yml do not exist. JSON-RPC serving remains the @deepseek-ai/dsh-sdk-app bundle and @deepseek-ai/dsh-sdk-jsonrpc-server plugin, not a Python-owned boot path.

The public Python configuration is dsh_bin, profile, ordered patches, dsh_home, process cwd/environment, provider/model/token selection, a bounded initialization timeout, and optional turn/shutdown timeouts. It does not expose a complete Cordis tree or arbitrary launch argv. RunResult reports the protocol-owned run values and does not duplicate the profile's persistence path.

Every Python launch requires either explicit dsh_home or a non-empty DSH_HOME in the child environment. The SDK never discovers ~/.dsh. The selected home consistently owns profiles, external plugins, credentials, settings, and sessions.

Plugin customization

Persistent SDK customization uses the same profile interfaces as direct CLI use. dsh plugin --profile <name> ... manages external dependencies and bundle order, $DSH_HOME/profiles/<name>/cordis.patch.yml owns persistent row changes, the home patch applies machine-local changes across profiles, and Python patches supplies invocation-specific overlays. A selected profile is valid only when it retains an SDK server row. Missing profiles, bundles, server rows, and invalid patches fail without a complete-config fallback; a profile that remains alive without serving JSON-RPC fails the independently bounded initialization handshake with a diagnostic naming that profile.

The standalone sdk-minimal profile lists one repository-owned bundle that inserts its complete explicit tree without dsh-base. Its persistent Bash and string-replace editor are present by composition; the shared JSON-RPC server exposes no root-agent tool filter. Dynamic runtime context, workspace instructions, settings, managed credentials, telemetry, compaction, and every other base row are absent. The same runtime still packages the full sdk and web profiles as separate choices.

The runtime wheel installs a dsh console command. Ordinary profile and SDK execution remains Node-free; external package management requires a caller-installed pnpm.

Executable packaging

The zero-code deployment manifest is dsh-python-runtime-closure. It packages node_modules/@deepseek-ai/dsh/lib/bin.js and profile, bundle, preset, native-addon, and shared-library assets into deepseek-harness-sdk-runtime-<platform>-<arch>. The wheel distribution names, Python import modules, JSON-RPC messages, and wire-stable serverInfo.name = deepseek-harness-sdk-runtime remain unchanged.

Plain Node profiles use symlinks in $DSH_HOME/profiles/node_modules to share installation packages with external plugins. An operating-system symlink cannot traverse pkg's /snapshot filesystem, so the packaged CLI writes small real ESM proxy packages instead. Each proxy resolves the source package's explicit ESM export map directly under Node import conditions, exposes targets that exist in the installation, and re-exports their virtual module URLs. Export rows without an ESM runtime target and executable-only or declaration-only packages produce no unusable proxy entry; malformed export maps fail startup. A complete matching generation returns without acquiring the cross-process writer lock. A missing or stale entry acquires the lock, rechecks the generation, and repairs it without exposing partial proxies; either carrier can replace the other carrier's managed entry. Loader rows and external plugin peers therefore resolve through the normal profile parent walk while retaining one Cordis and one instance of each bundled module.

The published target set is Linux x64, Linux arm64, macOS arm64, macOS x64, and Windows x64. Installed-wheel black-box CI owns artifact provenance, default and patched profiles, external bundle installation, native tools, MCP, direct JSON-RPC, snapshots, and trusted real-provider turns on every target. The Windows x64 runtime decision owns the Windows artifact and its platform-specific shell surface.

Existing decisions and supersession

This decision implements and supersedes the Python exception and deferred-migration sections of the single dsh application launcher. It supersedes the private application, external complete-config, artifact-name, and customization facts in the single-file Python SDK runtime distribution, which remains authoritative for pkg/SEA, wheel construction, native target validation, and publication. The standalone sdk-minimal profile supersedes only this note's minimal-overlay realization. No active note is fully superseded, so none is archived.

Alternatives considered

Keep complete cordis.yml as an advanced escape hatch. Rejected because it preserves a second application assembly and lets a caller bypass profile environment, plugin, and shutdown ownership.

Silently use ~/.dsh for compatibility. Rejected because an SDK process must not inherit a person's plugins, credentials, settings, or sessions without an explicit choice.

Copy the virtual dependency tree into every home. Rejected because it duplicates hundreds of megabytes and loads a second Cordis instance. Export-preserving proxies are small and retain module identity.

Bundle pnpm and Node package management into every SDK launch. Rejected because installed plugins are deployment state, not per-turn runtime work. Only dsh plugin needs the external package manager.

Consequences

Python callers configure the same profile vocabulary as TypeScript and direct CLI users, and arbitrary external bundles can extend an SDK profile without introducing another launcher. Homes are selected explicitly, complete-config and session_root parameters are unavailable, and the executable includes shared-library assets plus profile-module proxies. The full sdk, standalone sdk-minimal, and web applications remain separate profiles inside the same packaged CLI. The installed-wheel CI makes those package, profile, native, and provider paths release requirements rather than source-only assumptions.

中文

问题

Python SDK 分发一个私有 Node 应用,直接启动完整外部 cordis.yml;其他所有受支持应用都从 dsh profile 进入。该例外重复了环境加载、配置所有权、插件解析、关闭流程、产物命名与测试路径。它还把 SDK 自定义变成全量替换应用树:只想替换一个插件的调用方也必须拥有 JSON-RPC server 和所有无关 deployment 配置项。

仅修改 Python wrapper 无法采用普通 profile。运行时可执行程序必须包含 dsh CLI、随附 profile 与 bundle 文件、原生库,以及在 profile 文件和外部插件位于 pkg 虚拟文件系统之外时仍可工作的模块解析路径。

决策

一个应用启动器

运行时可执行程序打包 @deepseek-ai/dsh 并运行其普通命令语法。Python 客户端默认选择 --profile sdk,转发有序绝对 --patch 路径,也可以选择另一个 dsh 可执行程序或 profile。可运行极简示例选择随附 sdk-minimal profile。私有 @deepseek-ai/dsh-sdk-python-runtime 应用包和检入的运行时 cordis.yml 均不存在。JSON-RPC 服务仍由 @deepseek-ai/dsh-sdk-app bundle 与 @deepseek-ai/dsh-sdk-jsonrpc-server 插件提供,而不是 Python 自有启动路径。

公开 Python 配置包括 dsh_bin、profile、有序 patches、dsh_home、进程 cwd/环境、provider/model/token 选择、有界初始化 timeout,以及可选的轮次/关闭 timeout。它不暴露完整 Cordis 树或任意启动 argv。RunResult 报告协议所有的运行值,不重复 profile 的持久化路径。

每次 Python 启动都要求显式 dsh_home,或子进程环境中的非空 DSH_HOME。SDK 绝不会发现 ~/.dsh。所选 home 统一拥有 profile、外部插件、凭据、设置与会话。

插件自定义

持久 SDK 自定义使用与直接 CLI 相同的 profile 接口。dsh plugin --profile <name> ... 管理外部依赖与 bundle 顺序,$DSH_HOME/profiles/<name>/cordis.patch.yml 负责持久配置项变更,home patch 对所有 profile 应用机器本地变更,Python patches 则提供单次启动 overlay。所选 profile 只有保留 SDK server 配置项时才有效。缺失 profile、bundle、server 配置项或非法 patch 都会直接失败,不存在完整配置回退;保持运行却不提供 JSON-RPC 服务的 profile 会在独立有界的初始化握手中失败,诊断会指明该 profile。

独立 sdk-minimal profile只列出一个仓库自有组合包,该组合包会插入不含 dsh-base 的完整显式配置树。持久 Bash 与字符串替换 editor 通过组合存在;共享 JSON-RPC server 不暴露根 agent 工具筛选器。动态运行时上下文、workspace 指令、settings、托管凭据、遥测、compaction 与其他所有 base 配置项均不存在。同一运行时仍会把完整 sdk 与 web profile 作为独立选择打包。

运行时 wheel 安装 dsh 控制台命令。普通 profile 与 SDK 运行仍不需要 Node;外部包管理要求调用方自行安装 pnpm。

可执行程序打包

零代码部署 manifest 是 dsh-python-runtime-closure。它把 node_modules/@deepseek-ai/dsh/lib/bin.js 以及 profile、bundle、preset、原生 addon 与共享库资源打包进 deepseek-harness-sdk-runtime-<platform>-<arch>。Wheel distribution 名称、Python import 模块、JSON-RPC 消息和协议稳定的 serverInfo.name = deepseek-harness-sdk-runtime 保持不变。

普通 Node profile 在 $DSH_HOME/profiles/node_modules 中使用符号链接,让外部插件共享安装包。操作系统符号链接无法进入 pkg 的 /snapshot 文件系统,因此打包 CLI 改为写入小型真实 ESM 代理包。每个代理直接按 Node import 条件解析源包的显式 ESM exports map,公开安装中实际存在的目标,并重新导出其虚拟模块 URL。没有 ESM 运行时目标的 export 项以及仅含可执行入口或类型声明入口的包不会产生不可用的代理条目;格式错误的 exports map 会导致启动失败。完整且匹配的 generation 不会获取跨进程写入锁。缺失或过期的配置项会获取该锁、重新检查 generation,并在不暴露半成品代理的前提下修复;任一载体都可以替换另一载体留下的受管配置项。Loader 配置项和外部插件 peer 因而可以通过普通 profile 逐级向上查找解析,同时保留一个 Cordis 和每个内置模块的单一实例。

已发布目标集合是 Linux x64、Linux arm64、macOS arm64、macOS x64 与 Windows x64。Installed-wheel 黑盒 CI 在每个目标上负责产物来源、默认及 patched profile、外部 bundle 安装、原生工具、MCP、直接 JSON-RPC、快照,以及可信真实提供方轮次。Windows x64 运行时决策负责 Windows 产物及其平台专属 shell surface。

既有决策与取代关系

本决策实现并取代单一 dsh 应用启动器中的 Python 例外与延后迁移章节。它取代单文件 Python SDK 运行时分发中的私有应用、外部完整配置、产物名称与自定义事实;后者继续负责 pkg/SEA、wheel 构建、原生目标验证与发布。独立 sdk-minimal profile只取代本 Note 中的极简 overlay 实现。没有任何 active note 被完全取代,因此无需归档。

考虑过的替代方案

把完整 cordis.yml 保留为高级逃生口。 不予采用,因为它会保留第二套应用组装,并允许调用方绕过 profile 的环境、插件与关闭所有权。

为兼容性静默使用 ~/.dsh。 不予采用,因为 SDK 进程不应在没有显式选择时继承个人插件、凭据、设置或会话。

把虚拟依赖树复制到每个 home。 不予采用,因为这会重复数百 MB,并加载第二个 Cordis 实例。保留 exports 的代理很小,而且维持模块身份。

把 pnpm 与 Node 包管理纳入每次 SDK 启动。 不予采用,因为已安装插件属于 deployment 状态,而不是逐轮运行时工作。只有 dsh plugin 需要外部包管理器。

结果

Python 调用方使用与 TypeScript 和直接 CLI 用户相同的 profile 词汇,任意外部 bundle 可以扩展 SDK profile,而无需引入另一个 launcher。调用方必须显式选择 home,完整配置与 session_root 参数不可用,可执行程序则包含共享库资源和 profile 模块代理。完整 sdk、独立 sdk-minimal 与 web 应用作为同一打包 CLI 内的不同 profile 保持分离。Installed-wheel CI 将包、profile、原生与提供方路径变成发布要求,而不是仅在源码中成立的假设。