@deepseek-ai/dsh-subagent-dsh-sdk 0.1.1-rc.2 → 0.1.2-alpha.2
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/README.i18n.yaml +2 -2
- package/README.md +124 -33
- package/README.zh.md +128 -37
- package/lib/index.js +241 -67
- package/lib/types/index.d.ts +14 -10
- package/lib/types/run.d.ts +44 -25
- package/package.json +32 -21
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/subagent/subagent-dsh-sdk/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 59dc34f33a924c7cc67225a7337df2f8a3935f30
|
|
6
|
+
README.zh.md: 31da5276333f5ea6a90bd283639ceb495345075e
|
package/README.md
CHANGED
|
@@ -1,50 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "The out-of-process SDK subagent backend for users and maintainers choosing a delegation provider, configuring a child Harness runtime command, or debugging remote child runs."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-subagent-dsh-sdk
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## Summary
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
`dsh-subagent-dsh-sdk` runs each delegated child as a complete DeepSeek Harness runtime in a fresh subprocess, driven over stdio JSON-RPC through the TypeScript SDK client. It is the second out-of-process backend beside the ACP provider, differing in the wire and the child contract: the child is a full peer harness with its own `cordis.yml`-decided composition, session persistence, model route, and tools. Each run spawns the child runtime (the resolved `@deepseek-ai/dsh` CLI under Node, or the configured `dshBin`), completes an `initialize` handshake with the configured provider and model route, submits the task, and reads the answer from the child's session events. The parent receives only the child's final assistant text or a safe error — no intermediate messages or tool traffic crosses the boundary. Choose it when the child should be a genuine Harness runtime, fully isolated from the parent harness.
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## Table of Contents
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
-----
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
Mount this provider when a delegation should run as a complete Harness runtime in its own process. The common path is explicit: mount the seam, mount this provider, and give it a command that starts an SDK runtime with its own `cordis.yml`.
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
### When to choose it
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
Choose this backend when the child must be a full harness peer — its own composition, session persistence, model route, and tools — rather than an agent that shares the parent's process. Choose an in-process backend when the child must share the parent's composition or honor parent-enforced non-route capabilities: this provider accepts agent route options but rejects structured output, depth caps, tool filters, and personas rather than silently omitting them.
|
|
22
33
|
|
|
23
|
-
The provider advertises
|
|
34
|
+
The provider advertises `agentOptions: true`, with `outputSchema`/`depthLimit`/`toolFilter`/`persona` false, and `inheritsParentContext: false`. Its immutable `agentRouteDefaults` publish the configured provider/model baseline to `dsh-tool-subagent` before model overrides and exact-route preflight; `start()` independently applies the same configuration defaults for direct callers and `maxTokens`. Agent route values cross the SDK wire as an explicit whitelist; the child remains a fresh runtime in another process, and the only value derived from the parent agent itself is the workspace cwd. `dsh-tool-subagent` deployments over this provider set `maxDepth: 'provider-managed'` — the child harness owns its own recursion budget.
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
### Configuration
|
|
26
37
|
|
|
27
|
-
|
|
|
38
|
+
| Field | Default | Meaning |
|
|
28
39
|
|---|---|---|
|
|
29
|
-
| `providerName` | `dsh-sdk` | Registry name on `ctx.subagents
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
+
| `providerName` | `dsh-sdk` | Registry name on `ctx.subagents` |
|
|
41
|
+
| `dshBin` | SDK dependency | Explicit dsh CLI module, resolved and checked at plugin load; omission uses the SDK dependency |
|
|
42
|
+
| `profile` | `sdk` | Named child profile |
|
|
43
|
+
| `patches` | `[]` | Ordered per-launch profile patch files, resolved and checked at plugin load |
|
|
44
|
+
| `dshHome` | required | Absolute isolated Harness home for every nested child process |
|
|
45
|
+
| `cwd` | parent session cwd | Working-directory override for the child process and its SDK session |
|
|
46
|
+
| `provider` | `deepseek-official` | Provider route sent in the child's `initialize` |
|
|
47
|
+
| `model` | `deepseek-v4-flash` | Model sent in the child's `initialize` |
|
|
48
|
+
| `maxTokens` | adapter/provider route default | Per-request output-token cap sent in the child's `initialize` |
|
|
49
|
+
| `env` | `{}` | Explicit child environment layered over the credential-scrubbed parent environment |
|
|
50
|
+
| `shutdownTimeoutMs` | `1000` | Bound on the protocol `shutdown` exchange during dispose |
|
|
51
|
+
| `disposeEofGraceMs` | `6000` | Grace after stdin EOF before platform termination |
|
|
52
|
+
| `disposeGraceMs` | `3000` | Exit-confirmation grace after termination |
|
|
53
|
+
|
|
54
|
+
The generated [configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-subagent-dsh-sdk) is the exhaustive source for every accepted field and its JSDoc.
|
|
55
|
+
|
|
56
|
+
Request `agentOptions` override `provider`, `model`, and `maxTokens` independently. `reasoningEffort` has no provider-instance default: an omitted request leaves it absent so the selected child model resolves its own default. The model-facing subagent tool can select provider/model/reasoning per call; `maxTokens` remains deployment-controlled through tool config or this provider's default.
|
|
40
57
|
|
|
41
58
|
```yaml
|
|
42
59
|
- id: subagent-dsh-sdk
|
|
43
60
|
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
|
|
44
61
|
config:
|
|
45
62
|
providerName: dsh-sdk
|
|
46
|
-
|
|
47
|
-
|
|
63
|
+
profile: sdk
|
|
64
|
+
patches: ['./profiles/research-child.cordis.yml']
|
|
65
|
+
dshHome: !!js dshHomePath('children')
|
|
48
66
|
maxTokens: 49152
|
|
49
67
|
env:
|
|
50
68
|
DEEPSEEK_API_KEY: !!js process.env.DEEPSEEK_API_KEY
|
|
@@ -53,19 +71,74 @@ The provider advertises no start-time capabilities (`outputSchema`/`depthLimit`/
|
|
|
53
71
|
config: { provider: dsh-sdk, toolName: subagent, maxDepth: 'provider-managed' }
|
|
54
72
|
```
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
### What you get
|
|
75
|
+
|
|
76
|
+
A successful run returns the child's final assistant text (or accumulated partial text after cancellation) as result output. The child's model route, tools, and session come from the child runtime itself — the parent supplies the task, working directory, and `initialize` route. The child's last durable `turn/end` maps into the seam vocabulary: `completed` and `max-tokens` pass through, `blocked` becomes `refusal`, and an unexpected or missing terminal becomes `error`. An `aborted` result stays aborted; only a child-side `disposed` cause adds a `child-disposed` diagnostic.
|
|
77
|
+
|
|
78
|
+
### Failure and recovery
|
|
79
|
+
|
|
80
|
+
An already-aborted request fails before path resolution or spawn. A route, spawn, handshake, or pre-publication cancellation failure ordinarily rejects only after the subprocess is reaped. If initialization and cleanup both fail, the ordered safe facts preserve both failures without claiming quiescence. A child runtime that fails after publication settles through the run rather than rejecting it; partial output stays separate from the safe diagnostic. Diagnostics expose only the provider plus `initialize`, `session-run`, or `shutdown` stage and a fixed category. They never copy SDK messages, stderr, paths, task content, environment values, credentials, or protocol payloads.
|
|
81
|
+
|
|
82
|
+
-----
|
|
83
|
+
|
|
84
|
+
<a id="understand-the-implementation"></a>
|
|
85
|
+
## Understand the implementation
|
|
86
|
+
|
|
87
|
+
<details>
|
|
88
|
+
<summary>Implementation internals — click to expand</summary>
|
|
89
|
+
|
|
90
|
+
This section explains how the backend drives a child Harness runtime and where the observable behavior comes from; the full contract lives in [Use this package](#use-this-package).
|
|
91
|
+
|
|
92
|
+
### Design concept
|
|
93
|
+
|
|
94
|
+
- **Full harness peer.** Each child is a complete Harness runtime in its own process — own composition, session, model route, and tools; only the resolved working directory and the `initialize` route cross from the parent.
|
|
95
|
+
- **One runtime per run.** Every run spawns a fresh runtime process; there is no pooling.
|
|
96
|
+
- **The JSON-RPC wire is the serialization boundary.** Same-process subagent values are not defensively cloned; the protocol is where hostile input is validated.
|
|
97
|
+
|
|
98
|
+
### Source map
|
|
99
|
+
|
|
100
|
+
| File | Role |
|
|
101
|
+
|---|---|
|
|
102
|
+
| [`src/index.ts`](src/index.ts) | Plugin entry: config schema, provider registration |
|
|
103
|
+
| [`src/run.ts`](src/run.ts) | The SDK run lifecycle, answer extraction, and stop-reason mapping |
|
|
104
|
+
|
|
105
|
+
### Run flow
|
|
106
|
+
|
|
107
|
+
A start resolves the child's working directory and one process-wide SDK route before spawning. Each declared `request.agentOptions` field (`provider`, `model`, `reasoningEffort`, or `maxTokens`) overrides the matching provider-instance default; omission preserves the configured provider/model and optional cap, while reasoning effort remains absent unless the request supplies it. The provider spawns the runtime through the SDK client and completes the `initialize` handshake, including exact-model and effort validation, before it fulfills. A route, spawn, handshake, or pre-publication cancellation failure rejects only after the subprocess is reaped; a working-directory resolution failure rejects before spawning. After publication the provider owns one SDK activity and reads the child's answer from its session events: the last complete non-empty `assistant/message` (an empty-content message that records usage is skipped), or the accumulated `text-delta` stream when no such message exists. Disposal is idempotent: it settles the result locally as `aborted`, sends a bounded protocol `shutdown` request, then escalates through stdin EOF → SIGTERM → SIGKILL to actual exit.
|
|
108
|
+
|
|
109
|
+
### Stop-reason mapping
|
|
57
110
|
|
|
58
|
-
The child
|
|
111
|
+
The child's last `turn/end` reason maps into the shared stop-reason vocabulary in [`src/run.ts`](src/run.ts).
|
|
59
112
|
|
|
60
|
-
|
|
113
|
+
### Process boundary
|
|
61
114
|
|
|
115
|
+
The child environment is the subprocess seam's credential-scrubbed parent environment with explicit `config.env` values merged after the scrub. The child is spawned by the SDK client rather than through `ctx.subprocess` — the documented exception for SDK-managed transports — which is why this backend applies the scrub itself.
|
|
116
|
+
|
|
117
|
+
</details>
|
|
118
|
+
|
|
119
|
+
-----
|
|
120
|
+
|
|
121
|
+
<a id="further-exploration"></a>
|
|
122
|
+
## Further Exploration
|
|
123
|
+
|
|
124
|
+
Read these pages when the package-level contract is not enough. They move from this backend to the seam it plugs into and the SDK it drives.
|
|
125
|
+
|
|
126
|
+
- [Subagent subsystem](../../../docs/subsystems/subagent.md) — the service contract, provider contract, and terminal result semantics.
|
|
127
|
+
- [dsh-subagent seam](../subagent/README.md) — the registry and start API this provider registers on.
|
|
128
|
+
- [ACP subagent backend](../subagent-acp/README.md) — the sibling out-of-process provider over the Agent Client Protocol.
|
|
129
|
+
- [TypeScript SDK client](../../sdk/client/README.md) — the stdio JSON-RPC client this backend drives the child through.
|
|
130
|
+
- [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-subagent-dsh-sdk) — every accepted config field and its source declaration.
|
|
131
|
+
|
|
132
|
+
-----
|
|
133
|
+
|
|
134
|
+
<a id="model-experience"></a>
|
|
62
135
|
## Model Experience
|
|
63
136
|
|
|
64
137
|
### Child-agent request
|
|
65
138
|
|
|
66
139
|
#### What the model sees
|
|
67
140
|
|
|
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.
|
|
141
|
+
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. A parent tool call may choose the child provider, model, and reasoning effort for this run; the selected route and any deployment-owned output cap are fixed for the new child process. Persona, tool filtering, depth enforcement, and structured output remain unsupported and are rejected instead of silently omitted.
|
|
69
142
|
|
|
70
143
|
#### Token effect
|
|
71
144
|
|
|
@@ -79,7 +152,7 @@ Independent of the parent request cache. Each SDK child can reuse only prefixes
|
|
|
79
152
|
|
|
80
153
|
#### What the model sees
|
|
81
154
|
|
|
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.
|
|
155
|
+
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. A diagnostic-bearing non-completed result presents the safe diagnostic before separately preserved partial assistant output; startup and shutdown errors expose the same fixed facts without raw SDK text.
|
|
83
156
|
|
|
84
157
|
#### Token effect
|
|
85
158
|
|
|
@@ -91,7 +164,25 @@ Append-only; newly visible content follows the reusable request prefix and does
|
|
|
91
164
|
|
|
92
165
|
## Known Limitations and Deferred Work
|
|
93
166
|
|
|
167
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
These limits define when this backend is a poor fit or needs special operational care. They are current package constraints, not a general SDK comparison or a task backlog.
|
|
171
|
+
|
|
94
172
|
- **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
|
|
96
|
-
- **The child's transcript stays in the child's own session root** — the parent log records only the delegation tool call
|
|
97
|
-
- **Local child processes only** — the resolved
|
|
173
|
+
- **No non-route start-time capabilities** — the parent can select the child agent route but cannot enforce `outputSchema`, depth, tool filters, or persona inside the child process; configure the selected child profile and its ordered patches instead.
|
|
174
|
+
- **The child's transcript stays in the child's own session root** — the parent log records only the delegation tool call and result; the streamed `session.event` channel is consumed for output extraction, not bridged into the parent log.
|
|
175
|
+
- **Local child processes only** — the resolved working directory is a local path; a remote runtime would need its own backend.
|
|
176
|
+
|
|
177
|
+
<a id="dev-note"></a>
|
|
178
|
+
### Dev Note
|
|
179
|
+
|
|
180
|
+
<details>
|
|
181
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
182
|
+
|
|
183
|
+
This Dev Note is working context for maintainers: open questions and undecided directions. It is explicitly non-authoritative — shipped behavior and limits live in the sections above and in the package code.
|
|
184
|
+
|
|
185
|
+
- **Spawn cost** — the full plugin tree per run is the price of full isolation; pooling would change that trade-off.
|
|
186
|
+
- **Remote runtimes** — a remote runtime would need its own backend and workspace mapping.
|
|
187
|
+
|
|
188
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,50 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向用户与维护者的进程外 SDK subagent 后端,用于选择委派提供方、配置子 Harness 运行时命令或排查远程子 agent 运行问题。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @deepseek-ai/dsh-subagent-dsh-sdk
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
`dsh-subagent-dsh-sdk` 在全新的子进程中把每个被委派的子 agent(智能体)作为完整的 DeepSeek Harness 运行时运行,并经由 TypeScript SDK 客户端通过 stdio JSON-RPC 驱动。它是 ACP 提供方之外的第二个进程外后端,差异在协议格式(wire format)与子进程约定:子进程是完整的对等 harness,拥有由 `cordis.yml` 决定的组合、会话持久化、模型路由与工具。每次运行都会 spawn 子运行时(Node 下解析出的 `@deepseek-ai/dsh` CLI,或配置的 `dshBin`),以配置的提供方与模型路由完成 `initialize` 握手、提交任务,并从子进程的会话事件中读取答案。父级只收到子进程最终的 assistant 文本或安全错误——中间消息与工具流量不会跨越边界。当子进程应该是与父 harness 完全隔离的真实 Harness 运行时时,选择它。
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
## 目录
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
12
22
|
|
|
13
|
-
|
|
23
|
+
-----
|
|
14
24
|
|
|
15
|
-
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
当委派应以完整 Harness 运行时在独立进程中运行时,挂载本提供方。常用路径是显式的:挂载 seam、挂载本提供方,并给出一个启动带有自身 `cordis.yml` 的 SDK 运行时的命令。
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
### 何时选择
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
当子进程必须是完整的 harness 对等体——拥有自己的组合、会话持久化、模型路由与工具——而不是共享父进程的 agent 时,选择此后端。当子进程必须共享父级组合或遵守父级强制的非路由能力时,请选择进程内后端:本提供方接受 agent 路由选项,但会拒绝结构化输出、深度上限、工具过滤或 persona,而不是静默省略。
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
提供方声明 `agentOptions: true`,同时保持 `outputSchema`/`depthLimit`/`toolFilter`/`persona` 为 false,并且 `inheritsParentContext: false`。不可变的 `agentRouteDefaults` 会在模型覆盖与确切路由预检前,把配置的 provider/model 基线公开给 `dsh-tool-subagent`;`start()` 则为直接调用方与 `maxTokens` 独立应用同一份配置默认值。Agent 路由值通过显式白名单跨越 SDK 协议;子进程仍是另一进程里的全新运行时,唯一从父 agent 本身派生的值是工作区 cwd。基于本提供方的 `dsh-tool-subagent` 部署应设置 `maxDepth: 'provider-managed'`——子 harness 拥有自己的递归预算。
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
### 配置
|
|
26
37
|
|
|
27
|
-
|
|
|
38
|
+
| 字段 | 默认值 | 含义 |
|
|
28
39
|
|---|---|---|
|
|
29
|
-
| `providerName` | `dsh-sdk` | `ctx.subagents`
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
+
| `providerName` | `dsh-sdk` | `ctx.subagents` 上的注册表名称 |
|
|
41
|
+
| `dshBin` | SDK 依赖 | 显式 dsh CLI 模块,在插件加载时解析并校验;省略则使用 SDK 依赖 |
|
|
42
|
+
| `profile` | `sdk` | 子进程命名的 profile |
|
|
43
|
+
| `patches` | `[]` | 每次启动的有序 profile patch 文件,在插件加载时解析并校验 |
|
|
44
|
+
| `dshHome` | 必填 | 每个嵌套子进程的绝对隔离 Harness home |
|
|
45
|
+
| `cwd` | 父会话 cwd | 子进程及其 SDK 会话的工作目录覆盖值 |
|
|
46
|
+
| `provider` | `deepseek-official` | 写入子进程 `initialize` 的提供方路由 |
|
|
47
|
+
| `model` | `deepseek-v4-flash` | 写入子进程 `initialize` 的模型 |
|
|
48
|
+
| `maxTokens` | 适配器/提供方路由默认值 | 写入子进程 `initialize` 的单次请求输出 token 上限 |
|
|
49
|
+
| `env` | `{}` | 叠加在已清理凭据的父环境之上的显式子环境 |
|
|
50
|
+
| `shutdownTimeoutMs` | `1000` | dispose 期间协议 `shutdown` 交换的时限 |
|
|
51
|
+
| `disposeEofGraceMs` | `6000` | stdin EOF 之后、平台终止之前的宽限 |
|
|
52
|
+
| `disposeGraceMs` | `3000` | 终止后的退出确认宽限 |
|
|
53
|
+
|
|
54
|
+
生成的[配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-subagent-dsh-sdk)是每个受支持字段及其 JSDoc 的穷尽式真源。
|
|
55
|
+
|
|
56
|
+
请求 `agentOptions` 会分别覆盖 `provider`、`model` 与 `maxTokens`。`reasoningEffort` 没有提供方实例默认值:请求省略时保持缺省,由所选子模型解析自身默认值。面向模型的 subagent 工具可在每次调用时选择提供方/模型/推理强度;`maxTokens` 仍由工具配置或本提供方默认值在部署侧控制。
|
|
40
57
|
|
|
41
58
|
```yaml
|
|
42
59
|
- id: subagent-dsh-sdk
|
|
43
60
|
name: '@deepseek-ai/dsh-subagent-dsh-sdk'
|
|
44
61
|
config:
|
|
45
62
|
providerName: dsh-sdk
|
|
46
|
-
|
|
47
|
-
|
|
63
|
+
profile: sdk
|
|
64
|
+
patches: ['./profiles/research-child.cordis.yml']
|
|
65
|
+
dshHome: !!js dshHomePath('children')
|
|
48
66
|
maxTokens: 49152
|
|
49
67
|
env:
|
|
50
68
|
DEEPSEEK_API_KEY: !!js process.env.DEEPSEEK_API_KEY
|
|
@@ -53,19 +71,74 @@ Provider 不宣告任何启动期能力(`outputSchema`/`depthLimit`/`toolFilte
|
|
|
53
71
|
config: { provider: dsh-sdk, toolName: subagent, maxDepth: 'provider-managed' }
|
|
54
72
|
```
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
### 你会得到什么
|
|
75
|
+
|
|
76
|
+
成功的运行会把子进程最终的 assistant 文本(或取消后累积的部分文本)作为结果输出返回。子进程的模型路由、工具与会话来自子运行时自身——父级提供任务、工作目录与 `initialize` 路由。子进程最后一个持久化 `turn/end` 会映射进 seam 词汇:`completed` 与 `max-tokens` 原样通过,`blocked` 变为 `refusal`,意外终态或缺少终态变为 `error`。`aborted` 结果保持中止;只有子进程侧 `disposed` 原因会附加 `child-disposed` 诊断。
|
|
77
|
+
|
|
78
|
+
### 失败与恢复
|
|
79
|
+
|
|
80
|
+
已取消的请求会在路径解析或 spawn 之前失败。路由、spawn、握手或发布前取消失败通常只在子进程被回收后拒绝;如果初始化与清理均失败,有序安全事实会保留两项失败,而不会宣称已完全停稳。子运行时在发布后失败时会通过运行本身结算,而不是拒绝;部分输出与安全诊断保持分离。诊断只公开提供方、`initialize`、`session-run` 或 `shutdown` 阶段,以及固定类别。SDK 消息、stderr、路径、任务内容、环境值、凭据和协议载荷绝不会复制到诊断中。
|
|
81
|
+
|
|
82
|
+
-----
|
|
83
|
+
|
|
84
|
+
<a id="understand-the-implementation"></a>
|
|
85
|
+
## 理解实现
|
|
86
|
+
|
|
87
|
+
<details>
|
|
88
|
+
<summary>实现细节——点击展开</summary>
|
|
89
|
+
|
|
90
|
+
本节解释后端如何驱动子 Harness 运行时,以及可观察行为从何而来;完整约定见[使用本包](#use-this-package)。
|
|
91
|
+
|
|
92
|
+
### 设计理念
|
|
93
|
+
|
|
94
|
+
- **完整 harness 对等体。** 每个子进程都是独立进程中的完整 Harness 运行时——拥有自己的组合、会话、模型路由与工具;只有解析后的工作目录与 `initialize` 路由从父级跨越。
|
|
95
|
+
- **每次运行一个运行时。** 每次运行都 spawn 全新运行时进程;没有进程池。
|
|
96
|
+
- **JSON-RPC 协议格式是序列化边界。** 同进程 subagent 值不会为防御目的克隆;协议才是校验不可信输入的地方。
|
|
97
|
+
|
|
98
|
+
### 源码地图
|
|
99
|
+
|
|
100
|
+
| 文件 | 职责 |
|
|
101
|
+
|---|---|
|
|
102
|
+
| [`src/index.ts`](src/index.ts) | 插件入口:config schema、提供方注册 |
|
|
103
|
+
| [`src/run.ts`](src/run.ts) | SDK 运行生命周期、答案提取与停止原因映射 |
|
|
104
|
+
|
|
105
|
+
### 运行流程
|
|
106
|
+
|
|
107
|
+
一次启动会在 spawn 前解析子进程工作目录与一条进程级 SDK 路由。`request.agentOptions` 中每个已声明字段(`provider`、`model`、`reasoningEffort` 或 `maxTokens`)都会覆盖对应的提供方实例默认值;省略时保留已配置的提供方/模型与可选上限,而推理强度只有在请求提供时才会出现。随后,提供方通过 SDK 客户端 spawn 运行时,并在履行前完成 `initialize` 握手,其中包括确切模型与推理强度校验。路由、spawn、握手或发布前取消失败时,只会在子进程被回收后拒绝;工作目录解析失败则会在尚未 spawn 任何内容时拒绝。发布后,提供方拥有一段 SDK 活动,并从子会话事件中读取答案:最后一条完整且非空的 `assistant/message`(记录 usage 的空内容消息会被跳过);若没有这类消息,则取累积的 `text-delta` 流。dispose(资源释放)是幂等的:先在本地把结果确定为 `aborted`,发出有界的协议 `shutdown` 请求,再经 stdin EOF → SIGTERM → SIGKILL 升级到实际退出。
|
|
108
|
+
|
|
109
|
+
### 停止原因映射
|
|
57
110
|
|
|
58
|
-
|
|
111
|
+
子进程最后一个 `turn/end` 的原因会映射进共享的停止原因词汇,实现见 [`src/run.ts`](src/run.ts)。
|
|
59
112
|
|
|
60
|
-
|
|
113
|
+
### 进程边界
|
|
61
114
|
|
|
115
|
+
子进程环境以子进程 seam 的已清理凭据父环境为基础,并在清除之后合并显式 `config.env` 值。子进程由 SDK 客户端 spawn,而不是经由 `ctx.subprocess`——这是 SDK 托管传输的文档化例外——因此本后端会自行执行环境清理。
|
|
116
|
+
|
|
117
|
+
</details>
|
|
118
|
+
|
|
119
|
+
-----
|
|
120
|
+
|
|
121
|
+
<a id="further-exploration"></a>
|
|
122
|
+
## 进一步探索
|
|
123
|
+
|
|
124
|
+
当包级约定不够用时阅读以下页面。它们从本后端逐步进入它接入的 seam 与它驱动的 SDK。
|
|
125
|
+
|
|
126
|
+
- [Subagent 子系统](../../../docs/subsystems/subagent.zh.md)——服务约定、提供方约定与终态结果语义。
|
|
127
|
+
- [dsh-subagent seam](../subagent/README.zh.md)——本提供方注册于其上的注册表与启动 API。
|
|
128
|
+
- [ACP subagent 后端](../subagent-acp/README.zh.md)——经 Agent Client Protocol 的兄弟进程外提供方。
|
|
129
|
+
- [TypeScript SDK 客户端](../../sdk/client/README.zh.md)——本后端用以驱动子进程的 stdio JSON-RPC 客户端。
|
|
130
|
+
- [生成配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-subagent-dsh-sdk)——每个受支持配置字段及其源声明。
|
|
131
|
+
|
|
132
|
+
-----
|
|
133
|
+
|
|
134
|
+
<a id="model-experience"></a>
|
|
62
135
|
## 模型体验
|
|
63
136
|
|
|
64
137
|
### 子 agent 请求
|
|
65
138
|
|
|
66
|
-
####
|
|
139
|
+
#### 模型看到什么
|
|
67
140
|
|
|
68
|
-
|
|
141
|
+
子运行时的模型会收到作为用户消息的独立任务,以及该运行时自身配置的系统提示词、工具和全新会话。它不会收到父级对话。父级工具调用可以为本次运行选择子级提供方、模型与推理强度;所选路由和部署持有的可选输出上限会固定到这个新子进程。persona、工具过滤、深度强制与结构化输出仍不受支持,并会被拒绝而不是静默省略。
|
|
69
142
|
|
|
70
143
|
#### Token 影响
|
|
71
144
|
|
|
@@ -77,9 +150,9 @@ Provider 不宣告任何启动期能力(`outputSchema`/`depthLimit`/`toolFilte
|
|
|
77
150
|
|
|
78
151
|
### 父级工具结果(间接)
|
|
79
152
|
|
|
80
|
-
####
|
|
153
|
+
#### 模型看到什么
|
|
81
154
|
|
|
82
|
-
经由 `dsh-tool-subagent`,父级只会收到子运行时最终的 assistant
|
|
155
|
+
经由 `dsh-tool-subagent`,父级只会收到子运行时最终的 assistant 文本(或累积的部分文本),或该消费方给出的精确停止原因错误;不会收到中间消息或工具流量。带诊断的非完成结果会先呈现安全诊断,再单独呈现保留的部分 assistant 输出;启动与 shutdown 错误使用同一固定事实,不公开原始 SDK 文本。
|
|
83
156
|
|
|
84
157
|
#### Token 影响
|
|
85
158
|
|
|
@@ -89,9 +162,27 @@ Provider 不宣告任何启动期能力(`outputSchema`/`depthLimit`/`toolFilte
|
|
|
89
162
|
|
|
90
163
|
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
|
91
164
|
|
|
92
|
-
##
|
|
165
|
+
## 已知限制与延期工作
|
|
166
|
+
|
|
167
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
这些限制说明本后端何时不合适,或何时需要特别的运维注意。它们是当前包约束,不是通用 SDK 对比或任务积压。
|
|
171
|
+
|
|
172
|
+
- **每次运行都使用全新的运行时进程**——不使用进程池;harness 运行时需要启动完整的插件树,因此每次运行的 spawn 成本高于 ACP 后端通常使用的子进程。
|
|
173
|
+
- **不支持路由之外的启动时能力**——父级可以选择子 agent 路由,但无法在子进程内强制执行 `outputSchema`、深度限制、工具过滤或 persona;应改为配置所选子 profile 及其有序 patch。
|
|
174
|
+
- **子进程的 transcript(文本记录)保留在其自身的会话根目录中**——父级日志只记录委派工具调用与结果;流式会话事件通道只用于提取输出,不会桥接到父级日志中。
|
|
175
|
+
- **仅支持本地子进程**——解析出的工作目录是本地路径;远程运行时需要独立的后端。
|
|
176
|
+
|
|
177
|
+
<a id="dev-note"></a>
|
|
178
|
+
### 开发备注
|
|
179
|
+
|
|
180
|
+
<details>
|
|
181
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
182
|
+
|
|
183
|
+
本开发备注是维护者的工作上下文:开放问题与尚未决定的探索方向。它明确不具权威性——已交付的行为与限制以上文和包代码为准。
|
|
184
|
+
|
|
185
|
+
- **Spawn 成本**——每次运行加载完整插件树是彻底隔离的代价;池化会改变这一权衡。
|
|
186
|
+
- **远程运行时**——远程运行时需要独立的后端与工作区映射。
|
|
93
187
|
|
|
94
|
-
|
|
95
|
-
- **不支持可选的启动时能力**:父级无法在子进程内强制执行 `outputSchema`、深度限制、工具过滤或 persona;应改为配置子进程自身的 `cordis.yml`。
|
|
96
|
-
- **子进程的 transcript(文本记录)保留在其自身的会话根目录中**:父级日志只记录委派工具调用/结果(seam 的子级隔离规则);流式 `session.event` 通道只用于提取输出,不会桥接到父级日志中。
|
|
97
|
-
- **仅支持本地子进程**:解析出的 cwd 是本地路径;远程运行时需要独立的后端。
|
|
188
|
+
</details>
|
package/lib/index.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, resolve } from "node:path";
|
|
1
3
|
import z from "@deepseek-ai/schemastery";
|
|
2
4
|
import { AssistantOutputFold, NO_START_CAPABILITIES, assertPositiveFinite, resolveChildCwd, settleRunResult, subprocessRunHandle, validateConfiguredCwd } from "@deepseek-ai/dsh-subagent";
|
|
3
5
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
+
import { brandString } from "@deepseek-ai/dsh-brand";
|
|
7
|
+
import { DeepSeekHarness, JsonRpcResponseError, SdkProtocolError, TransportClosedError } from "@deepseek-ai/dsh-sdk-client";
|
|
6
8
|
import { scrubbedParentEnv } from "@deepseek-ai/dsh-subprocess";
|
|
7
9
|
//#region lib/types/run.js
|
|
8
10
|
/**
|
|
9
11
|
* Fresh-process SDK subagent client. Drives one child DeepSeek Harness
|
|
10
12
|
* runtime over stdio JSON-RPC through `@deepseek-ai/dsh-sdk-client` and owns
|
|
11
|
-
* cancellation and quiescent disposal.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* the
|
|
16
|
-
* so this driver applies the seam's shared env scrub itself.
|
|
13
|
+
* cancellation and quiescent disposal. It publishes after the child
|
|
14
|
+
* handshake, maps child failures to stop reasons, and tears down to
|
|
15
|
+
* quiescence. The SDK client spawns the child rather than using
|
|
16
|
+
* `ctx.subprocess` — the subprocess seam's documented exception for
|
|
17
|
+
* SDK-managed transports — so this driver applies the seam's shared env scrub.
|
|
17
18
|
*
|
|
18
19
|
* @module @deepseek-ai/dsh-subagent-dsh-sdk/run
|
|
19
20
|
*/
|
|
@@ -23,19 +24,88 @@ const DEFAULT_DISPOSE_EOF_GRACE_MS = 6e3;
|
|
|
23
24
|
const DEFAULT_DISPOSE_GRACE_MS = 3e3;
|
|
24
25
|
/** Default bound on the protocol `shutdown` exchange during dispose. */
|
|
25
26
|
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 1e3;
|
|
27
|
+
/** Fixed safe failure text derived only from provider-owned structured facts. */
|
|
28
|
+
function failureDiagnostic(facts) {
|
|
29
|
+
return `Subagent failure (${[
|
|
30
|
+
"provider: DSH SDK",
|
|
31
|
+
`stage: ${facts.stage}`,
|
|
32
|
+
`category: ${facts.category}`
|
|
33
|
+
].join("; ")})`;
|
|
34
|
+
}
|
|
35
|
+
var SdkRunFailure = class extends Error {
|
|
36
|
+
facts;
|
|
37
|
+
constructor(facts, cause) {
|
|
38
|
+
super(`subagent-dsh-sdk: ${failureDiagnostic(facts)}`, { cause });
|
|
39
|
+
this.facts = facts;
|
|
40
|
+
this.name = "SdkRunFailure";
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/** Runtime constructor seam replaced only by package-local fake-runtime tests. */
|
|
44
|
+
const internals = { createHarness: (options) => new DeepSeekHarness(options) };
|
|
26
45
|
/**
|
|
27
|
-
*
|
|
46
|
+
* Hide a pre-spawn workspace/configuration failure behind fixed safe facts.
|
|
47
|
+
* @param cause - original Host failure retained on the Error cause chain.
|
|
48
|
+
* @returns an Error whose message contains only the fixed DSH SDK failure line.
|
|
49
|
+
*/
|
|
50
|
+
function sdkConfigurationFailure(cause) {
|
|
51
|
+
return new SdkRunFailure({
|
|
52
|
+
stage: "initialize",
|
|
53
|
+
category: "configuration"
|
|
54
|
+
}, cause);
|
|
55
|
+
}
|
|
56
|
+
/** Classify one SDK rejection without reading its message or stderr tail. */
|
|
57
|
+
function sdkFailure(error, stage) {
|
|
58
|
+
return new SdkRunFailure(error instanceof TransportClosedError ? {
|
|
59
|
+
stage,
|
|
60
|
+
category: "transport"
|
|
61
|
+
} : error instanceof SdkProtocolError || error instanceof JsonRpcResponseError ? {
|
|
62
|
+
stage,
|
|
63
|
+
category: "protocol"
|
|
64
|
+
} : {
|
|
65
|
+
stage,
|
|
66
|
+
category: "unknown"
|
|
67
|
+
}, error);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Map one child terminal reason to its complete shared result outcome.
|
|
28
71
|
* @param reason - the owned child run's final durable turn reason, or
|
|
29
72
|
* `undefined` when it settled without running a turn.
|
|
30
|
-
* @returns the
|
|
31
|
-
* `error`, so an unclean stop is never reported as `completed`.
|
|
73
|
+
* @returns the shared stop reason and any additional safe diagnostic.
|
|
32
74
|
*/
|
|
33
|
-
function
|
|
75
|
+
function sdkChildOutcome(reason) {
|
|
34
76
|
switch (reason?.kind) {
|
|
35
|
-
case "completed": return "completed";
|
|
36
|
-
case "max-tokens": return "max-tokens";
|
|
37
|
-
case "aborted": return "
|
|
38
|
-
|
|
77
|
+
case "completed": return { stopReason: "completed" };
|
|
78
|
+
case "max-tokens": return { stopReason: "max-tokens" };
|
|
79
|
+
case "aborted": return reason.reason.kind === "disposed" ? {
|
|
80
|
+
stopReason: "aborted",
|
|
81
|
+
diagnostic: failureDiagnostic({
|
|
82
|
+
stage: "session-run",
|
|
83
|
+
category: "child-disposed"
|
|
84
|
+
})
|
|
85
|
+
} : { stopReason: "aborted" };
|
|
86
|
+
case "blocked": return { stopReason: "refusal" };
|
|
87
|
+
case "error": return {
|
|
88
|
+
stopReason: "error",
|
|
89
|
+
diagnostic: failureDiagnostic({
|
|
90
|
+
stage: "session-run",
|
|
91
|
+
category: "child-error"
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
case "interrupted": return { stopReason: "error" };
|
|
95
|
+
case void 0: return {
|
|
96
|
+
stopReason: "error",
|
|
97
|
+
diagnostic: failureDiagnostic({
|
|
98
|
+
stage: "session-run",
|
|
99
|
+
category: "missing-terminal"
|
|
100
|
+
})
|
|
101
|
+
};
|
|
102
|
+
default: return {
|
|
103
|
+
stopReason: "error",
|
|
104
|
+
diagnostic: failureDiagnostic({
|
|
105
|
+
stage: "session-run",
|
|
106
|
+
category: "child-unknown"
|
|
107
|
+
})
|
|
108
|
+
};
|
|
39
109
|
}
|
|
40
110
|
}
|
|
41
111
|
/** Normalize an unknown thrown value to an Error (the catch binding is `unknown`). */
|
|
@@ -43,34 +113,62 @@ function toError(value) {
|
|
|
43
113
|
/* v8 ignore next */
|
|
44
114
|
return value instanceof Error ? value : new Error(String(value));
|
|
45
115
|
}
|
|
116
|
+
/** Report an original Host failure without letting the observation sink replace it. */
|
|
117
|
+
function reportFailure(spec, error) {
|
|
118
|
+
try {
|
|
119
|
+
spec.onError?.(toError(error), "error");
|
|
120
|
+
} catch {}
|
|
121
|
+
}
|
|
122
|
+
/** Map an SDK-owned failed-start aggregate into safe initialize/shutdown lines. */
|
|
123
|
+
function sdkStartupFailure(spec, error) {
|
|
124
|
+
if (!(error instanceof AggregateError) || error.errors.length < 2) {
|
|
125
|
+
reportFailure(spec, error);
|
|
126
|
+
return sdkFailure(error, "initialize");
|
|
127
|
+
}
|
|
128
|
+
const initializeError = error.errors[0];
|
|
129
|
+
const cleanupError = error.errors[1];
|
|
130
|
+
reportFailure(spec, initializeError);
|
|
131
|
+
reportFailure(spec, cleanupError);
|
|
132
|
+
const initializeFailure = sdkFailure(initializeError, "initialize");
|
|
133
|
+
const cleanupFailure = new SdkRunFailure({
|
|
134
|
+
stage: "shutdown",
|
|
135
|
+
category: "unknown"
|
|
136
|
+
}, cleanupError);
|
|
137
|
+
return new AggregateError([initializeFailure, cleanupFailure], `${initializeFailure.message}; ${cleanupFailure.message}`);
|
|
138
|
+
}
|
|
46
139
|
/**
|
|
47
140
|
* Start and publish one SDK runtime child after its `initialize` handshake.
|
|
48
|
-
* Child failures resolve through the run result
|
|
49
|
-
*
|
|
141
|
+
* Child failures resolve through the run result. Startup rejects with fixed
|
|
142
|
+
* safe facts after SDK-owned cleanup; successful cleanup proves process reap.
|
|
143
|
+
* Cleanup failure preserves initialize plus shutdown for an ordinary failure,
|
|
144
|
+
* or shutdown alone after cancellation, without claiming quiescence. Disposal
|
|
145
|
+
* shuts the runtime down and reaps it.
|
|
50
146
|
* @param request - the start request; its signal is the cancellation channel.
|
|
51
|
-
* @param spec - the resolved spawn spec:
|
|
52
|
-
* provider/model route, env, timeouts, and the optional
|
|
147
|
+
* @param spec - the resolved spawn spec: profile/patches/home/cwd, the child's
|
|
148
|
+
* provider/model/reasoning route, output cap, env, timeouts, and the optional
|
|
149
|
+
* error sink.
|
|
53
150
|
* @returns the ready run handle for the child subprocess.
|
|
54
151
|
*/
|
|
55
152
|
async function startSdkRun(request, spec) {
|
|
56
153
|
if (request.signal.aborted) throw new Error("subagent request was aborted before the SDK child started");
|
|
57
|
-
const id =
|
|
58
|
-
const harness =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
shutdownTimeoutMs: spec.shutdownTimeoutMs,
|
|
68
|
-
disposeEofGraceMs: spec.disposeEofGraceMs,
|
|
69
|
-
disposeGraceMs: spec.disposeGraceMs
|
|
154
|
+
const id = brandString(randomUUID());
|
|
155
|
+
const harness = internals.createHarness({
|
|
156
|
+
...spec.dshBin === void 0 ? {} : { dshBin: spec.dshBin },
|
|
157
|
+
profile: spec.profile,
|
|
158
|
+
patches: spec.patches,
|
|
159
|
+
dshHome: spec.dshHome,
|
|
160
|
+
processCwd: spec.cwd,
|
|
161
|
+
env: {
|
|
162
|
+
...scrubbedParentEnv(),
|
|
163
|
+
...spec.env
|
|
70
164
|
},
|
|
165
|
+
shutdownTimeoutMs: spec.shutdownTimeoutMs,
|
|
166
|
+
disposeEofGraceMs: spec.disposeEofGraceMs,
|
|
167
|
+
disposeGraceMs: spec.disposeGraceMs,
|
|
71
168
|
cwd: spec.cwd,
|
|
72
169
|
provider: spec.provider,
|
|
73
170
|
model: spec.model,
|
|
171
|
+
...spec.reasoningEffort === void 0 ? {} : { reasoningEffort: spec.reasoningEffort },
|
|
74
172
|
...spec.maxTokens === void 0 ? {} : { maxTokens: spec.maxTokens }
|
|
75
173
|
});
|
|
76
174
|
const flags = { cancelled: false };
|
|
@@ -87,17 +185,27 @@ async function startSdkRun(request, spec) {
|
|
|
87
185
|
requestCancel();
|
|
88
186
|
};
|
|
89
187
|
request.signal.addEventListener("abort", onAbort, { once: true });
|
|
188
|
+
const cancelledStartup = /* @__PURE__ */ new Error("subagent cancelled before the SDK child initialized");
|
|
90
189
|
try {
|
|
91
190
|
await Promise.race([harness.start(), cancelSettled.then(() => {
|
|
92
|
-
throw
|
|
191
|
+
throw cancelledStartup;
|
|
93
192
|
})]);
|
|
94
193
|
/* v8 ignore next */
|
|
95
|
-
if (flags.cancelled) throw
|
|
194
|
+
if (flags.cancelled) throw cancelledStartup;
|
|
96
195
|
} catch (error) {
|
|
97
196
|
request.signal.removeEventListener("abort", onAbort);
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
197
|
+
if (error !== cancelledStartup) throw sdkStartupFailure(spec, error);
|
|
198
|
+
try {
|
|
199
|
+
await harness.close();
|
|
200
|
+
} catch (cleanupError) {
|
|
201
|
+
reportFailure(spec, cleanupError);
|
|
202
|
+
const cleanupFailure = new SdkRunFailure({
|
|
203
|
+
stage: "shutdown",
|
|
204
|
+
category: "unknown"
|
|
205
|
+
}, cleanupError);
|
|
206
|
+
throw new AggregateError([cleanupFailure], cleanupFailure.message);
|
|
207
|
+
}
|
|
208
|
+
throw new Error("subagent request was aborted before the SDK child started");
|
|
101
209
|
}
|
|
102
210
|
const childSessionId = `session-${randomUUID().replaceAll("-", "")}`;
|
|
103
211
|
const fold = new AssistantOutputFold();
|
|
@@ -106,22 +214,41 @@ async function startSdkRun(request, spec) {
|
|
|
106
214
|
fold.push(notification.params.event);
|
|
107
215
|
};
|
|
108
216
|
const collectOutput = () => fold.collect() ?? [];
|
|
217
|
+
const teardown = async () => {
|
|
218
|
+
try {
|
|
219
|
+
await harness.close();
|
|
220
|
+
} catch (error) {
|
|
221
|
+
reportFailure(spec, error);
|
|
222
|
+
throw new SdkRunFailure({
|
|
223
|
+
stage: "shutdown",
|
|
224
|
+
category: "unknown"
|
|
225
|
+
}, error);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
let diagnostic;
|
|
109
229
|
return subprocessRunHandle({
|
|
110
230
|
id,
|
|
111
231
|
result: settleRunResult({
|
|
112
232
|
attempt: async () => {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
233
|
+
try {
|
|
234
|
+
const turn = await Promise.race([harness.session(childSessionId).run(request.prompt, { onNotification: observe }), cancelSettled.then(() => "cancelled")]);
|
|
235
|
+
if (turn === "cancelled") return {
|
|
236
|
+
output: collectOutput(),
|
|
237
|
+
stopReason: "aborted"
|
|
238
|
+
};
|
|
239
|
+
const outcome = sdkChildOutcome(turn.events.findLast((event) => event.type === "turn/end")?.data.reason);
|
|
240
|
+
diagnostic = outcome.diagnostic;
|
|
241
|
+
return {
|
|
242
|
+
output: collectOutput(),
|
|
243
|
+
...outcome
|
|
244
|
+
};
|
|
245
|
+
} catch (error) {
|
|
246
|
+
diagnostic = failureDiagnostic(sdkFailure(error, "session-run").facts);
|
|
247
|
+
throw error;
|
|
248
|
+
}
|
|
123
249
|
},
|
|
124
250
|
collectOutput,
|
|
251
|
+
collectDiagnostic: () => diagnostic,
|
|
125
252
|
cancelled: () => flags.cancelled,
|
|
126
253
|
onError: spec.onError,
|
|
127
254
|
signal: request.signal,
|
|
@@ -130,18 +257,19 @@ async function startSdkRun(request, spec) {
|
|
|
130
257
|
signal: request.signal,
|
|
131
258
|
onAbort,
|
|
132
259
|
requestCancel,
|
|
133
|
-
teardown
|
|
260
|
+
teardown
|
|
134
261
|
});
|
|
135
262
|
}
|
|
136
263
|
//#endregion
|
|
137
264
|
//#region lib/types/index.js
|
|
138
265
|
/**
|
|
139
266
|
* Out-of-process SDK subagent backend. Each child is a complete DeepSeek
|
|
140
|
-
* Harness runtime in its own process — own
|
|
267
|
+
* Harness runtime in its own process — own named profile and patch composition,
|
|
141
268
|
* session, model route, and tools — driven over stdio JSON-RPC through the
|
|
142
|
-
* TypeScript SDK client, so it shares no Cordis context
|
|
143
|
-
*
|
|
144
|
-
*
|
|
269
|
+
* TypeScript SDK client, so it shares no Cordis context. It accepts the
|
|
270
|
+
* provider/model/reasoning/maxTokens subset of `agentOptions`; other start
|
|
271
|
+
* features remain unsupported. The ONE thing it reads off `request.parent`
|
|
272
|
+
* is the session's workspace cwd. This plugin uses named
|
|
145
273
|
* exports only; a default would hide its loader metadata (see
|
|
146
274
|
* `docs/postmortem/0001-acp-default-export-drops-inject.md`).
|
|
147
275
|
* @module @deepseek-ai/dsh-subagent-dsh-sdk
|
|
@@ -150,8 +278,10 @@ const name = "subagent-dsh-sdk";
|
|
|
150
278
|
const inject = ["subagents"];
|
|
151
279
|
const Config = z.object({
|
|
152
280
|
providerName: z.string().default("dsh-sdk"),
|
|
153
|
-
|
|
154
|
-
|
|
281
|
+
dshBin: z.string(),
|
|
282
|
+
profile: z.string().default("sdk"),
|
|
283
|
+
patches: z.array(z.string()).default([]),
|
|
284
|
+
dshHome: z.string().required(),
|
|
155
285
|
cwd: z.string(),
|
|
156
286
|
provider: z.string().default("deepseek-official"),
|
|
157
287
|
model: z.string().default("deepseek-v4-flash"),
|
|
@@ -161,30 +291,68 @@ const Config = z.object({
|
|
|
161
291
|
disposeEofGraceMs: z.number().default(DEFAULT_DISPOSE_EOF_GRACE_MS),
|
|
162
292
|
disposeGraceMs: z.number().default(DEFAULT_DISPOSE_GRACE_MS)
|
|
163
293
|
});
|
|
294
|
+
/** Resolve one configured runtime file against the harness launch directory and require a regular file. */
|
|
295
|
+
function resolveConfiguredFile(field, value) {
|
|
296
|
+
const path = resolve(value);
|
|
297
|
+
try {
|
|
298
|
+
if (statSync(path).isFile()) return path;
|
|
299
|
+
} catch {}
|
|
300
|
+
throw new TypeError(`subagent-dsh-sdk ${field} must name an existing file: ${path}`);
|
|
301
|
+
}
|
|
302
|
+
/** DSH SDK can apply Agent route options while the other start features remain child-owned. */
|
|
303
|
+
const SDK_START_CAPABILITIES = Object.freeze({
|
|
304
|
+
...NO_START_CAPABILITIES,
|
|
305
|
+
agentOptions: true
|
|
306
|
+
});
|
|
307
|
+
/** Merge the request's supported route fields over this provider instance's defaults. */
|
|
308
|
+
function resolveSdkRoute(config, requested) {
|
|
309
|
+
const maxTokens = requested?.maxTokens ?? config.maxTokens;
|
|
310
|
+
return {
|
|
311
|
+
provider: requested?.provider ?? config.provider,
|
|
312
|
+
model: requested?.model ?? config.model,
|
|
313
|
+
...requested?.reasoningEffort === void 0 ? {} : { reasoningEffort: requested.reasoningEffort },
|
|
314
|
+
...maxTokens === void 0 ? {} : { maxTokens }
|
|
315
|
+
};
|
|
316
|
+
}
|
|
164
317
|
/**
|
|
165
|
-
* The SDK provider.
|
|
166
|
-
*
|
|
167
|
-
*
|
|
318
|
+
* The SDK provider. It resolves Agent route options into the child runtime's
|
|
319
|
+
* process-wide handshake; output schema, depth, tool filter, and persona stay
|
|
320
|
+
* unsupported because their ownership does not cross this process boundary.
|
|
168
321
|
*/
|
|
169
322
|
var SdkSubagentProvider = class {
|
|
170
323
|
name;
|
|
171
324
|
ctx;
|
|
172
325
|
config;
|
|
173
|
-
capabilities =
|
|
326
|
+
capabilities = SDK_START_CAPABILITIES;
|
|
327
|
+
agentRouteDefaults;
|
|
174
328
|
inheritsParentContext = false;
|
|
175
329
|
constructor(name, ctx, config) {
|
|
176
330
|
this.name = name;
|
|
177
331
|
this.ctx = ctx;
|
|
178
332
|
this.config = config;
|
|
333
|
+
this.agentRouteDefaults = Object.freeze({
|
|
334
|
+
provider: config.provider,
|
|
335
|
+
model: config.model
|
|
336
|
+
});
|
|
179
337
|
}
|
|
180
338
|
start(request) {
|
|
339
|
+
if (request.signal.aborted) throw new Error("subagent request was aborted before the SDK child started");
|
|
340
|
+
let cwd;
|
|
341
|
+
try {
|
|
342
|
+
cwd = resolveChildCwd("subagent-dsh-sdk", this.config.cwd, request.parent.session.header.cwd);
|
|
343
|
+
} catch (error) {
|
|
344
|
+
const failure = sdkConfigurationFailure(error);
|
|
345
|
+
this.ctx.logger.warn(`subagent-dsh-sdk "${this.name}": child start failed: %o`, error);
|
|
346
|
+
throw failure;
|
|
347
|
+
}
|
|
348
|
+
const route = resolveSdkRoute(this.config, request.agentOptions);
|
|
181
349
|
return startSdkRun(request, {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
...
|
|
350
|
+
...this.config.dshBin === void 0 ? {} : { dshBin: this.config.dshBin },
|
|
351
|
+
profile: this.config.profile,
|
|
352
|
+
patches: this.config.patches,
|
|
353
|
+
dshHome: this.config.dshHome,
|
|
354
|
+
cwd,
|
|
355
|
+
...route,
|
|
188
356
|
env: this.config.env,
|
|
189
357
|
shutdownTimeoutMs: this.config.shutdownTimeoutMs,
|
|
190
358
|
disposeEofGraceMs: this.config.disposeEofGraceMs,
|
|
@@ -201,9 +369,15 @@ function apply(ctx, config) {
|
|
|
201
369
|
assertPositiveFinite("subagent-dsh-sdk", "disposeEofGraceMs", resolved.disposeEofGraceMs);
|
|
202
370
|
assertPositiveFinite("subagent-dsh-sdk", "disposeGraceMs", resolved.disposeGraceMs);
|
|
203
371
|
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");
|
|
204
|
-
|
|
205
|
-
const
|
|
372
|
+
if (!isAbsolute(resolved.dshHome)) throw new TypeError("subagent-dsh-sdk dshHome must be an absolute path");
|
|
373
|
+
const launchPaths = {
|
|
206
374
|
...resolved,
|
|
375
|
+
patches: resolved.patches.map((path, index) => resolveConfiguredFile(`patches[${String(index)}]`, path)),
|
|
376
|
+
...resolved.dshBin === void 0 ? {} : { dshBin: resolveConfiguredFile("dshBin", resolved.dshBin) }
|
|
377
|
+
};
|
|
378
|
+
const configuredCwd = validateConfiguredCwd("subagent-dsh-sdk", resolved.cwd);
|
|
379
|
+
const validated = configuredCwd === void 0 ? launchPaths : {
|
|
380
|
+
...launchPaths,
|
|
207
381
|
cwd: configuredCwd
|
|
208
382
|
};
|
|
209
383
|
ctx.subagents.registerProvider(new SdkSubagentProvider(validated.providerName, ctx, validated));
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Out-of-process SDK subagent backend. Each child is a complete DeepSeek
|
|
3
|
-
* Harness runtime in its own process — own
|
|
3
|
+
* Harness runtime in its own process — own named profile and patch composition,
|
|
4
4
|
* session, model route, and tools — driven over stdio JSON-RPC through the
|
|
5
|
-
* TypeScript SDK client, so it shares no Cordis context
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* TypeScript SDK client, so it shares no Cordis context. It accepts the
|
|
6
|
+
* provider/model/reasoning/maxTokens subset of `agentOptions`; other start
|
|
7
|
+
* features remain unsupported. The ONE thing it reads off `request.parent`
|
|
8
|
+
* is the session's workspace cwd. This plugin uses named
|
|
8
9
|
* exports only; a default would hide its loader metadata (see
|
|
9
10
|
* `docs/postmortem/0001-acp-default-export-drops-inject.md`).
|
|
10
11
|
* @module @deepseek-ai/dsh-subagent-dsh-sdk
|
|
@@ -17,10 +18,14 @@ export declare const inject: string[];
|
|
|
17
18
|
export interface Config {
|
|
18
19
|
/** Provider name on `ctx.subagents` (default `dsh-sdk`). */
|
|
19
20
|
providerName: string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
|
|
21
|
+
/** Explicit dsh CLI module, resolved and checked at plugin load; omission uses the SDK dependency. */
|
|
22
|
+
dshBin?: string;
|
|
23
|
+
/** Named child profile (default `sdk`). */
|
|
24
|
+
profile: string;
|
|
25
|
+
/** Ordered per-launch profile patch files, resolved and checked at plugin load. */
|
|
26
|
+
patches: string[];
|
|
27
|
+
/** Absolute isolated Harness home for every nested child process. */
|
|
28
|
+
dshHome: string;
|
|
24
29
|
/**
|
|
25
30
|
* Working directory override for the child process and its SDK session
|
|
26
31
|
* workspace. Must be non-empty; a relative path resolves against the
|
|
@@ -38,8 +43,7 @@ export interface Config {
|
|
|
38
43
|
maxTokens?: number;
|
|
39
44
|
/**
|
|
40
45
|
* Extra environment variables for the child process — e.g. the child
|
|
41
|
-
* runtime's own `DEEPSEEK_API_KEY
|
|
42
|
-
* config. Forwarded on top of a credential-scrubbed copy of the parent
|
|
46
|
+
* runtime's own `DEEPSEEK_API_KEY`. Forwarded on top of a credential-scrubbed copy of the parent
|
|
43
47
|
* env, so an explicit key here reaches the child while ambient secrets do
|
|
44
48
|
* not leak implicitly.
|
|
45
49
|
*/
|
package/lib/types/run.d.ts
CHANGED
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Fresh-process SDK subagent client. Drives one child DeepSeek Harness
|
|
3
3
|
* runtime over stdio JSON-RPC through `@deepseek-ai/dsh-sdk-client` and owns
|
|
4
|
-
* cancellation and quiescent disposal.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* the
|
|
9
|
-
* so this driver applies the seam's shared env scrub itself.
|
|
4
|
+
* cancellation and quiescent disposal. It publishes after the child
|
|
5
|
+
* handshake, maps child failures to stop reasons, and tears down to
|
|
6
|
+
* quiescence. The SDK client spawns the child rather than using
|
|
7
|
+
* `ctx.subprocess` — the subprocess seam's documented exception for
|
|
8
|
+
* SDK-managed transports — so this driver applies the seam's shared env scrub.
|
|
10
9
|
*
|
|
11
10
|
* @module @deepseek-ai/dsh-subagent-dsh-sdk/run
|
|
12
11
|
*/
|
|
13
|
-
import { type
|
|
14
|
-
import type {
|
|
12
|
+
import { DeepSeekHarness, type DeepSeekHarnessOptions } from '@deepseek-ai/dsh-sdk-client';
|
|
13
|
+
import type { ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
14
|
+
import type { TurnEndReason } from '@deepseek-ai/dsh-session';
|
|
15
|
+
import type { SubagentResult, SubagentRun, SubagentStartRequest, SubagentStopReason } from '@deepseek-ai/dsh-subagent';
|
|
15
16
|
/** Resolved spawn spec for an SDK runtime child process (no defaults — see Config). */
|
|
16
17
|
export interface SdkRunSpec {
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
|
|
18
|
+
/** Explicit dsh CLI module; omission resolves the SDK client's same-version dependency. */
|
|
19
|
+
dshBin?: string;
|
|
20
|
+
/** Named child profile. */
|
|
21
|
+
profile: string;
|
|
22
|
+
/** Ordered per-launch profile patch files. */
|
|
23
|
+
patches: string[];
|
|
24
|
+
/** Absolute isolated Harness home for the nested runtime. */
|
|
25
|
+
dshHome: string;
|
|
21
26
|
/**
|
|
22
27
|
* Absolute working directory for the child process AND the workspace cwd
|
|
23
28
|
* of its SDK session. The provider resolves it before this spec exists:
|
|
@@ -28,11 +33,13 @@ export interface SdkRunSpec {
|
|
|
28
33
|
provider: string;
|
|
29
34
|
/** Model the child runtime initializes with. */
|
|
30
35
|
model: string;
|
|
36
|
+
/** Optional adapter-owned reasoning effort sent in the child runtime's initialize handshake. */
|
|
37
|
+
reasoningEffort?: ReasoningEffortId;
|
|
31
38
|
/** Optional per-request output-token cap sent in the child runtime's initialize handshake. */
|
|
32
39
|
maxTokens?: number;
|
|
33
40
|
/**
|
|
34
41
|
* Extra environment variables to ADD for the child (e.g. the child
|
|
35
|
-
* runtime's own `DEEPSEEK_API_KEY
|
|
42
|
+
* runtime's own `DEEPSEEK_API_KEY`). Merged after
|
|
36
43
|
* the seam's `scrubbedParentEnv()` base, so an explicit credential or
|
|
37
44
|
* current `DSH_*` fact survives while ambient namesakes never leak.
|
|
38
45
|
*/
|
|
@@ -44,10 +51,9 @@ export interface SdkRunSpec {
|
|
|
44
51
|
/** Termination confirmation window (ms), including forced exit on every platform. */
|
|
45
52
|
disposeGraceMs: number;
|
|
46
53
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* stop reason directly.
|
|
54
|
+
* Host sink for startup, published-run, or shutdown failures. Model-visible
|
|
55
|
+
* text uses fixed safe facts, while this callback retains the original Error.
|
|
56
|
+
* A throw from the sink itself is contained.
|
|
51
57
|
*/
|
|
52
58
|
onError?: (error: Error, stopReason: SubagentStopReason) => void;
|
|
53
59
|
}
|
|
@@ -57,21 +63,34 @@ export declare const DEFAULT_DISPOSE_EOF_GRACE_MS = 6000;
|
|
|
57
63
|
export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
|
|
58
64
|
/** Default bound on the protocol `shutdown` exchange during dispose. */
|
|
59
65
|
export declare const DEFAULT_SHUTDOWN_TIMEOUT_MS = 1000;
|
|
66
|
+
/** Runtime constructor seam replaced only by package-local fake-runtime tests. */
|
|
67
|
+
export declare const internals: {
|
|
68
|
+
createHarness(options: DeepSeekHarnessOptions): DeepSeekHarness;
|
|
69
|
+
};
|
|
60
70
|
/**
|
|
61
|
-
*
|
|
71
|
+
* Hide a pre-spawn workspace/configuration failure behind fixed safe facts.
|
|
72
|
+
* @param cause - original Host failure retained on the Error cause chain.
|
|
73
|
+
* @returns an Error whose message contains only the fixed DSH SDK failure line.
|
|
74
|
+
*/
|
|
75
|
+
export declare function sdkConfigurationFailure(cause: unknown): Error;
|
|
76
|
+
/**
|
|
77
|
+
* Map one child terminal reason to its complete shared result outcome.
|
|
62
78
|
* @param reason - the owned child run's final durable turn reason, or
|
|
63
79
|
* `undefined` when it settled without running a turn.
|
|
64
|
-
* @returns the
|
|
65
|
-
* `error`, so an unclean stop is never reported as `completed`.
|
|
80
|
+
* @returns the shared stop reason and any additional safe diagnostic.
|
|
66
81
|
*/
|
|
67
|
-
export declare function
|
|
82
|
+
export declare function sdkChildOutcome(reason: TurnEndReason | undefined): Pick<SubagentResult, 'stopReason' | 'diagnostic'>;
|
|
68
83
|
/**
|
|
69
84
|
* Start and publish one SDK runtime child after its `initialize` handshake.
|
|
70
|
-
* Child failures resolve through the run result
|
|
71
|
-
*
|
|
85
|
+
* Child failures resolve through the run result. Startup rejects with fixed
|
|
86
|
+
* safe facts after SDK-owned cleanup; successful cleanup proves process reap.
|
|
87
|
+
* Cleanup failure preserves initialize plus shutdown for an ordinary failure,
|
|
88
|
+
* or shutdown alone after cancellation, without claiming quiescence. Disposal
|
|
89
|
+
* shuts the runtime down and reaps it.
|
|
72
90
|
* @param request - the start request; its signal is the cancellation channel.
|
|
73
|
-
* @param spec - the resolved spawn spec:
|
|
74
|
-
* provider/model route, env, timeouts, and the optional
|
|
91
|
+
* @param spec - the resolved spawn spec: profile/patches/home/cwd, the child's
|
|
92
|
+
* provider/model/reasoning route, output cap, env, timeouts, and the optional
|
|
93
|
+
* error sink.
|
|
75
94
|
* @returns the ready run handle for the child subprocess.
|
|
76
95
|
*/
|
|
77
96
|
export declare function startSdkRun(request: SubagentStartRequest, spec: SdkRunSpec): Promise<SubagentRun>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-subagent-dsh-sdk",
|
|
3
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.1.
|
|
4
|
+
"version": "0.1.2-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,29 +32,40 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@deepseek-ai/
|
|
36
|
-
"@deepseek-ai/dsh-
|
|
37
|
-
"@deepseek-ai/dsh-
|
|
38
|
-
"@deepseek-ai/dsh-
|
|
39
|
-
"@deepseek-ai/dsh-
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/
|
|
42
|
-
"@deepseek-ai/dsh-
|
|
35
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
36
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
|
|
39
|
+
"@deepseek-ai/dsh-sdk-client": "^0.1.2-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
41
|
+
"@deepseek-ai/dsh-subprocess": "^0.1.2-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-subagent": "^0.1.2-alpha.2"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@deepseek-ai/
|
|
45
|
+
"@deepseek-ai/dsh-brand": "^0.1.2-alpha.2",
|
|
46
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
|
-
"@deepseek-ai/cordis
|
|
49
|
-
"@deepseek-ai/
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
49
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
50
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.3",
|
|
51
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-agent-instructions": "^0.1.2-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-agent-spine-demo": "^0.1.2-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-app-boot": "^0.1.2-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
56
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-llm-deepseek": "^0.1.2-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-loader-smoke": "^0.1.2-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-sdk-client": "^0.1.2-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-sdk-protocol": "^0.1.2-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.2-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.2-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.1.2-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-subagent": "^0.1.2-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-subprocess": "^0.1.2-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-tool-subagent": "^0.1.2-alpha.2"
|
|
59
70
|
}
|
|
60
71
|
}
|