@qilin-agent/subagent-fork-in-process 0.0.0-stage → 3.1.4
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 +21 -0
- package/README.i18n.yaml +82 -0
- package/README.md +154 -2
- package/README.zh.md +155 -0
- package/lib/index.js +56 -0
- package/lib/types/index.d.ts +20 -0
- package/package.json +50 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kkutysllb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
|
2
|
+
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
|
3
|
+
# After editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/subagent/subagent-fork-in-process/README.md
|
|
5
|
+
/:
|
|
6
|
+
en: a4a75d423f70c4de
|
|
7
|
+
zh: a60816274b877a80
|
|
8
|
+
/qilin-agent-subagent-fork-in-process:
|
|
9
|
+
en: 7cf0e37620e22522
|
|
10
|
+
zh: b443e50dc2b48be2
|
|
11
|
+
/qilin-agent-subagent-fork-in-process/summary:
|
|
12
|
+
en: 97309f84ffe50ba9
|
|
13
|
+
zh: ce4121b0823b7c7f
|
|
14
|
+
/qilin-agent-subagent-fork-in-process/table-of-contents:
|
|
15
|
+
en: d152484eb41ac6b4
|
|
16
|
+
zh: 09388d293f9be9cb
|
|
17
|
+
/qilin-agent-subagent-fork-in-process/use-this-package:
|
|
18
|
+
en: 71affc798c840594
|
|
19
|
+
zh: 258a2932c3c04841
|
|
20
|
+
/qilin-agent-subagent-fork-in-process/use-this-package/when-to-choose-it:
|
|
21
|
+
en: 05090df7cc302c6a
|
|
22
|
+
zh: bd988019ba062e0a
|
|
23
|
+
/qilin-agent-subagent-fork-in-process/use-this-package/seed-boundary:
|
|
24
|
+
en: f4dfd1ce652f019b
|
|
25
|
+
zh: 9bb75239491f07cc
|
|
26
|
+
/qilin-agent-subagent-fork-in-process/use-this-package/minimal-configuration:
|
|
27
|
+
en: 2991e26cbb054981
|
|
28
|
+
zh: 283ec9733299ce57
|
|
29
|
+
/qilin-agent-subagent-fork-in-process/use-this-package/what-a-fork-delegation-does:
|
|
30
|
+
en: 461063deda821a1b
|
|
31
|
+
zh: 18d2d41d64884f22
|
|
32
|
+
/qilin-agent-subagent-fork-in-process/understand-the-implementation:
|
|
33
|
+
en: 6a0fe4b9cc780aaa
|
|
34
|
+
zh: 50cd69ceb8296827
|
|
35
|
+
/qilin-agent-subagent-fork-in-process/understand-the-implementation/design-concept:
|
|
36
|
+
en: 49c8725fee5330ed
|
|
37
|
+
zh: 9050680f2011820a
|
|
38
|
+
/qilin-agent-subagent-fork-in-process/understand-the-implementation/source-map:
|
|
39
|
+
en: f1f45255fd9f71c1
|
|
40
|
+
zh: 9a3f016b8fe9754a
|
|
41
|
+
/qilin-agent-subagent-fork-in-process/understand-the-implementation/run-flow:
|
|
42
|
+
en: ef063b5c5542e129
|
|
43
|
+
zh: ba564c6b92453b44
|
|
44
|
+
/qilin-agent-subagent-fork-in-process/understand-the-implementation/lifecycle-binding:
|
|
45
|
+
en: 8dad0155ed1b32d2
|
|
46
|
+
zh: f4d82d5ede03c4d7
|
|
47
|
+
/qilin-agent-subagent-fork-in-process/further-exploration:
|
|
48
|
+
en: c2982ca1d8a57a07
|
|
49
|
+
zh: 9054738d81c989bd
|
|
50
|
+
/qilin-agent-subagent-fork-in-process/model-experience:
|
|
51
|
+
en: 215e7ba838619b7b
|
|
52
|
+
zh: a311da3843709f90
|
|
53
|
+
/qilin-agent-subagent-fork-in-process/model-experience/child-agent-history-and-envelope:
|
|
54
|
+
en: 91a5bd22001586e9
|
|
55
|
+
zh: 456e5bf20881a70d
|
|
56
|
+
/qilin-agent-subagent-fork-in-process/model-experience/child-agent-history-and-envelope/what-the-model-sees:
|
|
57
|
+
en: fe88f3e65bb01009
|
|
58
|
+
zh: 64e05acfe80e81f3
|
|
59
|
+
/qilin-agent-subagent-fork-in-process/model-experience/child-agent-history-and-envelope/token-effect:
|
|
60
|
+
en: db9ae2edb5ee28ce
|
|
61
|
+
zh: 5a342ffa3e7a7b40
|
|
62
|
+
/qilin-agent-subagent-fork-in-process/model-experience/child-agent-history-and-envelope/kv-cache-effect:
|
|
63
|
+
en: 45f524befcb9b070
|
|
64
|
+
zh: ddd41e8b0d218864
|
|
65
|
+
/qilin-agent-subagent-fork-in-process/model-experience/parent-tool-result-indirectly:
|
|
66
|
+
en: 75d061c2151624a7
|
|
67
|
+
zh: 71e58e020b60ff90
|
|
68
|
+
/qilin-agent-subagent-fork-in-process/model-experience/parent-tool-result-indirectly/what-the-model-sees:
|
|
69
|
+
en: 54d10ba4da6cdece
|
|
70
|
+
zh: bb9cb4d685098483
|
|
71
|
+
/qilin-agent-subagent-fork-in-process/model-experience/parent-tool-result-indirectly/token-effect:
|
|
72
|
+
en: 8c81bab3c5d6a38a
|
|
73
|
+
zh: 44c798432a4bfdfb
|
|
74
|
+
/qilin-agent-subagent-fork-in-process/model-experience/parent-tool-result-indirectly/kv-cache-effect:
|
|
75
|
+
en: f5d5f97a153f7c70
|
|
76
|
+
zh: 3d6bc05b9eadfbc2
|
|
77
|
+
/qilin-agent-subagent-fork-in-process/known-limitations-and-deferred-work:
|
|
78
|
+
en: 7bdc464ac3108d28
|
|
79
|
+
zh: 6d94cdd487ab24a5
|
|
80
|
+
/qilin-agent-subagent-fork-in-process/known-limitations-and-deferred-work/dev-note:
|
|
81
|
+
en: e67f633dc6fe7773
|
|
82
|
+
zh: 3bb0c20c93f16f98
|
package/README.md
CHANGED
|
@@ -1,3 +1,155 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "In-process fork subagent backend for users and maintainers choosing, configuring, or debugging children seeded with the parent's completed turns."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# @qilin-agent/subagent-fork-in-process
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
`dsh-subagent-fork-in-process` is an in-process subagent backend that seeds each child with the parent's completed conversation turns: the child sees every finished turn and none of the in-flight one, so follow-up work builds on the conversation without duplicating it. A delegation tool reaches it under the `fork` provider name, and its behavior matches the spawn backend except for the session seed. Choose it when a subtask continues this conversation; choose spawn when the child must stand alone. The seed is a one-time snapshot taken at fork time: later parent turns never reach the child.
|
|
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 this backend when delegated work must build on the parent's conversation. The common path mirrors spawn: load the subagent service and this backend, then point a delegation tool such as `dsh-tool-subagent` at the `fork` provider.
|
|
29
|
+
|
|
30
|
+
### When to choose it
|
|
31
|
+
|
|
32
|
+
Choose fork when the child needs the conversation's completed turns — a follow-up analysis, a review, a continuation. Choose spawn when the child should start clean, or an out-of-process backend when the child must not share this process. The seed carries conversation history only: the child still gets a fresh tool scope and none of the parent's authority.
|
|
33
|
+
|
|
34
|
+
### Seed boundary
|
|
35
|
+
|
|
36
|
+
The seed ends at the parent's last completed turn. A parent's current tool-calling turn is still open when a subagent starts, so that in-flight turn is never included; before the first completed turn the seed is empty and the child behaves like a fresh spawn.
|
|
37
|
+
|
|
38
|
+
### Minimal configuration
|
|
39
|
+
|
|
40
|
+
Load the subagent service and this backend, then configure a delegation tool. This composition exposes a `subagent` tool backed by fork:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
- name: '@qilin-agent/subagent'
|
|
44
|
+
- name: '@qilin-agent/subagent-fork-in-process'
|
|
45
|
+
- name: '@qilin-agent/tool-subagent'
|
|
46
|
+
config:
|
|
47
|
+
provider: fork
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Field | Default | Meaning |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `providerName` | `fork` | Provider name registered on `ctx.subagents` |
|
|
53
|
+
|
|
54
|
+
The generated [configuration catalog](../../../docs/config-catalog.md#qilin-agentsubagent-fork-in-process) is the exhaustive source for every accepted field and its JSDoc.
|
|
55
|
+
|
|
56
|
+
### What a fork delegation does
|
|
57
|
+
|
|
58
|
+
One tool call creates a background child and returns its session id immediately. The child works in its own session; the parent receives its final answer in a completion notice. The child can also send messages through `send_message`. A rejected start leaves no published child. Programmatic callers such as workflows can await the activation result directly.
|
|
59
|
+
|
|
60
|
+
-----
|
|
61
|
+
|
|
62
|
+
<a id="understand-the-implementation"></a>
|
|
63
|
+
## Understand the implementation
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>Implementation internals — click to expand</summary>
|
|
67
|
+
|
|
68
|
+
This section explains the design decisions behind the backend and where the behavior in [Use this package](#use-this-package) comes from.
|
|
69
|
+
|
|
70
|
+
### Design concept
|
|
71
|
+
|
|
72
|
+
This backend supplies the balanced completed-turn prefix of the parent log as the child session seed. The subagent service records the inherited range so results contain only the child’s own output.
|
|
73
|
+
|
|
74
|
+
### Source map
|
|
75
|
+
|
|
76
|
+
| File | Role |
|
|
77
|
+
|---|---|
|
|
78
|
+
| [`src/index.ts`](src/index.ts) | Provider registration: prefix computation, `Config` schema, capability declaration |
|
|
79
|
+
|
|
80
|
+
### Run flow
|
|
81
|
+
|
|
82
|
+
`prepareContinuable()` captures the parent’s completed-turn prefix once at creation. `startActivation()` creates the child with that seed, and the subagent service applies persona, tool filtering, and structured output for this activation. The provider advertises the same agent options, output, depth, filter, and persona capabilities as spawn.
|
|
83
|
+
|
|
84
|
+
### Lifecycle binding
|
|
85
|
+
|
|
86
|
+
The delegation tool creates a background activation and returns a stable child session id. Parent and child share the same messaging tool definitions and ordering; the parent id and return guidance follow inherited history in the initial task. Workflows await results with caller delivery and send no completion notice to the parent.
|
|
87
|
+
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
-----
|
|
91
|
+
|
|
92
|
+
<a id="further-exploration"></a>
|
|
93
|
+
## Further Exploration
|
|
94
|
+
|
|
95
|
+
Read these pages when the package-level contract is not enough; they move from the shared subagent model to the sibling backends and the design evidence for preserving the inherited request prefix.
|
|
96
|
+
|
|
97
|
+
- [Subagent subsystem](../../../docs/subsystems/subagent.md) — start requests, results, provider contract, and in-process depth and seed.
|
|
98
|
+
- [dsh-subagent-spawn-in-process](../subagent-spawn-in-process/README.md) — the fresh-child sibling backend.
|
|
99
|
+
- [dsh-tool-subagent](../tool-subagent/README.md) — the model-facing delegation tool that reaches this provider.
|
|
100
|
+
- [Generated configuration catalog](../../../docs/config-catalog.md#qilin-agentsubagent-fork-in-process) — every accepted config field and its source declaration.
|
|
101
|
+
- [Forked children preserve the parent request prefix](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md) — why continuable fork preserves the inherited request prefix.
|
|
102
|
+
|
|
103
|
+
-----
|
|
104
|
+
|
|
105
|
+
<a id="model-experience"></a>
|
|
106
|
+
## Model Experience
|
|
107
|
+
|
|
108
|
+
### Child-agent history and envelope
|
|
109
|
+
|
|
110
|
+
#### What the model sees
|
|
111
|
+
|
|
112
|
+
The child receives the parent's balanced completed-turn prefix, then the new task content verbatim. A configured persona shadows prompt text in the child's fresh scope; a tool restriction filters its global wire schemas, executable lookup, and PTC mode SDK bindings but not standalone guidance. The parent's tool view and authority are not inherited; an optional structured-output request adds a child-only contract; the parent's current in-flight turn is excluded.
|
|
113
|
+
|
|
114
|
+
#### Token effect
|
|
115
|
+
|
|
116
|
+
Forking duplicates retained completed history into the child's request, which then accumulates its own tokens independently. A persona changes repeated prompt cost; filtering changes schema or generated SDK cost; a first-turn fork has no inherited history.
|
|
117
|
+
|
|
118
|
+
#### KV Cache effect
|
|
119
|
+
|
|
120
|
+
The child may reuse the inherited byte-identical prefix under the same provider and model. Persona, tool-filter, generated-SDK, or route changes may invalidate reuse before inherited history; later child history is append-only. Continuable messaging adds no child-only system-prompt section or tool schema; the parent id and return guidance follow inherited history in the initial user task ([cache-preserving fork Agent Note](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md)).
|
|
121
|
+
|
|
122
|
+
### Parent tool result, indirectly
|
|
123
|
+
|
|
124
|
+
#### What the model sees
|
|
125
|
+
|
|
126
|
+
Through `dsh-tool-subagent`, the parent first receives the child session id, then a completion notice with its final answer. Child-authored messages arrive through `send_message`; the inherited prefix and internal work remain in the child session.
|
|
127
|
+
|
|
128
|
+
#### Token effect
|
|
129
|
+
|
|
130
|
+
Parent input grows by one data-dependent final result retained until compaction.
|
|
131
|
+
|
|
132
|
+
#### KV Cache effect
|
|
133
|
+
|
|
134
|
+
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
|
|
135
|
+
|
|
136
|
+
## Known Limitations and Deferred Work
|
|
137
|
+
|
|
138
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
These limits define when the backend is the wrong choice; they are current package constraints.
|
|
142
|
+
|
|
143
|
+
- **The seed is a one-time snapshot** — the child sees the parent's completed turns as of the fork and nothing the parent logs afterwards; there is no live context sharing.
|
|
144
|
+
- **Prefix reuse depends on matching request inputs** — parent and child messaging definitions match byte for byte; explicit persona, tool filtering, generated-SDK, or route changes can still break equality. Rationale: the [cache-preserving fork Agent Note](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md).
|
|
145
|
+
- **Shipped fork tools do not expose child LLM route selection** — they inherit the parent's provider and model so the copied history remains eligible for KV Cache reuse. Route selection stays disabled until a change can preserve reuse or expose a bounded recomputation cost.
|
|
146
|
+
|
|
147
|
+
<a id="dev-note"></a>
|
|
148
|
+
### Dev Note
|
|
149
|
+
|
|
150
|
+
<details>
|
|
151
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
152
|
+
|
|
153
|
+
None.
|
|
154
|
+
|
|
155
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向用户与维护者的进程内 fork subagent 后端说明,用于选择、配置或排查以父级已完成轮次作初始内容的子 agent(智能体)。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @qilin-agent/subagent-fork-in-process
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
`dsh-subagent-fork-in-process` 是一个进程内 subagent 后端:它以父级已完成的对话轮次作为每个子 agent 的初始内容——子 agent 能看到所有已完成轮次,但看不到进行中的轮次,因此后续工作可以在对话基础上继续,而无需重复提供对话内容。委派工具以 `fork` 提供方名称找到它,其行为与 spawn 后端一致,唯一差异是会话初始内容。当子任务延续当前对话时选择它;当子 agent 必须独立运行时选择 spawn。初始内容是 fork 时的一次性快照:此后父级记录的任何内容都不会到达子 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
|
+
当委派的工作必须建立在父级对话之上时,挂载此后端。常用路径与 spawn 相同:加载 subagent 服务与本后端,再把 `dsh-tool-subagent` 之类的委派工具指向 `fork` 提供方。
|
|
29
|
+
|
|
30
|
+
### 何时选择
|
|
31
|
+
|
|
32
|
+
当子 agent 需要对话的已完成轮次时——后续分析、审查、延续——选择 fork。当子 agent 应全新开始时选择 spawn;当子 agent 不能共享本进程时选择进程外后端。初始内容只传递对话历史:子 agent 仍获得全新的工具作用域,且不继承父级的任何权限。
|
|
33
|
+
|
|
34
|
+
### 初始内容边界
|
|
35
|
+
|
|
36
|
+
初始内容止于父级最后一个已完成的轮次。subagent 启动时,父级当前的工具调用轮次仍在进行,因此该进行中的轮次绝不会被包含;在第一个已完成轮次之前,初始内容为空,子 agent 的行为与全新 spawn 相同。
|
|
37
|
+
|
|
38
|
+
### 最小配置
|
|
39
|
+
|
|
40
|
+
先加载 subagent 服务与本后端,再配置一个委派工具。此组合暴露由 fork 支撑的 `subagent` 工具:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
- name: '@qilin-agent/subagent'
|
|
44
|
+
- name: '@qilin-agent/subagent-fork-in-process'
|
|
45
|
+
- name: '@qilin-agent/tool-subagent'
|
|
46
|
+
config:
|
|
47
|
+
provider: fork
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| 字段 | 默认值 | 含义 |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `providerName` | `fork` | 注册到 `ctx.subagents` 的提供方名称 |
|
|
53
|
+
|
|
54
|
+
生成的[配置目录](../../../docs/config-catalog.zh.md#qilin-agentsubagent-fork-in-process)是每个受支持字段及其 JSDoc 的穷尽式真源。
|
|
55
|
+
|
|
56
|
+
### 一次 fork 委派会做什么
|
|
57
|
+
|
|
58
|
+
一次工具调用创建后台子 agent 并立即返回子会话 ID。子级在自己的会话中工作,父级通过完成通知收到其最终答案。子级也可以通过 `send_message` 发送消息。被拒绝的启动不会留下已发布的子 agent;工作流等程序调用方可以直接等待 activation 的结果。
|
|
59
|
+
|
|
60
|
+
-----
|
|
61
|
+
|
|
62
|
+
<a id="understand-the-implementation"></a>
|
|
63
|
+
## 理解实现
|
|
64
|
+
|
|
65
|
+
<details>
|
|
66
|
+
<summary>实现细节——点击展开</summary>
|
|
67
|
+
|
|
68
|
+
本节解释后端背后的设计决策,以及[使用本包](#use-this-package)中行为的来源。
|
|
69
|
+
|
|
70
|
+
### 设计理念
|
|
71
|
+
|
|
72
|
+
本后端把父级日志中已配平的已完成轮次前缀作为子会话初始内容。subagent 服务记录继承范围,因此结果只包含子级自己的输出。
|
|
73
|
+
|
|
74
|
+
### 源码地图
|
|
75
|
+
|
|
76
|
+
| 文件 | 职责 |
|
|
77
|
+
|---|---|
|
|
78
|
+
| [`src/index.ts`](src/index.ts) | 提供方注册:前缀计算、`Config` schema、能力声明 |
|
|
79
|
+
|
|
80
|
+
### 运行流程
|
|
81
|
+
|
|
82
|
+
`prepareContinuable()` 在创建时捕获一次父级已完成轮次前缀。`startActivation()` 以此创建子 agent,并由 subagent 服务应用 persona、工具过滤与本次 activation 的结构化输出设置。提供方声明与 spawn 相同的 `agentOptions`、输出、深度、过滤及 persona 能力。
|
|
83
|
+
|
|
84
|
+
### 生命周期绑定
|
|
85
|
+
|
|
86
|
+
委派工具以后台 activation 创建子级,并返回稳定的子会话 ID。父级与子级共享相同的消息工具定义及顺序;父级 ID 与返回指导位于继承历史之后的初始任务中。工作流以调用方收集模式等待结果,不向父级发送完成通知。
|
|
87
|
+
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
-----
|
|
91
|
+
|
|
92
|
+
<a id="further-exploration"></a>
|
|
93
|
+
## 进一步探索
|
|
94
|
+
|
|
95
|
+
当包级约定不够用时阅读以下页面;它们从共享 subagent 模型进入兄弟后端,以及保留继承请求前缀的设计证据。
|
|
96
|
+
|
|
97
|
+
- [Subagent 子系统](../../../docs/subsystems/subagent.zh.md)——启动请求、结果、提供方约定与进程内深度和初始内容。
|
|
98
|
+
- [dsh-subagent-spawn-in-process](../subagent-spawn-in-process/README.zh.md)——全新子级的兄弟后端。
|
|
99
|
+
- [dsh-tool-subagent](../tool-subagent/README.zh.md)——指向该提供方的面向模型委派工具。
|
|
100
|
+
- [生成配置目录](../../../docs/config-catalog.zh.md#qilin-agentsubagent-fork-in-process)——每个受支持配置字段及其源声明。
|
|
101
|
+
- [Fork child 保留 parent 请求前缀](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.zh.md)——可继续 fork 为何保留继承的请求前缀。
|
|
102
|
+
|
|
103
|
+
-----
|
|
104
|
+
|
|
105
|
+
<a id="model-experience"></a>
|
|
106
|
+
## 模型体验
|
|
107
|
+
|
|
108
|
+
### 子 agent 历史与包络
|
|
109
|
+
|
|
110
|
+
#### 模型看到什么
|
|
111
|
+
|
|
112
|
+
子 agent 先接收由父级已配平的已完成轮次构成的前缀,再逐字接收新的任务内容。配置的 persona 会在子 agent 的全新作用域中遮蔽提示词文本;工具限制会过滤其全局协议 schema、可执行工具查找与 PTC mode SDK 绑定,但不影响独立指导内容。父级的工具视图与权限不会被继承;可选的结构化输出请求会添加仅属于子 agent 的约定;父级当前进行中的轮次会被排除。
|
|
113
|
+
|
|
114
|
+
#### Token 影响
|
|
115
|
+
|
|
116
|
+
fork 会把保留的已完成历史复制到子 agent 的请求中,子 agent 随后独立累积自己的 token。persona 会改变重复提示词的成本;过滤会改变 schema 或生成 SDK 的成本;首轮 fork 没有继承历史。
|
|
117
|
+
|
|
118
|
+
#### KV Cache 影响
|
|
119
|
+
|
|
120
|
+
在提供方与模型相同的前提下,子 agent 可以复用继承的逐字节相同前缀。persona、工具过滤、生成 SDK 或路由变化可能在继承历史之前使复用失效;后续子 agent 历史仅追加。可继续消息不会增加子级专属的系统提示词区段或工具 schema;父级 ID 与返回指导在初始用户任务中位于继承历史之后(见[保持 fork 缓存的 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.zh.md))。
|
|
121
|
+
|
|
122
|
+
### 父级工具结果(间接)
|
|
123
|
+
|
|
124
|
+
#### 模型看到什么
|
|
125
|
+
|
|
126
|
+
父级通过 `dsh-tool-subagent` 先收到子会话 ID,随后收到包含最终答案的完成通知。子级自行编写的消息通过 `send_message` 到达;继承的前缀与内部工作保留在子会话中。
|
|
127
|
+
|
|
128
|
+
#### Token 影响
|
|
129
|
+
|
|
130
|
+
父级输入增加一个取决于数据的最终结果,并保留到上下文压缩(context compaction)为止。
|
|
131
|
+
|
|
132
|
+
#### KV Cache 影响
|
|
133
|
+
|
|
134
|
+
仅追加;新增可见内容位于可复用请求前缀之后,不会使现有 KV Cache 条目失效。
|
|
135
|
+
|
|
136
|
+
## 已知限制与延期工作
|
|
137
|
+
|
|
138
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
这些限制说明何时选择该后端是错误的;它们是当前包约束。
|
|
142
|
+
|
|
143
|
+
- **初始内容是一次性快照**——子 agent 只能看到 fork 时父级已完成的轮次,看不到父级此后记录的任何内容;不会实时共享上下文。
|
|
144
|
+
- **前缀复用取决于请求输入是否匹配**——父级与子级的消息定义都逐字节相同;显式 persona、工具过滤、生成 SDK 或路由变化仍可破坏相等性。理由见[保持 fork 缓存的 Agent Note](../../../.agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.zh.md)。
|
|
145
|
+
- **随附 fork 工具不公开子级 LLM(大语言模型)路由选择**——它们继承父级提供方与模型,使复制的历史仍有资格复用 KV Cache。在某项改动能保留复用或公开有界重算成本前,路由选择保持禁用。
|
|
146
|
+
|
|
147
|
+
<a id="dev-note"></a>
|
|
148
|
+
### 开发备注
|
|
149
|
+
|
|
150
|
+
<details>
|
|
151
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
152
|
+
|
|
153
|
+
无。
|
|
154
|
+
|
|
155
|
+
</details>
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import z from "@qilin-agent/schemastery";
|
|
2
|
+
//#region lib/types/index.js
|
|
3
|
+
/**
|
|
4
|
+
* The in-process FORK subagent backend: registers a {@link SubagentProvider} on
|
|
5
|
+
* `ctx.subagents` that runs each child as a child {@link Agent} SEEDED with a prefix of the
|
|
6
|
+
* parent's session log — so the child inherits the parent's conversation context instead of
|
|
7
|
+
* starting fresh. The seed ends at the last `turn/end`: the current tool-call turn is
|
|
8
|
+
* unbalanced and cannot be replayed as a valid child session.
|
|
9
|
+
* @module @qilin-agent/subagent-fork-in-process
|
|
10
|
+
*/
|
|
11
|
+
const name = "subagent-fork-in-process";
|
|
12
|
+
const inject = ["subagents"];
|
|
13
|
+
const Config = z.object({ providerName: z.string().default("fork") });
|
|
14
|
+
/**
|
|
15
|
+
* The balanced completed-turn prefix of `parent`'s log: every event up to and including the
|
|
16
|
+
* last `turn/end`. The in-flight turn is excluded; before any completed turn the child starts
|
|
17
|
+
* fresh. Because live sequence numbers equal array indexes, the result remains a valid seed
|
|
18
|
+
* beginning at sequence zero.
|
|
19
|
+
* @param parent - the agent whose session log to slice.
|
|
20
|
+
* @returns the seed events, contiguous from seq 0; empty when no turn has completed.
|
|
21
|
+
*/
|
|
22
|
+
function completedTurnPrefix(parent) {
|
|
23
|
+
const events = parent.session.snapshotEvents();
|
|
24
|
+
const lastEnd = events.findLast((e) => e.type === "turn/end");
|
|
25
|
+
if (lastEnd === void 0) return [];
|
|
26
|
+
return events.slice(0, lastEnd.seq + 1);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The fork provider. Supports `depthLimit` and `outputSchema` (via the shared
|
|
30
|
+
* in-process structured runtime), `agentOptions` (merged over the parent
|
|
31
|
+
* route), and `toolFilter`/`persona` (scoped restrict() and a scoped shadowing
|
|
32
|
+
* persona section).
|
|
33
|
+
*/
|
|
34
|
+
var ForkInProcessProvider = class {
|
|
35
|
+
name;
|
|
36
|
+
capabilities = {
|
|
37
|
+
agentOptions: true,
|
|
38
|
+
outputSchema: true,
|
|
39
|
+
depthLimit: true,
|
|
40
|
+
toolFilter: true,
|
|
41
|
+
persona: true
|
|
42
|
+
};
|
|
43
|
+
inheritsParentContext = true;
|
|
44
|
+
constructor(name) {
|
|
45
|
+
this.name = name;
|
|
46
|
+
}
|
|
47
|
+
prepareContinuable(request) {
|
|
48
|
+
const seed = completedTurnPrefix(request.parent);
|
|
49
|
+
return Promise.resolve(seed.length > 0 ? { seed } : {});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
function apply(ctx, config) {
|
|
53
|
+
ctx.subagents.registerProvider(new ForkInProcessProvider(config.providerName));
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { Config, apply, inject, name };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The in-process FORK subagent backend: registers a {@link SubagentProvider} on
|
|
3
|
+
* `ctx.subagents` that runs each child as a child {@link Agent} SEEDED with a prefix of the
|
|
4
|
+
* parent's session log — so the child inherits the parent's conversation context instead of
|
|
5
|
+
* starting fresh. The seed ends at the last `turn/end`: the current tool-call turn is
|
|
6
|
+
* unbalanced and cannot be replayed as a valid child session.
|
|
7
|
+
* @module @qilin-agent/subagent-fork-in-process
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '@qilin-agent/kylin';
|
|
10
|
+
import z from '@qilin-agent/schemastery';
|
|
11
|
+
export declare const name = "subagent-fork-in-process";
|
|
12
|
+
export declare const inject: string[];
|
|
13
|
+
/** Config: the registry name to register the provider under. */
|
|
14
|
+
export interface Config {
|
|
15
|
+
/** Provider name on `ctx.subagents` (default `fork`). */
|
|
16
|
+
providerName: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const Config: z<Config>;
|
|
19
|
+
export declare function apply(ctx: Context, config: Config): void;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qilin-agent/subagent-fork-in-process",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"description": "In-process fork subagent backend: runs a child agent seeded with a prefix of the parent's log",
|
|
4
|
+
"version": "3.1.4",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/kkutysllb/QiLin.git",
|
|
11
|
+
"directory": "packages/subagent/subagent-fork-in-process"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "lib/index.js",
|
|
18
|
+
"types": "lib/types/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./lib/types/index.d.ts",
|
|
22
|
+
"default": "./lib/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./src/*": "./src/*",
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"lib/index.js",
|
|
29
|
+
"lib/types/**/*.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@qilin-agent/agent": "3.1.4",
|
|
34
|
+
"@qilin-agent/subagent": "3.1.4",
|
|
35
|
+
"@qilin-agent/kylin": "~4.0.3",
|
|
36
|
+
"@qilin-agent/session": "3.1.4"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@qilin-agent/schemastery": "~3.18.3"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@qilin-agent/kylin-plugin-loader": "~1.0.4",
|
|
43
|
+
"@qilin-agent/agent": "3.1.4",
|
|
44
|
+
"@qilin-agent/agent-loop": "3.1.4",
|
|
45
|
+
"@qilin-agent/agent-loop-testkit": "3.1.4",
|
|
46
|
+
"@qilin-agent/subagent": "3.1.4",
|
|
47
|
+
"@qilin-agent/subagent-spawn-in-process": "3.1.4",
|
|
48
|
+
"@qilin-agent/llm": "3.1.4",
|
|
49
|
+
"@qilin-agent/kylin": "~4.0.3",
|
|
50
|
+
"@qilin-agent/session-projection": "3.1.4",
|
|
51
|
+
"@qilin-agent/session": "3.1.4"
|
|
52
|
+
}
|
|
6
53
|
}
|