@deepseek-ai/dsh-subagent-dsh-sdk 0.0.1-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.i18n.yaml +6 -0
- package/README.md +97 -0
- package/README.zh.md +97 -0
- package/lib/index.js +222 -0
- package/lib/invariant.js +24 -0
- package/lib/types/index.d.ts +60 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/run.d.ts +78 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, DeepSeek
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/subagent/subagent-dsh-sdk/README.md
|
|
5
|
+
README.md: 0bbcfa105ecf024a2492d39d3bf8d28956110050
|
|
6
|
+
README.zh.md: 8c8551f85951aa8475ab2ce95771e4d54e0ed89a
|
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-subagent-dsh-sdk
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
The SDK provider runs each subagent as a complete DeepSeek Harness runtime in a fresh subprocess, driven over stdio JSON-RPC through the [TypeScript SDK client](../../scaffold/client/README.md). It is the second out-of-process backend beside [`subagent-acp`](../subagent-acp/README.md), differing in the wire and the child contract: the ACP backend drives any Agent Client Protocol agent; this backend drives specifically a harness SDK runtime (`dsh-jsonrpc-agent` bin or packaged executable), so the child is a full peer harness — own `cordis.yml`-decided composition, session persistence, model route, and tools.
|
|
6
|
+
|
|
7
|
+
## Start and ownership
|
|
8
|
+
|
|
9
|
+
`start(request)` resolves the child's working directory, spawns the runtime through `DeepSeekHarness`, and completes the `initialize` handshake (with the configured `provider`/`model` route and optional `maxTokens` output cap) before it fulfills. Fulfillment therefore means the child runtime is ready and ownership has transferred to the caller. A spawn, handshake, or pre-publication cancellation failure rejects only after the subprocess has been reaped; a working-directory resolution failure rejects before anything is spawned.
|
|
10
|
+
|
|
11
|
+
The working directory resolves exactly like the ACP backend, through the seam's shared out-of-process helpers ([`dsh-subagent`](../subagent/README.md)): the configured `cwd` override when set (validated once at load), else the delegating parent session's cwd — never the server process's own cwd. The resolved path becomes the child process cwd and the workspace cwd of its SDK session.
|
|
12
|
+
|
|
13
|
+
The returned run id is minted in the parent namespace; the child runtime's session id exists only inside the child process. After publication the provider owns one SDK activity and reads the child's answer from its session events: the last complete `assistant/message`, or the `text-delta` stream accumulated before the activity was cut short — a partial answer survives cancel and error paths.
|
|
14
|
+
|
|
15
|
+
`dispose()` is idempotent: it settles the result locally as `aborted` (there is no wire-level prompt cancel), then closes the runtime — a bounded protocol `shutdown` request followed by the shared stdin-EOF → SIGTERM → SIGKILL ladder to actual exit.
|
|
16
|
+
|
|
17
|
+
## Stop-reason mapping
|
|
18
|
+
|
|
19
|
+
The SDK client returns an owned child activity rather than a prompt result. The provider reads the last durable `turn/end` inside that activity and maps it into the seam vocabulary: `completed` → `completed`, `max-tokens` → `max-tokens`, `aborted` → `aborted`; everything else — `error`, `interrupted`, `disposed`, a future variant, or an activity with no turn — maps to `error`, so an unclean stop is never reported as success. Transport-level failures after publication flatten to `stopReason: 'error'` through the `onError` diagnostic sink (wired to `ctx.logger.warn`); the seam contract forbids `result` rejecting.
|
|
20
|
+
|
|
21
|
+
## Capabilities and context
|
|
22
|
+
|
|
23
|
+
The provider advertises no start-time capabilities (`outputSchema`/`depthLimit`/`toolFilter`/`persona` all false) and `inheritsParentContext: false`: the child is a fresh runtime in another process, and the only parent-derived input is the workspace cwd. `dsh-tool-subagent` deployments over this provider set `maxDepth: 'provider-managed'` — the child harness owns its own recursion budget.
|
|
24
|
+
|
|
25
|
+
## Configuration
|
|
26
|
+
|
|
27
|
+
| Key | Default | Meaning |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `providerName` | `dsh-sdk` | Registry name on `ctx.subagents`. |
|
|
30
|
+
| `command` | required | Executable spawned per run (the child runtime bin or packaged exe). |
|
|
31
|
+
| `args` | `[]` | Command arguments (typically the child's `cordis.yml` path). |
|
|
32
|
+
| `cwd` | parent session cwd | Working-directory override; same validation as [`subagent-acp`](../subagent-acp/README.md). |
|
|
33
|
+
| `provider` | `deepseek-official` | Provider route sent in the child's `initialize`. |
|
|
34
|
+
| `model` | `deepseek-v4-flash` | Model sent in the child's `initialize`. |
|
|
35
|
+
| `maxTokens` | adapter/provider route default | Per-request output-token cap sent in the child's `initialize`; it applies to the child root agent and its in-process descendants. |
|
|
36
|
+
| `env` | `{}` | Explicit child environment layered over a credential-scrubbed parent environment (e.g. the child's own `DEEPSEEK_API_KEY`, or `DSH_CORDIS_CONFIG`). |
|
|
37
|
+
| `shutdownTimeoutMs` | `1000` | Bound on the protocol `shutdown` exchange during dispose. |
|
|
38
|
+
| `disposeEofGraceMs` | `6000` | Grace after stdin EOF before platform termination. |
|
|
39
|
+
| `disposeGraceMs` | `3000` | Exit-confirmation grace after termination; POSIX also waits this long after SIGTERM before SIGKILL. |
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
- id: subagent-dsh-sdk
|
|
43
|
+
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
|
|
44
|
+
config:
|
|
45
|
+
providerName: dsh-sdk
|
|
46
|
+
command: node
|
|
47
|
+
args: ['./packages/examples/jsonrpc-demo/lib/bin.js', './examples/jsonrpc-agent/cordis.yml']
|
|
48
|
+
maxTokens: 49152
|
|
49
|
+
env:
|
|
50
|
+
DEEPSEEK_API_KEY: !!js process.env.DEEPSEEK_API_KEY
|
|
51
|
+
- id: tool-subagent
|
|
52
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
53
|
+
config: { provider: dsh-sdk, toolName: subagent, maxDepth: 'provider-managed' }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Process boundary
|
|
57
|
+
|
|
58
|
+
The child environment is the [`dsh-subprocess`](../../subprocess/README.md) seam's `scrubbedParentEnv()` base — ambient credential-shaped and `DSH_*` names dropped — with explicit `config.env` values merged after the scrub. The child is spawned by the SDK client rather than through `ctx.subprocess` (the subprocess README's documented exception for SDK-managed transports), which is why this backend applies the scrub itself. The JSON-RPC wire is the real serialization boundary.
|
|
59
|
+
|
|
60
|
+
The package has no default export. Cordis loader unwrapping would otherwise hide the named `inject` metadata; see [postmortem 0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md).
|
|
61
|
+
|
|
62
|
+
## Model Experience
|
|
63
|
+
|
|
64
|
+
### Child-agent request
|
|
65
|
+
|
|
66
|
+
#### What the model sees
|
|
67
|
+
|
|
68
|
+
The child runtime's model receives the standalone task as its user message plus that runtime's own configured system prompt, tools, and fresh session. It receives no parent conversation. This provider advertises no optional start-time capabilities, so the local service rejects requests for persona, tool filtering, depth enforcement, or structured output instead of silently omitting them.
|
|
69
|
+
|
|
70
|
+
#### Token effect
|
|
71
|
+
|
|
72
|
+
The child pays for an independent full context and its own multi-step history. These tokens never enter the parent's context.
|
|
73
|
+
|
|
74
|
+
#### KV Cache effect
|
|
75
|
+
|
|
76
|
+
Independent of the parent request cache. Each SDK child can reuse only prefixes identical under its own provider, model, composition, and history; child steps otherwise grow append-only.
|
|
77
|
+
|
|
78
|
+
### Parent tool result, indirectly
|
|
79
|
+
|
|
80
|
+
#### What the model sees
|
|
81
|
+
|
|
82
|
+
Through `dsh-tool-subagent`, the parent receives only the child's final assistant text (or accumulated partial text) or that consumer's exact stop-reason error, not intermediate messages or tool traffic.
|
|
83
|
+
|
|
84
|
+
#### Token effect
|
|
85
|
+
|
|
86
|
+
Parent input grows only by the final result or error, which is data-dependent and retained until compaction. This provider adds no parent schema itself.
|
|
87
|
+
|
|
88
|
+
#### KV Cache effect
|
|
89
|
+
|
|
90
|
+
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
|
91
|
+
|
|
92
|
+
## Known Limitations and Deferred Work
|
|
93
|
+
|
|
94
|
+
- **A fresh runtime process per run** — no pooling; a harness runtime boots a full plugin tree, so per-run spawn cost is higher than the ACP backend's typical child.
|
|
95
|
+
- **No optional start-time capabilities** — the parent cannot enforce `outputSchema`, depth, tool filters, or persona inside the child process; configure the child's own `cordis.yml` instead.
|
|
96
|
+
- **The child's transcript stays in the child's own session root** — the parent log records only the delegation tool call/result (the seam's child-isolation rule); the streamed `session.event` channel is consumed for output extraction, not bridged into the parent log.
|
|
97
|
+
- **Local child processes only** — the resolved cwd is a local path; a remote runtime would need its own backend.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-subagent-dsh-sdk
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
SDK 提供方会在全新的子进程中把每个 subagent 作为完整的 DeepSeek Harness 运行时运行,并经由 [TypeScript SDK 客户端](../../scaffold/client/README.md) 通过 stdio JSON-RPC 驱动。它是 [`subagent-acp`](../subagent-acp/README.md) 之外的第二个进程外后端,差异在协议格式(wire format)和子进程约定:ACP(Agent Client Protocol)后端能驱动任何 Agent Client Protocol agent(智能体);本后端专门驱动 harness SDK 运行时(`dsh-jsonrpc-agent` bin 或打包后的可执行文件),因此子进程是一个完整的对等 harness,拥有由 `cordis.yml` 决定的组合、会话持久化、模型路由和工具。
|
|
6
|
+
|
|
7
|
+
## 启动与所有权
|
|
8
|
+
|
|
9
|
+
`start(request)` 先解析子进程工作目录,通过 `DeepSeekHarness` spawn 运行时,并在履行前完成 `initialize` 握手(携带配置的 `provider`/`model` 路由及可选的 `maxTokens` 输出上限)。因此,履行意味着子运行时已就绪、所有权已移交给调用方。spawn、握手或发布前取消失败时,只会在子进程被回收后拒绝;工作目录解析失败则会在尚未 spawn 任何内容时拒绝。
|
|
10
|
+
|
|
11
|
+
工作目录的解析与 ACP 后端完全一致,并使用 seam 共享的进程外辅助工具([`dsh-subagent`](../subagent/README.md)):设置了 `cwd` 覆盖值时使用该值(加载时校验一次),否则使用发起委派的父会话 cwd,绝不使用服务器进程自身的 cwd。解析出的路径同时成为子进程 cwd 和其 SDK 会话的工作区 cwd。
|
|
12
|
+
|
|
13
|
+
返回的 run id 在父级命名空间中生成;子运行时的会话 id 只存在于子进程内部。发布后,提供方拥有一段 SDK 活动,并从子会话事件中读取答案:最后一条完整的 `assistant/message`,或该活动中断前已经累积的 `text-delta` 流;部分答案在取消和错误路径上都得以保留。
|
|
14
|
+
|
|
15
|
+
`dispose()`(资源释放)是幂等的:先在本地把结果确定为 `aborted`(协议层面没有提示词取消机制),再关闭运行时,即先发出一次有界的协议 `shutdown` 请求,随后通过共享的 stdin-EOF → SIGTERM → SIGKILL 阶梯使进程实际退出。
|
|
16
|
+
|
|
17
|
+
## 停止原因映射
|
|
18
|
+
|
|
19
|
+
SDK 客户端返回自有子活动,而不是提示词结果。提供方读取该活动内最后一个已持久化的 `turn/end`,并将其映射为 seam 词汇:`completed` → `completed`,`max-tokens` → `max-tokens`,`aborted` → `aborted`;其余情况,包括 `error`、`interrupted`、`disposed`、未来变体或不含轮次的活动,均映射为 `error`,因此非正常停止绝不会报告为成功。发布后的传输层失败会通过 `onError` 诊断接收器(连接到 `ctx.logger.warn`)压平为 `stopReason: 'error'`;seam 约定禁止 `result` 被拒绝。
|
|
20
|
+
|
|
21
|
+
## 能力与上下文
|
|
22
|
+
|
|
23
|
+
Provider 不宣告任何启动期能力(`outputSchema`/`depthLimit`/`toolFilter`/`persona` 全为 false),且 `inheritsParentContext: false`:子进程是另一进程里的全新运行时,唯一来自父方的输入是工作区 cwd。基于本 provider 的 `dsh-tool-subagent` 部署应设置 `maxDepth: 'provider-managed'`——子 harness 拥有自己的递归预算。
|
|
24
|
+
|
|
25
|
+
## 配置
|
|
26
|
+
|
|
27
|
+
| 键 | 默认 | 含义 |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `providerName` | `dsh-sdk` | `ctx.subagents` 上的注册名。 |
|
|
30
|
+
| `command` | 必填 | 每次运行时 spawn 的可执行文件(子运行时 bin 或打包后的可执行文件)。 |
|
|
31
|
+
| `args` | `[]` | 命令参数(通常是子进程的 `cordis.yml` 路径)。 |
|
|
32
|
+
| `cwd` | 父会话 cwd | 工作目录覆盖;校验规则与 [`subagent-acp`](../subagent-acp/README.md) 相同。 |
|
|
33
|
+
| `provider` | `deepseek-official` | 写入子进程 `initialize` 的提供方路由。 |
|
|
34
|
+
| `model` | `deepseek-v4-flash` | 写入子进程 `initialize` 的模型。 |
|
|
35
|
+
| `maxTokens` | 适配器/提供方路由默认值 | 写入子进程 `initialize` 的单次请求输出 token 上限;对子运行时的根 agent 及其进程内后代生效。 |
|
|
36
|
+
| `env` | `{}` | 在凭据擦除后的父环境之上叠加的显式子环境(例如子进程自己的 `DEEPSEEK_API_KEY`,或 `DSH_CORDIS_CONFIG`)。 |
|
|
37
|
+
| `shutdownTimeoutMs` | `1000` | dispose 期间协议 `shutdown` 交换的时限。 |
|
|
38
|
+
| `disposeEofGraceMs` | `6000` | stdin EOF 之后、平台终止之前的宽限。 |
|
|
39
|
+
| `disposeGraceMs` | `3000` | 终止后的退出确认窗口;POSIX 在 SIGTERM 之后、SIGKILL 之前也等待同样时长。 |
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
- id: subagent-dsh-sdk
|
|
43
|
+
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
|
|
44
|
+
config:
|
|
45
|
+
providerName: dsh-sdk
|
|
46
|
+
command: node
|
|
47
|
+
args: ['./packages/examples/jsonrpc-demo/lib/bin.js', './examples/jsonrpc-agent/cordis.yml']
|
|
48
|
+
maxTokens: 49152
|
|
49
|
+
env:
|
|
50
|
+
DEEPSEEK_API_KEY: !!js process.env.DEEPSEEK_API_KEY
|
|
51
|
+
- id: tool-subagent
|
|
52
|
+
name: '@deepseek-ai/dsh-tool-subagent'
|
|
53
|
+
config: { provider: dsh-sdk, toolName: subagent, maxDepth: 'provider-managed' }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 进程边界
|
|
57
|
+
|
|
58
|
+
子进程环境以 [`dsh-subprocess`](../../subprocess/README.md) seam 的 `scrubbedParentEnv()` 为基础,先移除疑似凭据和名称为 `DSH_*` 的环境变量,再合并显式 `config.env` 值。子进程由 SDK 客户端 spawn,而不是经由 `ctx.subprocess` spawn(这是 subprocess README 中记录的 SDK 托管传输例外),因此本后端会自行执行环境清理。JSON-RPC 协议格式才是真正的序列化边界。
|
|
59
|
+
|
|
60
|
+
本包没有默认导出。否则 Cordis loader 解包会隐藏具名 `inject` 元数据;见[事故复盘(postmortem)0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md)。
|
|
61
|
+
|
|
62
|
+
## 模型体验
|
|
63
|
+
|
|
64
|
+
### 子 agent 请求
|
|
65
|
+
|
|
66
|
+
#### 模型看到的内容
|
|
67
|
+
|
|
68
|
+
子运行时的模型会收到作为用户消息的独立任务,以及该运行时自身配置的系统提示词、工具和全新会话。它不会收到父级对话。本提供方不声明可选的启动时能力,因此本地服务会拒绝要求 persona、工具过滤、深度强制或结构化输出的请求,而不是静默省略这些要求。
|
|
69
|
+
|
|
70
|
+
#### Token 影响
|
|
71
|
+
|
|
72
|
+
子运行时会为独立的完整上下文及其多步骤历史消耗 token。这些 token 绝不会进入父级上下文。
|
|
73
|
+
|
|
74
|
+
#### KV Cache 影响
|
|
75
|
+
|
|
76
|
+
与父级请求缓存相互独立。每个 SDK 子进程只能复用其自身提供方、模型、组合和历史均相同时的前缀;除此之外,子 agent 的步骤仅追加增长。
|
|
77
|
+
|
|
78
|
+
### 父级工具结果(间接)
|
|
79
|
+
|
|
80
|
+
#### 模型看到的内容
|
|
81
|
+
|
|
82
|
+
经由 `dsh-tool-subagent`,父级只会收到子运行时最终的 assistant 文本(或累积的部分文本),或该消费方给出的精确停止原因错误;不会收到中间消息或工具流量。
|
|
83
|
+
|
|
84
|
+
#### Token 影响
|
|
85
|
+
|
|
86
|
+
父级输入只增加最终结果或错误,其大小取决于数据,并保留到压缩(compaction)为止。本提供方自身不会向父级添加任何 schema。
|
|
87
|
+
|
|
88
|
+
#### KV Cache 影响
|
|
89
|
+
|
|
90
|
+
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
|
91
|
+
|
|
92
|
+
## 已知限制与暂缓事项
|
|
93
|
+
|
|
94
|
+
- **每次运行都使用全新的运行时进程**:不使用进程池;harness 运行时需要启动完整的插件树,因此每次运行的 spawn 成本高于 ACP 后端通常使用的子进程。
|
|
95
|
+
- **不支持可选的启动时能力**:父级无法在子进程内强制执行 `outputSchema`、深度限制、工具过滤或 persona;应改为配置子进程自身的 `cordis.yml`。
|
|
96
|
+
- **子进程的 transcript(文本记录)保留在其自身的会话根目录中**:父级日志只记录委派工具调用/结果(seam 的子级隔离规则);流式 `session.event` 通道只用于提取输出,不会桥接到父级日志中。
|
|
97
|
+
- **仅支持本地子进程**:解析出的 cwd 是本地路径;远程运行时需要独立的后端。
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { NO_START_CAPABILITIES, assertPositiveFinite, resolveChildCwd, settleRunResult, subprocessRunHandle, validateConfiguredCwd } from "@deepseek-ai/dsh-subagent";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { DeepSeekHarness } from "@deepseek-ai/dsh-sdk-client";
|
|
5
|
+
import { SessionId } from "@deepseek-ai/dsh-session";
|
|
6
|
+
import { scrubbedParentEnv } from "@deepseek-ai/dsh-subprocess";
|
|
7
|
+
//#region lib/types/run.js
|
|
8
|
+
/**
|
|
9
|
+
* Fresh-process SDK subagent client. Drives one child DeepSeek Harness
|
|
10
|
+
* runtime over stdio JSON-RPC through `@deepseek-ai/dsh-sdk-client` and owns
|
|
11
|
+
* cancellation and quiescent disposal. Structure mirrors the ACP backend
|
|
12
|
+
* (`@deepseek-ai/dsh-subagent-acp`): publish after the child handshake,
|
|
13
|
+
* flatten child failures into stop reasons, tear down to quiescence. The
|
|
14
|
+
* child is spawned BY the SDK client rather than through `ctx.subprocess` —
|
|
15
|
+
* the subprocess seam's documented exception for SDK-managed transports —
|
|
16
|
+
* so this driver applies the seam's shared env scrub itself.
|
|
17
|
+
*
|
|
18
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk/run
|
|
19
|
+
*/
|
|
20
|
+
/** EOF grace for child flush and nested-process teardown; wider than the signal grace below. */
|
|
21
|
+
const DEFAULT_DISPOSE_EOF_GRACE_MS = 6e3;
|
|
22
|
+
/** Default POSIX grace between SIGTERM and SIGKILL on dispose (the `disposeGraceMs` config). */
|
|
23
|
+
const DEFAULT_DISPOSE_GRACE_MS = 3e3;
|
|
24
|
+
/** Default bound on the protocol `shutdown` exchange during dispose. */
|
|
25
|
+
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 1e3;
|
|
26
|
+
/**
|
|
27
|
+
* Map a child turn-end reason to a harness {@link SubagentStopReason}.
|
|
28
|
+
* @param reason - the owned child run's final durable turn reason, or
|
|
29
|
+
* `undefined` when it settled without running a turn.
|
|
30
|
+
* @returns the harness equivalent; an absent or unknown reason maps to
|
|
31
|
+
* `error`, so an unclean stop is never reported as `completed`.
|
|
32
|
+
*/
|
|
33
|
+
function sdkStopReason(reason) {
|
|
34
|
+
switch (reason?.kind) {
|
|
35
|
+
case "completed": return "completed";
|
|
36
|
+
case "max-tokens": return "max-tokens";
|
|
37
|
+
case "aborted": return "aborted";
|
|
38
|
+
default: return "error";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Normalize an unknown thrown value to an Error (the catch binding is `unknown`). */
|
|
42
|
+
function toError(value) {
|
|
43
|
+
/* v8 ignore next */
|
|
44
|
+
return value instanceof Error ? value : new Error(String(value));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Start and publish one SDK runtime child after its `initialize` handshake.
|
|
48
|
+
* Child failures resolve through the run result; startup failures reject
|
|
49
|
+
* after process reap. Disposal shuts the runtime down and reaps it.
|
|
50
|
+
* @param request - the start request; its signal is the cancellation channel.
|
|
51
|
+
* @param spec - the resolved spawn spec: command/args/cwd, the child's
|
|
52
|
+
* provider/model route, env, timeouts, and the optional error sink.
|
|
53
|
+
* @returns the ready run handle for the child subprocess.
|
|
54
|
+
*/
|
|
55
|
+
async function startSdkRun(request, spec) {
|
|
56
|
+
if (request.signal.aborted) throw new Error("subagent request was aborted before the SDK child started");
|
|
57
|
+
const id = SessionId(randomUUID());
|
|
58
|
+
const harness = new DeepSeekHarness({
|
|
59
|
+
launch: {
|
|
60
|
+
command: spec.command,
|
|
61
|
+
args: spec.args,
|
|
62
|
+
cwd: spec.cwd,
|
|
63
|
+
env: {
|
|
64
|
+
...scrubbedParentEnv(),
|
|
65
|
+
...spec.env
|
|
66
|
+
},
|
|
67
|
+
shutdownTimeoutMs: spec.shutdownTimeoutMs,
|
|
68
|
+
disposeEofGraceMs: spec.disposeEofGraceMs,
|
|
69
|
+
disposeGraceMs: spec.disposeGraceMs
|
|
70
|
+
},
|
|
71
|
+
cwd: spec.cwd,
|
|
72
|
+
provider: spec.provider,
|
|
73
|
+
model: spec.model,
|
|
74
|
+
...spec.maxTokens === void 0 ? {} : { maxTokens: spec.maxTokens }
|
|
75
|
+
});
|
|
76
|
+
const flags = { cancelled: false };
|
|
77
|
+
let signalCancelSettled;
|
|
78
|
+
const cancelSettled = new Promise((resolve) => {
|
|
79
|
+
signalCancelSettled = resolve;
|
|
80
|
+
});
|
|
81
|
+
const requestCancel = () => {
|
|
82
|
+
if (flags.cancelled) return;
|
|
83
|
+
flags.cancelled = true;
|
|
84
|
+
signalCancelSettled();
|
|
85
|
+
};
|
|
86
|
+
const onAbort = () => {
|
|
87
|
+
requestCancel();
|
|
88
|
+
};
|
|
89
|
+
request.signal.addEventListener("abort", onAbort, { once: true });
|
|
90
|
+
try {
|
|
91
|
+
await Promise.race([harness.start(), cancelSettled.then(() => {
|
|
92
|
+
throw new Error("subagent cancelled before the SDK child initialized");
|
|
93
|
+
})]);
|
|
94
|
+
/* v8 ignore next */
|
|
95
|
+
if (flags.cancelled) throw new Error("subagent cancelled before the SDK child initialized");
|
|
96
|
+
} catch (error) {
|
|
97
|
+
request.signal.removeEventListener("abort", onAbort);
|
|
98
|
+
await harness.close();
|
|
99
|
+
if (flags.cancelled) throw new Error("subagent request was aborted before the SDK child started");
|
|
100
|
+
throw toError(error);
|
|
101
|
+
}
|
|
102
|
+
const childSessionId = `session-${randomUUID().replaceAll("-", "")}`;
|
|
103
|
+
let lastMessage;
|
|
104
|
+
const partial = [];
|
|
105
|
+
const observe = (notification) => {
|
|
106
|
+
if (notification.method !== "session.event" || notification.params.sessionId !== childSessionId) return;
|
|
107
|
+
const event = notification.params.event;
|
|
108
|
+
if (event.type === "assistant/chunk" && event.data.chunk.type === "text-delta") partial.push(event.data.chunk.text);
|
|
109
|
+
else if (event.type === "assistant/message") lastMessage = event.data.message.content;
|
|
110
|
+
};
|
|
111
|
+
const collectOutput = () => {
|
|
112
|
+
if (lastMessage !== void 0) return lastMessage;
|
|
113
|
+
const text = partial.join("");
|
|
114
|
+
return text.length > 0 ? [{
|
|
115
|
+
type: "text",
|
|
116
|
+
text
|
|
117
|
+
}] : [];
|
|
118
|
+
};
|
|
119
|
+
return subprocessRunHandle({
|
|
120
|
+
id,
|
|
121
|
+
result: settleRunResult({
|
|
122
|
+
attempt: async () => {
|
|
123
|
+
const turn = await Promise.race([harness.session(childSessionId).run(request.prompt, { onNotification: observe }), cancelSettled.then(() => "cancelled")]);
|
|
124
|
+
if (turn === "cancelled") return {
|
|
125
|
+
output: collectOutput(),
|
|
126
|
+
stopReason: "aborted"
|
|
127
|
+
};
|
|
128
|
+
const lastEnd = turn.events.findLast((event) => event.type === "turn/end");
|
|
129
|
+
return {
|
|
130
|
+
output: collectOutput(),
|
|
131
|
+
stopReason: sdkStopReason(lastEnd?.data.reason)
|
|
132
|
+
};
|
|
133
|
+
},
|
|
134
|
+
collectOutput,
|
|
135
|
+
cancelled: () => flags.cancelled,
|
|
136
|
+
onError: spec.onError,
|
|
137
|
+
signal: request.signal,
|
|
138
|
+
onAbort
|
|
139
|
+
}),
|
|
140
|
+
signal: request.signal,
|
|
141
|
+
onAbort,
|
|
142
|
+
requestCancel,
|
|
143
|
+
teardown: () => harness.close()
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region lib/types/index.js
|
|
148
|
+
/**
|
|
149
|
+
* Out-of-process SDK subagent backend. Each child is a complete DeepSeek
|
|
150
|
+
* Harness runtime in its own process — own `cordis.yml`-decided composition,
|
|
151
|
+
* session, model route, and tools — driven over stdio JSON-RPC through the
|
|
152
|
+
* TypeScript SDK client, so it shares no Cordis context and advertises no
|
|
153
|
+
* parent-enforced start capabilities; the ONE thing it reads off
|
|
154
|
+
* `request.parent` is the session's workspace cwd. This plugin uses named
|
|
155
|
+
* exports only; a default would hide its loader metadata (see
|
|
156
|
+
* `docs/postmortem/0001-acp-default-export-drops-inject.md`).
|
|
157
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk
|
|
158
|
+
*/
|
|
159
|
+
const name = "subagent-dsh-sdk";
|
|
160
|
+
const inject = ["subagents"];
|
|
161
|
+
const Config = z.object({
|
|
162
|
+
providerName: z.string().default("dsh-sdk"),
|
|
163
|
+
command: z.string().required(),
|
|
164
|
+
args: z.array(z.string()).default([]),
|
|
165
|
+
cwd: z.string(),
|
|
166
|
+
provider: z.string().default("deepseek-official"),
|
|
167
|
+
model: z.string().default("deepseek-v4-flash"),
|
|
168
|
+
maxTokens: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER),
|
|
169
|
+
env: z.dict(z.string()).default({}),
|
|
170
|
+
shutdownTimeoutMs: z.number().default(DEFAULT_SHUTDOWN_TIMEOUT_MS),
|
|
171
|
+
disposeEofGraceMs: z.number().default(DEFAULT_DISPOSE_EOF_GRACE_MS),
|
|
172
|
+
disposeGraceMs: z.number().default(DEFAULT_DISPOSE_GRACE_MS)
|
|
173
|
+
});
|
|
174
|
+
/**
|
|
175
|
+
* The SDK provider. Advertises NO start-time capabilities: an out-of-process
|
|
176
|
+
* child cannot honor `outputSchema`/`maxDepth`/`toolFilter`/`persona` (the
|
|
177
|
+
* service rejects a request needing any of them before `start` runs).
|
|
178
|
+
*/
|
|
179
|
+
var SdkProvider = class {
|
|
180
|
+
name;
|
|
181
|
+
ctx;
|
|
182
|
+
config;
|
|
183
|
+
capabilities = NO_START_CAPABILITIES;
|
|
184
|
+
inheritsParentContext = false;
|
|
185
|
+
constructor(name, ctx, config) {
|
|
186
|
+
this.name = name;
|
|
187
|
+
this.ctx = ctx;
|
|
188
|
+
this.config = config;
|
|
189
|
+
}
|
|
190
|
+
start(request) {
|
|
191
|
+
return startSdkRun(request, {
|
|
192
|
+
command: this.config.command,
|
|
193
|
+
args: this.config.args,
|
|
194
|
+
cwd: resolveChildCwd("subagent-dsh-sdk", this.config.cwd, request.parent.session.header.cwd),
|
|
195
|
+
provider: this.config.provider,
|
|
196
|
+
model: this.config.model,
|
|
197
|
+
...this.config.maxTokens === void 0 ? {} : { maxTokens: this.config.maxTokens },
|
|
198
|
+
env: this.config.env,
|
|
199
|
+
shutdownTimeoutMs: this.config.shutdownTimeoutMs,
|
|
200
|
+
disposeEofGraceMs: this.config.disposeEofGraceMs,
|
|
201
|
+
disposeGraceMs: this.config.disposeGraceMs,
|
|
202
|
+
onError: (error, stopReason) => {
|
|
203
|
+
this.ctx.logger.warn(`subagent-dsh-sdk "${this.name}": child run failed (${stopReason}): ${error.message}`);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
function apply(ctx, config) {
|
|
209
|
+
const resolved = config;
|
|
210
|
+
assertPositiveFinite("subagent-dsh-sdk", "shutdownTimeoutMs", resolved.shutdownTimeoutMs);
|
|
211
|
+
assertPositiveFinite("subagent-dsh-sdk", "disposeEofGraceMs", resolved.disposeEofGraceMs);
|
|
212
|
+
assertPositiveFinite("subagent-dsh-sdk", "disposeGraceMs", resolved.disposeGraceMs);
|
|
213
|
+
if (resolved.maxTokens !== void 0 && (!Number.isSafeInteger(resolved.maxTokens) || resolved.maxTokens <= 0)) throw new TypeError("subagent-dsh-sdk maxTokens must be a positive safe integer");
|
|
214
|
+
const configuredCwd = validateConfiguredCwd("subagent-dsh-sdk", resolved.cwd);
|
|
215
|
+
const validated = configuredCwd === void 0 ? resolved : {
|
|
216
|
+
...resolved,
|
|
217
|
+
cwd: configuredCwd
|
|
218
|
+
};
|
|
219
|
+
ctx.subagents.registerProvider(new SdkProvider(validated.providerName, ctx, validated));
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
export { Config, apply, inject, name };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-dsh-sdk`.
|
|
4
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-subagent-dsh-sdk";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "subagent-dsh-sdk-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: run lifecycle pairing is owned and checked by the
|
|
13
|
+
* subagent seam's invariant; this backend's own state lives in the child
|
|
14
|
+
* process beyond this context's event streams.
|
|
15
|
+
*/
|
|
16
|
+
const install = () => {};
|
|
17
|
+
/**
|
|
18
|
+
* Register this package's invariant companion.
|
|
19
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
20
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
21
|
+
*/
|
|
22
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
23
|
+
//#endregion
|
|
24
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Out-of-process SDK subagent backend. Each child is a complete DeepSeek
|
|
3
|
+
* Harness runtime in its own process — own `cordis.yml`-decided composition,
|
|
4
|
+
* session, model route, and tools — driven over stdio JSON-RPC through the
|
|
5
|
+
* TypeScript SDK client, so it shares no Cordis context and advertises no
|
|
6
|
+
* parent-enforced start capabilities; the ONE thing it reads off
|
|
7
|
+
* `request.parent` is the session's workspace cwd. This plugin uses named
|
|
8
|
+
* exports only; a default would hide its loader metadata (see
|
|
9
|
+
* `docs/postmortem/0001-acp-default-export-drops-inject.md`).
|
|
10
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import z from '@deepseek-ai/schemastery';
|
|
14
|
+
export declare const name = "subagent-dsh-sdk";
|
|
15
|
+
export declare const inject: string[];
|
|
16
|
+
/** Config: how to spawn and drive the child SDK runtime process. */
|
|
17
|
+
export interface Config {
|
|
18
|
+
/** Provider name on `ctx.subagents` (default `dsh-sdk`). */
|
|
19
|
+
providerName: string;
|
|
20
|
+
/** The executable to spawn for each run (the child runtime bin or packaged exe). */
|
|
21
|
+
command: string;
|
|
22
|
+
/** Arguments passed to {@link command} (typically the child's `cordis.yml` path). */
|
|
23
|
+
args: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Working directory override for the child process and its SDK session
|
|
26
|
+
* workspace. Must be non-empty; a relative path resolves against the
|
|
27
|
+
* harness launch directory at load, and the result must be an existing
|
|
28
|
+
* directory. When omitted, each child inherits its delegating parent
|
|
29
|
+
* session's cwd — and starting one from a parent session that has no cwd
|
|
30
|
+
* fails.
|
|
31
|
+
*/
|
|
32
|
+
cwd?: string;
|
|
33
|
+
/** Provider route the child runtime initializes with (default `deepseek-official`). */
|
|
34
|
+
provider: string;
|
|
35
|
+
/** Model the child runtime initializes with (default `deepseek-v4-flash`). */
|
|
36
|
+
model: string;
|
|
37
|
+
/** Optional per-request output-token cap for the child runtime. */
|
|
38
|
+
maxTokens?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Extra environment variables for the child process — e.g. the child
|
|
41
|
+
* runtime's own `DEEPSEEK_API_KEY`, or `DSH_CORDIS_CONFIG` naming its
|
|
42
|
+
* config. Forwarded on top of a credential-scrubbed copy of the parent
|
|
43
|
+
* env, so an explicit key here reaches the child while ambient secrets do
|
|
44
|
+
* not leak implicitly.
|
|
45
|
+
*/
|
|
46
|
+
env: Record<string, string>;
|
|
47
|
+
/** Bound (ms) on the protocol `shutdown` exchange during dispose. */
|
|
48
|
+
shutdownTimeoutMs?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Grace period (ms) for the child's EOF-driven quiesce on dispose — its
|
|
51
|
+
* window to flush persistence and tear down its own nested subprocesses
|
|
52
|
+
* before the parent escalates to a signal.
|
|
53
|
+
*/
|
|
54
|
+
disposeEofGraceMs?: number;
|
|
55
|
+
/** Termination confirmation window (ms), including forced exit on every platform. */
|
|
56
|
+
disposeGraceMs?: number;
|
|
57
|
+
}
|
|
58
|
+
export declare const Config: z<Config>;
|
|
59
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-subagent-dsh-sdk`.
|
|
3
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "subagent-dsh-sdk-invariant";
|
|
8
|
+
/** Service required before the companion can reserve package ownership. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fresh-process SDK subagent client. Drives one child DeepSeek Harness
|
|
3
|
+
* runtime over stdio JSON-RPC through `@deepseek-ai/dsh-sdk-client` and owns
|
|
4
|
+
* cancellation and quiescent disposal. Structure mirrors the ACP backend
|
|
5
|
+
* (`@deepseek-ai/dsh-subagent-acp`): publish after the child handshake,
|
|
6
|
+
* flatten child failures into stop reasons, tear down to quiescence. The
|
|
7
|
+
* child is spawned BY the SDK client rather than through `ctx.subprocess` —
|
|
8
|
+
* the subprocess seam's documented exception for SDK-managed transports —
|
|
9
|
+
* so this driver applies the seam's shared env scrub itself.
|
|
10
|
+
*
|
|
11
|
+
* @module @deepseek-ai/dsh-subagent-dsh-sdk/run
|
|
12
|
+
*/
|
|
13
|
+
import { type TurnEndReason } from '@deepseek-ai/dsh-session';
|
|
14
|
+
import type { SubagentRun, SubagentStartRequest, SubagentStopReason } from '@deepseek-ai/dsh-subagent';
|
|
15
|
+
/** Resolved spawn spec for an SDK runtime child process (no defaults — see Config). */
|
|
16
|
+
export interface SdkRunSpec {
|
|
17
|
+
/** The executable to spawn (the child runtime — a `dsh-jsonrpc-agent` bin or packaged exe). */
|
|
18
|
+
command: string;
|
|
19
|
+
/** Arguments passed to {@link command} (typically the child's `cordis.yml` path). */
|
|
20
|
+
args: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Absolute working directory for the child process AND the workspace cwd
|
|
23
|
+
* of its SDK session. The provider resolves it before this spec exists:
|
|
24
|
+
* config override, else the delegating parent session's workspace.
|
|
25
|
+
*/
|
|
26
|
+
cwd: string;
|
|
27
|
+
/** Provider route the child runtime initializes with. */
|
|
28
|
+
provider: string;
|
|
29
|
+
/** Model the child runtime initializes with. */
|
|
30
|
+
model: string;
|
|
31
|
+
/** Optional per-request output-token cap sent in the child runtime's initialize handshake. */
|
|
32
|
+
maxTokens?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Extra environment variables to ADD for the child (e.g. the child
|
|
35
|
+
* runtime's own `DEEPSEEK_API_KEY`, or `DSH_CORDIS_CONFIG`). Merged after
|
|
36
|
+
* the seam's `scrubbedParentEnv()` base, so an explicit credential or
|
|
37
|
+
* current `DSH_*` fact survives while ambient namesakes never leak.
|
|
38
|
+
*/
|
|
39
|
+
env: Record<string, string>;
|
|
40
|
+
/** Bound (ms) on the protocol `shutdown` exchange during dispose. */
|
|
41
|
+
shutdownTimeoutMs: number;
|
|
42
|
+
/** Grace period (ms) for the child's EOF-driven quiesce on dispose. */
|
|
43
|
+
disposeEofGraceMs: number;
|
|
44
|
+
/** Termination confirmation window (ms), including forced exit on every platform. */
|
|
45
|
+
disposeGraceMs: number;
|
|
46
|
+
/**
|
|
47
|
+
* Sink for a child-level failure that the run flattened into a stop reason
|
|
48
|
+
* (the seam contract forbids `result` rejecting). A throw from the sink
|
|
49
|
+
* itself is contained. Optional — omitted in unit tests that assert the
|
|
50
|
+
* stop reason directly.
|
|
51
|
+
*/
|
|
52
|
+
onError?: (error: Error, stopReason: SubagentStopReason) => void;
|
|
53
|
+
}
|
|
54
|
+
/** EOF grace for child flush and nested-process teardown; wider than the signal grace below. */
|
|
55
|
+
export declare const DEFAULT_DISPOSE_EOF_GRACE_MS = 6000;
|
|
56
|
+
/** Default POSIX grace between SIGTERM and SIGKILL on dispose (the `disposeGraceMs` config). */
|
|
57
|
+
export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
|
|
58
|
+
/** Default bound on the protocol `shutdown` exchange during dispose. */
|
|
59
|
+
export declare const DEFAULT_SHUTDOWN_TIMEOUT_MS = 1000;
|
|
60
|
+
/**
|
|
61
|
+
* Map a child turn-end reason to a harness {@link SubagentStopReason}.
|
|
62
|
+
* @param reason - the owned child run's final durable turn reason, or
|
|
63
|
+
* `undefined` when it settled without running a turn.
|
|
64
|
+
* @returns the harness equivalent; an absent or unknown reason maps to
|
|
65
|
+
* `error`, so an unclean stop is never reported as `completed`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function sdkStopReason(reason: TurnEndReason | undefined): SubagentStopReason;
|
|
68
|
+
/**
|
|
69
|
+
* Start and publish one SDK runtime child after its `initialize` handshake.
|
|
70
|
+
* Child failures resolve through the run result; startup failures reject
|
|
71
|
+
* after process reap. Disposal shuts the runtime down and reaps it.
|
|
72
|
+
* @param request - the start request; its signal is the cancellation channel.
|
|
73
|
+
* @param spec - the resolved spawn spec: command/args/cwd, the child's
|
|
74
|
+
* provider/model route, env, timeouts, and the optional error sink.
|
|
75
|
+
* @returns the ready run handle for the child subprocess.
|
|
76
|
+
*/
|
|
77
|
+
export declare function startSdkRun(request: SubagentStartRequest, spec: SdkRunSpec): Promise<SubagentRun>;
|
|
78
|
+
//# sourceMappingURL=run.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-subagent-dsh-sdk",
|
|
3
|
+
"description": "Out-of-process SDK subagent backend: drives a child DeepSeek Harness runtime subprocess over stdio JSON-RPC through the TypeScript SDK client",
|
|
4
|
+
"version": "0.0.1-rc.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "restricted"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/subagent/subagent-dsh-sdk"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./src/*": "./src/*",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"lib/index.js",
|
|
30
|
+
"lib/invariant.js",
|
|
31
|
+
"lib/types/**/*.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"license": "BSD-3-Clause",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
|
|
36
|
+
"@deepseek-ai/dsh-sdk-client": "^0.0.1-rc.1",
|
|
37
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.1",
|
|
38
|
+
"@deepseek-ai/dsh-subagent": "^0.0.1-rc.1",
|
|
39
|
+
"@deepseek-ai/dsh-subprocess": "^0.0.1-rc.1",
|
|
40
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
41
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
42
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.1"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@deepseek-ai/schemastery": "^3.18.1-rc.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-agent": "^0.0.1-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-loader-smoke": "^0.0.1-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-sdk-client": "^0.0.1-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-sdk-protocol": "^0.0.1-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-subprocess": "^0.0.1-rc.1",
|
|
56
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-session": "^0.0.1-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-subagent": "^0.0.1-rc.1"
|
|
59
|
+
}
|
|
60
|
+
}
|