@xneog/dsh-tool-subagent 0.1.0 → 0.1.3-alpha.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/README.i18n.yaml +2 -2
- package/README.md +167 -24
- package/README.zh.md +174 -31
- package/lib/index.js +510 -153
- package/lib/invariant.js +34 -5
- package/lib/model-selection-settings.js +94 -0
- package/lib/types/index.d.ts +5 -0
- package/lib/types/list-models.d.ts +10 -0
- package/lib/types/model-selection-settings.d.ts +43 -0
- package/lib/types/model-selection-state.d.ts +48 -0
- package/lib/types/model-selection.d.ts +81 -0
- package/package.json +38 -25
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/tool-subagent/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 18e391739a504c653933199f3213b6fed2729fed
|
|
6
|
+
README.zh.md: 07c9e75cc115995747c91c2acbcf6afd29c89b94
|
package/README.md
CHANGED
|
@@ -1,57 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Model-facing subagent delegation tool for users and maintainers configuring, composing, or debugging delegation over a subagent provider."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @xneog/dsh-tool-subagent
|
|
2
7
|
|
|
3
8
|
English | [中文](README.zh.md)
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-tool-subagent` is the model-facing delegation tool: it turns one configured `ctx.subagents` provider into a tool the agent can call to start a child agent. Changing the provider changes the transport without changing the execution contract, so one composition can expose several delegation tools, each bound to a different backend. Calls wait for the child by default under `one-shot` policy, or start work in the background by default under `continuable` policy, which returns a durable child id the model can message later. An eligible instance can also let the model discover and select the child's LLM provider, model, and reasoning effort. The tool's descriptions adapt to whether the child inherits the parent's completed turns, and failed runs surface as errored tool results rather than partial success.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
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)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Mount one instance per delegation target, each with a distinct `toolName`. The tool exists exactly while its provider does, so sibling load order and provider reloads never strand it.
|
|
29
|
+
|
|
30
|
+
### Minimal configuration
|
|
31
|
+
|
|
32
|
+
Load the subagent service, an in-process or remote backend, and this tool; then name the provider. This composition exposes a `subagent` tool that delegates to the `spawn` backend:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@xneog/dsh-subagent'
|
|
36
|
+
- name: '@xneog/dsh-subagent-spawn-in-process'
|
|
37
|
+
- name: '@xneog/dsh-tool-subagent'
|
|
38
|
+
config:
|
|
39
|
+
provider: spawn
|
|
40
|
+
toolName: subagent
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Field | Default | Meaning |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `provider` | required | Provider name on `ctx.subagents` (e.g. `spawn`, `fork`, `acp`) |
|
|
46
|
+
| `toolName` | `subagent` | Model-facing tool name; distinct for every loaded instance |
|
|
47
|
+
| `modelSelectionSettings` | `false` | Sample the Host's exact-route authorization preference for each new top-level Session; valid only in Agent scope and requires provider `agentOptions` support |
|
|
48
|
+
| `enableRunInBackground` | `true` | Expose `run_in_background`; disabling also rejects forced background calls |
|
|
49
|
+
| `backgroundMode` | `one-shot` | Background policy: `one-shot` defaults calls to foreground; `continuable` defaults them to background and requires the provider's `prepareContinuable` capability |
|
|
50
|
+
| `agentOptions` | — | Configured child `provider`, `model`, adapter-owned `reasoningEffort`, and positive `maxTokens` defaults; requires provider `agentOptions` support and overlays any provider-owned route defaults |
|
|
51
|
+
| `persona` | — | Per-child persona; requires the provider's `persona` capability |
|
|
52
|
+
| `toolFilter` | — | Per-child global-tool restriction; requires the `toolFilter` capability |
|
|
53
|
+
| `maxDepth` | `3` | Absolute delegation-depth cap (`0` forbids delegation); `'provider-managed'` sends no cap to an out-of-process provider |
|
|
54
|
+
|
|
55
|
+
The generated [configuration catalog](../../../docs/config-catalog.md#xneogdsh-tool-subagent) is the exhaustive source for every accepted field and its JSDoc.
|
|
56
|
+
|
|
57
|
+
### Foreground and background modes
|
|
58
|
+
|
|
59
|
+
Under `one-shot` policy, an omitted `run_in_background` waits in the foreground and returns the child's final text; `run_in_background: true` starts a plain parent-owned background job and returns `started background subagent job <id>`, collected with `job_output` and stopped with `job_kill`.
|
|
60
|
+
|
|
61
|
+
Under `continuable` policy, an omitted or `true` `run_in_background` starts a durable child and returns `started subagent <childId>` without waiting for a result; the runtime delivers one settlement notice when the child's Activation ends, and the optional `send_message` tool sends it more work. Set `run_in_background: false` to wait for the result in the foreground.
|
|
6
62
|
|
|
7
|
-
|
|
63
|
+
`maxDepth` caps recursion (default `3`; `0` forbids delegation) and requires a provider with the `depthLimit` capability; `'provider-managed'` leaves the budget to an out-of-process provider. `persona` and `toolFilter` configure every child when the provider supports them, and the tool stays visible at the cap — each attempted start checks the calling agent's current depth and rejects with an errored result.
|
|
8
64
|
|
|
9
|
-
|
|
65
|
+
### Selecting a child LLM
|
|
10
66
|
|
|
11
|
-
|
|
67
|
+
Set `modelSelectionSettings: true` to sample the Host's `subagent-model-selection` preference when each fresh top-level Session is composed. A restored Session without a recorded policy remains disabled, including an explicitly empty restore. When enabled, the non-empty exact provider/model route list is recorded in the Session, inherited by child Sessions, and unchanged by later settings edits. The tool then exposes optional `provider`, `model`, and `reasoning_effort` fields and registers the shared `list_subagent_models` tool. This mode requires a backend that advertises `agentOptions`; both in-process backends and DSH SDK support it, while ACP, Codex, and Claude Code reject it rather than ignore it.
|
|
12
68
|
|
|
13
|
-
|
|
69
|
+
A call supplies `provider` and `model` together, or supplies only an effort when configured, parent, or provider-owned defaults provide the route. Static `provider.agentRouteDefaults`, when present, form the provider/model baseline; tool configuration and model fields overlay it before route-aware effort merging and exact-route preflight. Providers without these defaults use compatible values from the parent's latest logged request, then the parent's creation options before its first request, while retaining the configured `maxTokens`. Changing the route without an explicit effort clears the inherited route-owned effort, so the selected model resolves its default. The live LLM adapter validates the effective route before child creation. Catalog membership remains advisory, so a model can use an unlisted id when its adapter accepts it.
|
|
14
70
|
|
|
15
|
-
|
|
71
|
+
-----
|
|
16
72
|
|
|
17
|
-
|
|
73
|
+
<a id="understand-the-implementation"></a>
|
|
74
|
+
## Understand the implementation
|
|
18
75
|
|
|
19
|
-
|
|
76
|
+
<details>
|
|
77
|
+
<summary>Implementation internals — click to expand</summary>
|
|
78
|
+
|
|
79
|
+
This section explains how the tool mirrors provider lifecycle and settles runs; the observable behavior is covered in [Use this package](#use-this-package).
|
|
80
|
+
|
|
81
|
+
### Design concept
|
|
82
|
+
|
|
83
|
+
One instance is one provider plus one tool name. The plugin mirrors provider lifecycle: it registers the tool when the named provider appears and disposes it when the provider leaves, so sibling load order and HMR replacement cannot strand a dangling tool. A numeric `maxDepth` or configured LLM selection the provider cannot enforce fails the mount instead of the first delegation. At most one instance in a tool scope may own model selection because `list_subagent_models` has a global name.
|
|
84
|
+
|
|
85
|
+
### Foreground settlement
|
|
86
|
+
|
|
87
|
+
A foreground call awaits `run.result`, maps every non-completed stop reason to an error headline, appends the provider diagnostic and any preserved partial assistant text, and always awaits `run.dispose()` before returning; when result collection and disposal both reject, the errored result preserves both failures.
|
|
88
|
+
|
|
89
|
+
### Background routes
|
|
90
|
+
|
|
91
|
+
One-shot background registers a plain parent-owned Task whose done channel settles the start and keeps the stop reason and optional provider diagnostic in its detail. Continuable background calls `ctx.subagents.startContinuable()`, which resolves at inbox acceptance: the child owns its own turns from there, so the call neither waits for nor collects a result.
|
|
92
|
+
|
|
93
|
+
### Context-sensitive wording
|
|
94
|
+
|
|
95
|
+
The tool's description derives from `provider.inheritsParentContext`: a fresh child gets "it does not see this conversation" wording, a forked child gets "it does not see the current in-flight turn" wording, so the model never restates or omits context that does not exist.
|
|
96
|
+
|
|
97
|
+
### Source map
|
|
98
|
+
|
|
99
|
+
| File | Role |
|
|
20
100
|
|---|---|
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
101
|
+
| [`src/index.ts`](src/index.ts) | Tool registration, lifecycle mirroring, mode resolution, result settlement |
|
|
102
|
+
| [`src/model-selection.ts`](src/model-selection.ts) | Request/config merge and live LLM route preflight |
|
|
103
|
+
| [`src/model-selection-settings.ts`](src/model-selection-settings.ts) | Host-owned opt-in setting sampled for new Sessions |
|
|
104
|
+
| [`src/model-selection-state.ts`](src/model-selection-state.ts) | Session event that records and inherits the sampled decision |
|
|
105
|
+
| [`src/list-models.ts`](src/list-models.ts) | `list_subagent_models` runtime discovery tool |
|
|
106
|
+
|
|
107
|
+
</details>
|
|
108
|
+
|
|
109
|
+
-----
|
|
110
|
+
|
|
111
|
+
<a id="further-exploration"></a>
|
|
112
|
+
## Further Exploration
|
|
113
|
+
|
|
114
|
+
Read these pages when the package-level contract is not enough; they move from the tool's runtime behavior to the seam it delegates over and the adjacent child tools.
|
|
29
115
|
|
|
30
|
-
|
|
116
|
+
- [Subagent subsystem](../../../docs/subsystems/subagent.md) — providers, one-shot start requests, continuable children and activations.
|
|
117
|
+
- [dsh-tool-subagent-control](../tool-subagent-control/README.md) — messaging, interrupt, and listing tools for continuable children.
|
|
118
|
+
- [Generated tool catalog](../../../docs/tool-catalog.md#xneogdsh-tool-subagent) — the default schema and per-mode wording.
|
|
119
|
+
- [Generated configuration catalog](../../../docs/config-catalog.md#xneogdsh-tool-subagent) — every accepted config field.
|
|
120
|
+
- [Background subagent tasks](../../../.agents/notes/implemented/feature/2026-07-08-background-subagent-tasks.md) — the one-shot background route.
|
|
121
|
+
- [Background-first continuable delegation](../../../.agents/notes/implemented/feature/2026-08-11-background-first-continuable-delegation.md) — why continuable work defaults to background.
|
|
122
|
+
- [Model-selected subagent routes](../../../.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.md) — selection policy, inheritance, discovery, and the fork restriction.
|
|
31
123
|
|
|
32
|
-
|
|
124
|
+
-----
|
|
33
125
|
|
|
126
|
+
<a id="model-experience"></a>
|
|
34
127
|
## Model Experience
|
|
35
128
|
|
|
36
129
|
### Tool schema
|
|
37
130
|
|
|
38
131
|
#### What the model sees
|
|
39
132
|
|
|
40
|
-
The generated default [`subagent` schema](../../../docs/tool-catalog.md#
|
|
133
|
+
The generated default [`subagent` schema](../../../docs/tool-catalog.md#xneogdsh-tool-subagent) under this instance's configured name while its provider exists. An enabled Session policy adds `provider`, `model`, and `reasoning_effort` plus inheritance and selection guidance; the provider must support `agentOptions`. Provider context inheritance changes the tool and prompt descriptions. Enabled background mode adds `run_in_background`: continuable mode documents its `true` default, runtime settlement notice, and explicit foreground override, while one-shot mode documents its `false` default and the job id collected with `job_output` or stopped with `job_kill`. While the tool is visible in an assembly's scope, a `tool:<toolName>` system-prompt section tells the model to start independent continuable delegations together, keep working while they run, and choose foreground only when its next action depends on the result; a tool restriction removes both its schema and this guidance.
|
|
41
134
|
|
|
42
135
|
#### Token effect
|
|
43
136
|
|
|
44
|
-
Fixed schema cost per parent request;
|
|
137
|
+
Fixed schema cost per parent request; model selection adds three parameters. Each provider instance adds one schema, and each continuable instance adds one short system-prompt section.
|
|
45
138
|
|
|
46
139
|
#### KV Cache effect
|
|
47
140
|
|
|
48
|
-
Prefix-stable while provider instances
|
|
141
|
+
Prefix-stable while provider instances and their configuration are unchanged. Adapter catalog changes do not alter the definition; a child route override may prevent a fork child from reusing the inherited parent prefix.
|
|
142
|
+
|
|
143
|
+
### Model selection and discovery
|
|
144
|
+
|
|
145
|
+
#### What the model sees
|
|
146
|
+
|
|
147
|
+
A settings-controlled instance whose Session carries a policy exposes the child LLM selection fields and `list_subagent_models`. Calls reject while the optional `ctx.llm` service is unavailable. Discovery returns only registered providers and advertised models in the exact route policy; an unauthorized provider is rejected before its adapter catalog is called, and an exact lookup must be allowed before it resolves the model's reasoning efforts and default. Execution independently enforces the same policy.
|
|
148
|
+
|
|
149
|
+
#### Token effect
|
|
150
|
+
|
|
151
|
+
One fixed discovery schema is present in enabled compositions. Directory contents enter the transcript only when the model calls the tool.
|
|
152
|
+
|
|
153
|
+
#### KV Cache effect
|
|
154
|
+
|
|
155
|
+
The schema is prefix-stable across adapter registration and catalog changes. Each discovery result is appended after the reusable prefix.
|
|
156
|
+
|
|
157
|
+
### System prompt
|
|
158
|
+
|
|
159
|
+
#### What the model sees
|
|
160
|
+
|
|
161
|
+
When `enableRunInBackground` and `backgroundMode: continuable` are both set, the model additionally reads a `tool:<toolName>` system-prompt section telling it to start independent continuable delegations together and keep working while they run. With the default tool name `subagent`, the section text is:
|
|
162
|
+
|
|
163
|
+
##### Tool-guidance section
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
Use subagent in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set `run_in_background: false` only when your next action depends on that subagent's result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message.
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Token effect
|
|
170
|
+
|
|
171
|
+
One short fixed section per continuable instance, paid on every parent request while the tool is in scope.
|
|
172
|
+
|
|
173
|
+
#### KV Cache effect
|
|
174
|
+
|
|
175
|
+
Prefix-stable while the section text and tool presence are unchanged; removing the tool or changing the section establishes a different parent prefix.
|
|
49
176
|
|
|
50
177
|
### Foreground result
|
|
51
178
|
|
|
52
179
|
#### What the model sees
|
|
53
180
|
|
|
54
|
-
The call retains the description and prompt. Success contains only the child's final text; other outcomes become `Error: <
|
|
181
|
+
The call retains the description and prompt. Success contains only the child's final text; other outcomes become `Error: <stop reason>`, followed by a safe provider diagnostic when present and then any partial assistant text. Intermediate child steps stay out of the parent.
|
|
55
182
|
|
|
56
183
|
#### Token effect
|
|
57
184
|
|
|
@@ -65,7 +192,7 @@ Append-only; newly visible content follows the reusable request prefix and does
|
|
|
65
192
|
|
|
66
193
|
#### What the model sees
|
|
67
194
|
|
|
68
|
-
Start returns exactly `started subagent <childId>` in configured continuable mode, or `started background subagent job <id>` in configured one-shot mode. In one-shot mode the generic task surface provides later status, final output, cancellation responses, and notices. In continuable mode this tool returns no result of its own
|
|
195
|
+
Start returns exactly `started subagent <childId>` in configured continuable mode, or `started background subagent job <id>` in configured one-shot mode. In one-shot mode the generic task surface provides later status, final output, cancellation responses, and notices; failed status detail includes the provider diagnostic when the result supplied one. In continuable mode this tool returns no result of its own: the child's settlement reaches the parent as a service-owned notice, an independently loaded `send_message` tool delivers follow-ups, and the child's transcript by its id is the source of its detailed output.
|
|
69
196
|
|
|
70
197
|
#### Token effect
|
|
71
198
|
|
|
@@ -77,6 +204,22 @@ Append-only; newly visible content follows the reusable request prefix and does
|
|
|
77
204
|
|
|
78
205
|
## Known Limitations and Deferred Work
|
|
79
206
|
|
|
207
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
These limits define what this tool does not return or enforce; they are current package constraints.
|
|
211
|
+
|
|
80
212
|
- **Background runs expose no result through this tool** — a one-shot task's final output is collected through the generic task surface, and a continuable child's output stays in its own session, read by its subagent id. The settlement notice states how that child ended and carries any final assistant message, but it is not this call's return value and cannot be awaited here.
|
|
81
213
|
- **Duplicate names across waiting one-shot instances are detected late** (`TODO(subagent-dup-toolname)`) — continuable instances reserve their prompt-section name during plugin application, but preventing provider-registration rollback for waiting one-shot instances requires a registry of intended names.
|
|
82
|
-
- **
|
|
214
|
+
- **Shipped fork tools cannot select a child LLM route** — they inherit the parent's provider and model to keep the copied conversation prefix eligible for KV Cache reuse. Re-enable selection only when route changes preserve reuse or expose a bounded recomputation cost.
|
|
215
|
+
- **Non-routing child policy is fixed per instance** — another persona, tool filter, or depth cap requires another distinctly named tool. LLM selection requires an enabled per-Session preference and a provider that advertises `agentOptions`; both in-process providers and DSH SDK advertise it, while ACP, Codex, and Claude Code reject it rather than ignore it.
|
|
216
|
+
|
|
217
|
+
<a id="dev-note"></a>
|
|
218
|
+
### Dev Note
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
222
|
+
|
|
223
|
+
None.
|
|
224
|
+
|
|
225
|
+
</details>
|
package/README.zh.md
CHANGED
|
@@ -1,61 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向模型的 subagent 委派工具,供用户与维护者配置、组合或排查基于 subagent 提供方的委派。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# @xneog/dsh-tool-subagent
|
|
2
7
|
|
|
3
8
|
[English](README.md) | 中文
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-tool-subagent` 是面向模型的委派工具:它把一个已配置的 `ctx.subagents` 提供方变成 agent 可以调用来启动子 agent(智能体)的工具。更换提供方只会改变传输,不会改变执行约定,因此一个组合可以暴露多个委派工具,各自绑定不同的后端。`one-shot` 策略下,调用默认在前台等待子 agent;`continuable` 策略下,调用默认在后台启动工作,并返回模型之后可以发消息的持久化子 agent id。合适的实例还可让模型发现并选择子 agent 的 LLM 提供方、模型与推理等级。工具的描述会随子 agent 是否继承父级已完成轮次而调整,失败的运行以出错的工具结果呈现,而非部分成功。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
每个委派目标挂载一个实例,且每个实例的 `toolName` 必须不同。工具与其提供方同时存在、同时消失,因此同级加载顺序与提供方重新加载都不会让工具悬空。
|
|
29
|
+
|
|
30
|
+
### 最小配置
|
|
31
|
+
|
|
32
|
+
先加载 subagent 服务、一个进程内或远程后端与本工具,然后指定提供方名称。此组合暴露一个委派给 `spawn` 后端的 `subagent` 工具:
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- name: '@xneog/dsh-subagent'
|
|
36
|
+
- name: '@xneog/dsh-subagent-spawn-in-process'
|
|
37
|
+
- name: '@xneog/dsh-tool-subagent'
|
|
38
|
+
config:
|
|
39
|
+
provider: spawn
|
|
40
|
+
toolName: subagent
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| 字段 | 默认值 | 含义 |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `provider` | 必填 | `ctx.subagents` 上的提供方名称(如 `spawn`、`fork`、`acp`) |
|
|
46
|
+
| `toolName` | `subagent` | 面向模型的工具名称;每个已加载实例必须不同 |
|
|
47
|
+
| `modelSelectionSettings` | `false` | 为每个新顶层 Session 读取宿主的精确路由授权偏好;只在 Agent 作用域内有效,并要求提供方支持 `agentOptions` |
|
|
48
|
+
| `enableRunInBackground` | `true` | 公开 `run_in_background`;禁用时也会拒绝强制后台调用 |
|
|
49
|
+
| `backgroundMode` | `one-shot` | 后台策略:`one-shot` 默认前台调用;`continuable` 默认后台调用,并要求提供方具备 `prepareContinuable` 能力 |
|
|
50
|
+
| `agentOptions` | — | 配置的子级 `provider`、`model`、适配器所有的 `reasoningEffort` 与正整数 `maxTokens` 默认值;要求提供方支持 `agentOptions`,并会覆盖提供方持有的路由默认值 |
|
|
51
|
+
| `persona` | — | 每个子 agent 独立的 persona;要求提供方具备 `persona` 能力 |
|
|
52
|
+
| `toolFilter` | — | 每个子 agent 独立的全局工具限制;要求提供方具备 `toolFilter` 能力 |
|
|
53
|
+
| `maxDepth` | `3` | 绝对委派深度上限(`0` 禁止委派);`'provider-managed'` 不向进程外提供方发送上限 |
|
|
54
|
+
|
|
55
|
+
生成的[配置目录](../../../docs/config-catalog.zh.md#xneogdsh-tool-subagent)是每个受支持字段及其 JSDoc 的穷尽式真源。
|
|
56
|
+
|
|
57
|
+
### 前台与后台模式
|
|
58
|
+
|
|
59
|
+
`one-shot` 策略下,省略 `run_in_background` 会在前台等待并返回子 agent 的最终文本;`run_in_background: true` 会启动一个归父级所有的普通后台任务,并返回 `started background subagent job <id>`,可用 `job_output` 收集、用 `job_kill` 停止。
|
|
60
|
+
|
|
61
|
+
`continuable` 策略下,省略或为 `true` 的 `run_in_background` 会启动一个持久化子 agent,并返回 `started subagent <childId>`,不等待结果;子 agent 的 Activation 结束时,运行时投递一条结算通知,可选的 `send_message` 工具会向它发送更多工作。把 `run_in_background` 设为 `false` 可在前台等待结果。
|
|
6
62
|
|
|
7
|
-
|
|
63
|
+
`maxDepth` 限制递归深度(默认 `3`;`0` 禁止委派),并要求提供方具备 `depthLimit` 能力;`'provider-managed'` 把预算留给进程外提供方。当提供方支持时,`persona` 与 `toolFilter` 会配置每个子 agent;工具在达到上限时仍然可见——每次尝试启动都会检查调用 agent 的当前深度,被拒绝时返回出错的工具结果。
|
|
8
64
|
|
|
9
|
-
|
|
65
|
+
### 选择子级 LLM
|
|
10
66
|
|
|
11
|
-
|
|
67
|
+
设置 `modelSelectionSettings: true`,即可在组合每个全新顶层 Session 时读取宿主的 `subagent-model-selection` 偏好。没有已记录策略的恢复 Session 会保持禁用,包括显式为空的恢复。启用后,非空的精确 provider/model 路由列表会记录进 Session、由子 Session 继承,后续设置编辑不会改变它。工具随后公开可选的 `provider`、`model` 与 `reasoning_effort` 字段,并注册共享的 `list_subagent_models` 工具。此模式要求后端声明 `agentOptions`;两个进程内后端和 DSH SDK 支持该能力,而 ACP、Codex 与 Claude Code 会拒绝它,而不是忽略它。
|
|
12
68
|
|
|
13
|
-
|
|
69
|
+
一次调用需同时提供 `provider` 与 `model`;当配置值、父 agent 值或提供方持有的默认值能提供路由时,也可只提供推理等级。静态的 `provider.agentRouteDefaults` 在存在时构成提供方/模型基线;工具配置与模型字段会在路由相关强度合并和确切路由预检前覆盖它。没有这些默认值的提供方会使用父 agent 最新已记录请求中的兼容值,再使用父级首次请求前的创建选项,并保留配置的 `maxTokens`。更改路由但未显式提供推理等级时,会清除继承的路由自有等级,使所选模型解析自己的默认值。实时 LLM 适配器在创建子 agent 前校验有效路由。目录成员资格只提供建议,因此适配器接受时,模型可以使用未列出的 id。
|
|
14
70
|
|
|
15
|
-
|
|
71
|
+
-----
|
|
16
72
|
|
|
17
|
-
|
|
73
|
+
<a id="understand-the-implementation"></a>
|
|
74
|
+
## 理解实现
|
|
18
75
|
|
|
19
|
-
|
|
76
|
+
<details>
|
|
77
|
+
<summary>实现细节——点击展开</summary>
|
|
78
|
+
|
|
79
|
+
本节解释工具如何镜像提供方生命周期并结算运行;可观察行为已在[使用本包](#use-this-package)中说明。
|
|
80
|
+
|
|
81
|
+
### 设计理念
|
|
82
|
+
|
|
83
|
+
一个实例就是一个提供方加一个工具名称。插件镜像提供方生命周期:具名提供方出现时注册工具,提供方离开时释放工具,因此同级加载顺序与 HMR 替换不会让工具悬空。提供方无法执行的数值型 `maxDepth` 或已配置 LLM 选择会在挂载时失败,而不是在首次委派时失败。每个工具作用域内最多一个实例可以拥有模型选择,因为 `list_subagent_models` 使用全局名称。
|
|
84
|
+
|
|
85
|
+
### 前台结算
|
|
86
|
+
|
|
87
|
+
前台调用会等待 `run.result`,把每个非完成终止原因映射为错误标题,追加提供方诊断与任何保留下来的部分 assistant 文本,并在返回前始终等待 `run.dispose()`;当结果收集与 dispose(资源释放)都 reject 时,出错结果会保留两项失败。
|
|
88
|
+
|
|
89
|
+
### 后台路由
|
|
90
|
+
|
|
91
|
+
一次性后台模式会注册一个归父级所有的普通 Task,其 done 通道结算启动,并在 detail 中保留终止原因与可选提供方诊断。可继续后台模式调用 `ctx.subagents.startContinuable()`,该调用在 inbox 接受时结算:子 agent 自此拥有自己的轮次,因此该调用既不等待也不收集结果。
|
|
92
|
+
|
|
93
|
+
### 随上下文变化的措辞
|
|
94
|
+
|
|
95
|
+
工具描述源自 `provider.inheritsParentContext`:全新子 agent 得到「it does not see this conversation」措辞,fork 子 agent 得到「it does not see the current in-flight turn」措辞,因此模型既不会复述、也不会省略并不存在的上下文。
|
|
96
|
+
|
|
97
|
+
### 源码地图
|
|
98
|
+
|
|
99
|
+
| 文件 | 职责 |
|
|
20
100
|
|---|---|
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
101
|
+
| [`src/index.ts`](src/index.ts) | 工具注册、生命周期镜像、模式解析、结果结算 |
|
|
102
|
+
| [`src/model-selection.ts`](src/model-selection.ts) | 请求/配置合并与实时 LLM 路由预检 |
|
|
103
|
+
| [`src/model-selection-settings.ts`](src/model-selection-settings.ts) | 为新 Session 读取的宿主所有 opt-in 设置 |
|
|
104
|
+
| [`src/model-selection-state.ts`](src/model-selection-state.ts) | 记录并继承已读取决定的 Session 事件 |
|
|
105
|
+
| [`src/list-models.ts`](src/list-models.ts) | `list_subagent_models` 运行时发现工具 |
|
|
106
|
+
|
|
107
|
+
</details>
|
|
108
|
+
|
|
109
|
+
-----
|
|
110
|
+
|
|
111
|
+
<a id="further-exploration"></a>
|
|
112
|
+
## 进一步探索
|
|
29
113
|
|
|
30
|
-
|
|
114
|
+
当包级约定不够用时阅读以下页面;它们从工具运行时行为进入它所委派其上的 seam,以及相邻的子 agent 工具。
|
|
31
115
|
|
|
32
|
-
|
|
116
|
+
- [Subagent 子系统](../../../docs/subsystems/subagent.zh.md)——提供方、一次性启动请求、可继续子 agent 与 Activation。
|
|
117
|
+
- [dsh-tool-subagent-control](../tool-subagent-control/README.zh.md)——可继续子 agent 的消息、中断与列表工具。
|
|
118
|
+
- [生成工具目录](../../../docs/tool-catalog.zh.md#xneogdsh-tool-subagent)——默认 schema 与各模式的措辞。
|
|
119
|
+
- [生成配置目录](../../../docs/config-catalog.zh.md#xneogdsh-tool-subagent)——每个受支持配置字段。
|
|
120
|
+
- [后台 subagent 任务](../../../.agents/notes/implemented/feature/2026-07-08-background-subagent-tasks.zh.md)——一次性后台路由。
|
|
121
|
+
- [后台优先的可继续委派](../../../.agents/notes/implemented/feature/2026-08-11-background-first-continuable-delegation.zh.md)——可继续工作为何默认在后台运行。
|
|
122
|
+
- [模型选择 subagent 路由](../../../.agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.zh.md)——选择策略、继承、发现与 fork 限制。
|
|
33
123
|
|
|
124
|
+
-----
|
|
125
|
+
|
|
126
|
+
<a id="model-experience"></a>
|
|
34
127
|
## 模型体验
|
|
35
128
|
|
|
36
129
|
### 工具 schema
|
|
37
130
|
|
|
38
|
-
####
|
|
131
|
+
#### 模型看到什么
|
|
132
|
+
|
|
133
|
+
当提供方存在时,以当前实例配置的名称公开已生成的默认 [`subagent` schema](../../../docs/tool-catalog.zh.md#xneogdsh-tool-subagent)。启用的 Session 策略会添加 `provider`、`model` 与 `reasoning_effort`,以及继承和选择指引;提供方必须支持 `agentOptions`。提供方是否继承上下文会改变工具描述和提示词描述。启用后台模式会添加 `run_in_background`:可继续模式会记录其默认值为 `true`、运行时结算通知与显式前台覆盖;一次性模式会记录其默认值为 `false`,以及用 `job_output` 收集或用 `job_kill` 停止的 job id。当工具在本次组装的作用域中可见时,一个 `tool:<toolName>` 系统提示词 section 会指示模型同时启动相互独立的可继续委派、在它们运行时继续工作,并且仅当下一步动作依赖结果时选择前台;工具限制会同时移除其 schema 和这段指引。
|
|
134
|
+
|
|
135
|
+
#### Token 影响
|
|
136
|
+
|
|
137
|
+
每个父级请求支付固定的 schema 成本;模型选择会增加三个参数。每个提供方实例增加一个 schema,每个可继续实例还增加一个简短的系统提示词 section。
|
|
138
|
+
|
|
139
|
+
#### KV Cache 影响
|
|
140
|
+
|
|
141
|
+
只要提供方实例及其配置不变,前缀就保持稳定。适配器目录变化不会改变定义;子级路由覆盖可能使 fork 子 agent 无法复用继承的父级前缀。
|
|
142
|
+
|
|
143
|
+
### 模型选择与发现
|
|
144
|
+
|
|
145
|
+
#### 模型看到什么
|
|
146
|
+
|
|
147
|
+
Session 携带策略的 settings 控制实例会公开子级 LLM 选择字段与 `list_subagent_models`。可选 `ctx.llm` 服务不可用时,调用会失败。发现只返回精确路由策略中的已注册提供方与已公布模型;未授权提供方会在调用其适配器目录前被拒绝,精确查询也必须先获准,才会解析模型的推理强度与默认值。执行阶段会独立强制同一策略。
|
|
148
|
+
|
|
149
|
+
#### Token 影响
|
|
150
|
+
|
|
151
|
+
启用的组合中存在一个固定发现 schema。只有模型调用工具时,目录内容才进入 transcript。
|
|
39
152
|
|
|
40
|
-
|
|
153
|
+
#### KV Cache 影响
|
|
154
|
+
|
|
155
|
+
适配器注册与目录变化不会改变 schema 前缀。每个发现结果都追加在可复用前缀之后。
|
|
156
|
+
|
|
157
|
+
### 系统提示词
|
|
158
|
+
|
|
159
|
+
#### 模型看到什么
|
|
160
|
+
|
|
161
|
+
当 `enableRunInBackground` 与 `backgroundMode: continuable` 同时设置时,模型还会读到 `tool:<toolName>` 系统提示词 section,指示它把相互独立的可继续委派一起启动,并在它们运行时继续工作。使用默认工具名 `subagent` 时,section 文本为:
|
|
162
|
+
|
|
163
|
+
##### 工具指导 section
|
|
164
|
+
|
|
165
|
+
```markdown
|
|
166
|
+
Use subagent in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set `run_in_background: false` only when your next action depends on that subagent's result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message.
|
|
167
|
+
```
|
|
41
168
|
|
|
42
169
|
#### Token 影响
|
|
43
170
|
|
|
44
|
-
|
|
171
|
+
每个可继续实例一个简短固定 section,只要工具在作用域内,就由每个父级请求支付。
|
|
45
172
|
|
|
46
173
|
#### KV Cache 影响
|
|
47
174
|
|
|
48
|
-
|
|
175
|
+
只要 section 文本与工具存在性不变,前缀就保持稳定;移除工具或更改 section 会建立不同的父级前缀。
|
|
49
176
|
|
|
50
177
|
### 前台结果
|
|
51
178
|
|
|
52
|
-
####
|
|
179
|
+
#### 模型看到什么
|
|
53
180
|
|
|
54
|
-
|
|
181
|
+
调用会保留描述与提示词。成功时只包含子 agent 的最终文本;其他结果变为 `Error: <终止原因>`,随后在存在时附上安全的提供方诊断,再附上任何部分 assistant 文本。子 agent 中间步骤不会进入父级。
|
|
55
182
|
|
|
56
183
|
#### Token 影响
|
|
57
184
|
|
|
58
|
-
|
|
185
|
+
提示词与结果保留在父级历史中,直到上下文压缩(context compaction);子 agent 工作上下文留在子 agent 中。
|
|
59
186
|
|
|
60
187
|
#### KV Cache 影响
|
|
61
188
|
|
|
@@ -63,9 +190,9 @@
|
|
|
63
190
|
|
|
64
191
|
### 后台结果
|
|
65
192
|
|
|
66
|
-
####
|
|
193
|
+
#### 模型看到什么
|
|
67
194
|
|
|
68
|
-
在配置的可继续模式下,启动时返回内容恰为 `started subagent <childId>`;在配置的一次性模式下,则返回 `started background subagent job <id>`。一次性模式下,通用 Task
|
|
195
|
+
在配置的可继续模式下,启动时返回内容恰为 `started subagent <childId>`;在配置的一次性模式下,则返回 `started background subagent job <id>`。一次性模式下,通用 Task 接口提供后续状态、最终输出、取消响应与通知;若结果携带提供方诊断,失败状态的 detail 会包含它。可继续模式下,本工具不返回自己的结果:子 agent 的结算以服务负责的通知到达父级,独立加载的 `send_message` 工具投递后续消息,而通过其 id 查看子 agent 的 transcript(文本记录)即是其详细输出来源。
|
|
69
196
|
|
|
70
197
|
#### Token 影响
|
|
71
198
|
|
|
@@ -75,8 +202,24 @@
|
|
|
75
202
|
|
|
76
203
|
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
|
77
204
|
|
|
78
|
-
##
|
|
205
|
+
## 已知限制与延期工作
|
|
206
|
+
|
|
207
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
这些限制说明本工具不返回或不强制执行什么;它们是当前包约束。
|
|
211
|
+
|
|
212
|
+
- **后台运行不通过本工具公开结果**——一次性任务的最终输出通过通用 Task 接口收集,可继续子 agent 的输出留在其自身会话中,按其 subagent id 读取。结算通知会说明该子 agent 如何结束,并携带可能存在的最终 assistant 消息,但它不是本次调用的返回值,也无法在此等待。
|
|
213
|
+
- **等待中的一次性实例较晚才发现重复名称**(`TODO(subagent-dup-toolname)`)——可继续实例会在插件应用期间预留提示词 section 名称,但若要阻止等待中的一次性实例回滚提供方注册,仍需要一份预期名称注册表。
|
|
214
|
+
- **随附 fork 工具不能选择子级 LLM 路由**——它们继承父级提供方与模型,使复制的对话前缀仍有资格复用 KV Cache。仅当路由变更能保留复用或公开有界重算成本时,才重新启用选择。
|
|
215
|
+
- **非路由子 agent 策略按实例固定**——另一个 persona、工具过滤器或深度上限需要另一个名称不同的工具。LLM 选择要求启用逐 Session 偏好,且提供方必须声明 `agentOptions`;两个进程内提供方和 DSH SDK 会声明该能力,而 ACP、Codex 与 Claude Code 会拒绝它,而不是忽略它。
|
|
216
|
+
|
|
217
|
+
<a id="dev-note"></a>
|
|
218
|
+
### 开发备注
|
|
219
|
+
|
|
220
|
+
<details>
|
|
221
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
222
|
+
|
|
223
|
+
无。
|
|
79
224
|
|
|
80
|
-
|
|
81
|
-
- **等待中的一次性实例较晚才发现重复名称**(`TODO(subagent-dup-toolname)`):可继续实例会在插件应用期间预留提示词 section 名称,但若要阻止等待中的一次性实例回滚提供方注册,仍需要一份预期名称注册表。
|
|
82
|
-
- **每个实例的子 agent 策略固定**:其他模型、persona、工具过滤器或深度上限都需要另一个名称不同的工具。
|
|
225
|
+
</details>
|