@qilin-agent/experimental-agent-team 3.1.3 → 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/README.i18n.yaml +60 -60
- package/README.md +12 -14
- package/README.zh.md +11 -13
- package/lib/index.js +925 -1145
- package/lib/typert.host.js +9 -9
- package/lib/typert.remote-client.js +2 -2
- package/lib/types/index.d.ts +12 -6
- package/lib/types/index.js +52 -18
- package/lib/types/lifecycle.d.ts +12 -0
- package/lib/types/lifecycle.js +18 -0
- package/lib/types/roster.d.ts +0 -6
- package/lib/types/roster.js +7 -18
- package/lib/types/types.d.ts +3 -6
- package/package.json +23 -23
- package/lib/types/mailbox.d.ts +0 -78
- package/lib/types/mailbox.js +0 -293
package/README.i18n.yaml
CHANGED
|
@@ -5,99 +5,99 @@
|
|
|
5
5
|
/:
|
|
6
6
|
en: 6dbca19f6b32549f
|
|
7
7
|
zh: dae9c49eab8f6fee
|
|
8
|
-
/qilin-experimental-agent-team:
|
|
9
|
-
en:
|
|
10
|
-
zh:
|
|
11
|
-
/qilin-experimental-agent-team/summary:
|
|
12
|
-
en:
|
|
13
|
-
zh:
|
|
14
|
-
/qilin-experimental-agent-team/table-of-contents:
|
|
8
|
+
/qilin-agent-experimental-agent-team:
|
|
9
|
+
en: 4402b42eb6f211c1
|
|
10
|
+
zh: 8ac92563ac79d88a
|
|
11
|
+
/qilin-agent-experimental-agent-team/summary:
|
|
12
|
+
en: 287cc2a4386252f2
|
|
13
|
+
zh: 25729a2ac8565d15
|
|
14
|
+
/qilin-agent-experimental-agent-team/table-of-contents:
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
17
|
-
/qilin-experimental-agent-team/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
20
|
-
/qilin-experimental-agent-team/use-this-package/when-to-choose-it:
|
|
17
|
+
/qilin-agent-experimental-agent-team/use-this-package:
|
|
18
|
+
en: dd1424b30f3cfb4e
|
|
19
|
+
zh: 184ef8c784fbb2ca
|
|
20
|
+
/qilin-agent-experimental-agent-team/use-this-package/when-to-choose-it:
|
|
21
21
|
en: 8da318ac2f4343d7
|
|
22
22
|
zh: b31a399d6e3fd64e
|
|
23
|
-
/qilin-experimental-agent-team/use-this-package/smallest-working-setup:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
26
|
-
/qilin-experimental-agent-team/use-this-package/teammates:
|
|
23
|
+
/qilin-agent-experimental-agent-team/use-this-package/smallest-working-setup:
|
|
24
|
+
en: 067776ea2c4f9776
|
|
25
|
+
zh: 4a73fe617591dd61
|
|
26
|
+
/qilin-agent-experimental-agent-team/use-this-package/teammates:
|
|
27
27
|
en: 93bba70f00d8015a
|
|
28
28
|
zh: b66c4c2b1a91facf
|
|
29
|
-
/qilin-experimental-agent-team/use-this-package/messages-between-teammates:
|
|
30
|
-
en:
|
|
31
|
-
zh:
|
|
32
|
-
/qilin-experimental-agent-team/use-this-package/shared-task-board:
|
|
29
|
+
/qilin-agent-experimental-agent-team/use-this-package/messages-between-teammates:
|
|
30
|
+
en: 14ae48980c5e7fd0
|
|
31
|
+
zh: dc40cb0c15789d14
|
|
32
|
+
/qilin-agent-experimental-agent-team/use-this-package/shared-task-board:
|
|
33
33
|
en: 73682f0d2001b517
|
|
34
34
|
zh: 3744d82eb3b7fcb9
|
|
35
|
-
/qilin-experimental-agent-team/use-this-package/waiting-and-interruption:
|
|
36
|
-
en:
|
|
37
|
-
zh:
|
|
38
|
-
/qilin-experimental-agent-team/use-this-package/what-success-and-failure-look-like:
|
|
39
|
-
en:
|
|
40
|
-
zh:
|
|
41
|
-
/qilin-experimental-agent-team/understand-the-implementation:
|
|
35
|
+
/qilin-agent-experimental-agent-team/use-this-package/waiting-and-interruption:
|
|
36
|
+
en: 42c6d6e7175a930f
|
|
37
|
+
zh: eb077879ea52bd97
|
|
38
|
+
/qilin-agent-experimental-agent-team/use-this-package/what-success-and-failure-look-like:
|
|
39
|
+
en: a14116e6ef3b90fc
|
|
40
|
+
zh: 9b1984cfcb4501d6
|
|
41
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation:
|
|
42
42
|
en: 6a18034f1ccc247a
|
|
43
43
|
zh: e08b0eb0ccb41ea8
|
|
44
|
-
/qilin-experimental-agent-team/understand-the-implementation/design-philosophy:
|
|
45
|
-
en:
|
|
46
|
-
zh:
|
|
47
|
-
/qilin-experimental-agent-team/understand-the-implementation/source-map:
|
|
48
|
-
en:
|
|
49
|
-
zh:
|
|
50
|
-
/qilin-experimental-agent-team/understand-the-implementation/team-identity-and-roster:
|
|
44
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/design-philosophy:
|
|
45
|
+
en: 5ed15e91ee5575cb
|
|
46
|
+
zh: e34618a49056b439
|
|
47
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/source-map:
|
|
48
|
+
en: b4617379acb1800c
|
|
49
|
+
zh: d0b2846a7117cdbd
|
|
50
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/team-identity-and-roster:
|
|
51
51
|
en: 85f97723e45e43de
|
|
52
52
|
zh: def66721e21339cc
|
|
53
|
-
/qilin-experimental-agent-team/understand-the-implementation/
|
|
54
|
-
en:
|
|
55
|
-
zh:
|
|
56
|
-
/qilin-experimental-agent-team/understand-the-implementation/shared-task-board:
|
|
53
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/direct-steering:
|
|
54
|
+
en: bc66f052a2290fe1
|
|
55
|
+
zh: 2deb7e0847349f3c
|
|
56
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/shared-task-board:
|
|
57
57
|
en: 2dc37ba97a8a7178
|
|
58
58
|
zh: 96bd24033030e19d
|
|
59
|
-
/qilin-experimental-agent-team/understand-the-implementation/waiting-and-interruption:
|
|
60
|
-
en:
|
|
61
|
-
zh:
|
|
62
|
-
/qilin-experimental-agent-team/understand-the-implementation/durability-model:
|
|
63
|
-
en:
|
|
64
|
-
zh:
|
|
65
|
-
/qilin-experimental-agent-team/understand-the-implementation/disposal:
|
|
66
|
-
en:
|
|
67
|
-
zh:
|
|
68
|
-
/qilin-experimental-agent-team/further-exploration:
|
|
59
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/waiting-and-interruption:
|
|
60
|
+
en: 94e09c51cec44b0c
|
|
61
|
+
zh: dbbead1b8de96a3a
|
|
62
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/durability-model:
|
|
63
|
+
en: 40cdf38b158a6a99
|
|
64
|
+
zh: 78b6a0a9cf9dda25
|
|
65
|
+
/qilin-agent-experimental-agent-team/understand-the-implementation/disposal:
|
|
66
|
+
en: 47588f975c83fe96
|
|
67
|
+
zh: fd25c61a7dcc9b01
|
|
68
|
+
/qilin-agent-experimental-agent-team/further-exploration:
|
|
69
69
|
en: 7bf1185e46e3afc7
|
|
70
70
|
zh: 99ffb9a0e8997b2f
|
|
71
|
-
/qilin-experimental-agent-team/further-exploration/browser-projection:
|
|
71
|
+
/qilin-agent-experimental-agent-team/further-exploration/browser-projection:
|
|
72
72
|
en: 96186095e80f835f
|
|
73
73
|
zh: 2f6d699872a07730
|
|
74
|
-
/qilin-experimental-agent-team/further-exploration/browser-write-bridge:
|
|
74
|
+
/qilin-agent-experimental-agent-team/further-exploration/browser-write-bridge:
|
|
75
75
|
en: af8b1417a9566469
|
|
76
76
|
zh: b9ddc7d585d34be5
|
|
77
|
-
/qilin-experimental-agent-team/model-experience:
|
|
77
|
+
/qilin-agent-experimental-agent-team/model-experience:
|
|
78
78
|
en: 215e7ba838619b7b
|
|
79
79
|
zh: a311da3843709f90
|
|
80
|
-
/qilin-experimental-agent-team/model-experience/peer-messages:
|
|
80
|
+
/qilin-agent-experimental-agent-team/model-experience/peer-messages:
|
|
81
81
|
en: 7a72088145dd45ec
|
|
82
82
|
zh: 6763071c604c2edd
|
|
83
|
-
/qilin-experimental-agent-team/model-experience/peer-messages/what-the-model-sees:
|
|
83
|
+
/qilin-agent-experimental-agent-team/model-experience/peer-messages/what-the-model-sees:
|
|
84
84
|
en: 4f9110ba058f25cd
|
|
85
85
|
zh: cf820293929ea993
|
|
86
|
-
/qilin-experimental-agent-team/model-experience/peer-messages/token-effect:
|
|
87
|
-
en:
|
|
88
|
-
zh:
|
|
89
|
-
/qilin-experimental-agent-team/model-experience/peer-messages/kv-cache-effect:
|
|
86
|
+
/qilin-agent-experimental-agent-team/model-experience/peer-messages/token-effect:
|
|
87
|
+
en: deacf0f9e654cff5
|
|
88
|
+
zh: 2a30a685b2e3a04f
|
|
89
|
+
/qilin-agent-experimental-agent-team/model-experience/peer-messages/kv-cache-effect:
|
|
90
90
|
en: ff845d434b857afe
|
|
91
91
|
zh: 04479bddf7650ede
|
|
92
|
-
/qilin-experimental-agent-team/known-limitations-and-deferred-work:
|
|
92
|
+
/qilin-agent-experimental-agent-team/known-limitations-and-deferred-work:
|
|
93
93
|
en: 016afbeb35dd7448
|
|
94
94
|
zh: 909b7ae6796314b0
|
|
95
|
-
/qilin-experimental-agent-team/known-limitations-and-deferred-work/dev-note:
|
|
95
|
+
/qilin-agent-experimental-agent-team/known-limitations-and-deferred-work/dev-note:
|
|
96
96
|
en: 498e4cf9fe5741a7
|
|
97
97
|
zh: 9d2bab630e655c99
|
|
98
|
-
/qilin-experimental-agent-team/known-limitations-and-deferred-work/dev-note/promotion:
|
|
98
|
+
/qilin-agent-experimental-agent-team/known-limitations-and-deferred-work/dev-note/promotion:
|
|
99
99
|
en: 3d126e3b1015e4ce
|
|
100
100
|
zh: 22f0d18e2ce5c30f
|
|
101
|
-
/qilin-experimental-agent-team/known-limitations-and-deferred-work/dev-note/future-directions:
|
|
101
|
+
/qilin-agent-experimental-agent-team/known-limitations-and-deferred-work/dev-note/future-directions:
|
|
102
102
|
en: 38eadeacd73b9c02
|
|
103
103
|
zh: 05c5b55022e0b8d9
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
`qilin-experimental-agent-team` turns one coding session into a small working team: the session's agent becomes the Lead, creates named teammates for delegated work, exchanges durable messages with them, and tracks shared tasks on a common board. Messages and task state survive crashes, reloads, and interruptions
|
|
12
|
+
`qilin-experimental-agent-team` turns one coding session into a small working team: the session's agent becomes the Lead, creates named teammates for delegated work, exchanges durable messages with them, and tracks shared tasks on a common board. Messages and task state survive crashes, reloads, and interruptions: a message steered at an offline teammate cold-resumes it. It provides no tools of its own — mount the sibling `qilin-experimental-tool-agent-team` so the model can create teammates, message them, and use the task board. It is published under its experimental name, carries no stability promise, and needs durable session storage to activate.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -50,7 +50,6 @@ With the tools installed, the model does the rest on request — for example, "c
|
|
|
50
50
|
|---|---|---|
|
|
51
51
|
| `maxMembers` | `16` | Maximum teammates a team may ever create, including failed ones |
|
|
52
52
|
| `maxTasks` | `256` | Maximum active tasks on the board |
|
|
53
|
-
| `maxPendingMessagesPerMember` | `64` | Maximum queued messages for one member |
|
|
54
53
|
| `maxMessageBytes` | `65,536` | Maximum size of one sent message |
|
|
55
54
|
| `disposalTimeoutMs` | `5,000` | Time allowed for shutdown cleanup |
|
|
56
55
|
|
|
@@ -66,9 +65,9 @@ Only the Lead can create teammates or interrupt them.
|
|
|
66
65
|
|
|
67
66
|
### Messages between teammates
|
|
68
67
|
|
|
69
|
-
Any member can send a message to any other member or to the Lead. A live member receives it
|
|
68
|
+
Any member can send a message to any other member or to the Lead. A live member receives it at its next step boundary; an idle or inactive member is started or cold-resumed so the message still arrives. The message becomes durable in the target's own Session log, so it survives a crash between delivery and model processing.
|
|
70
69
|
|
|
71
|
-
Every message uses Steer: a running target receives it at the nearest step boundary, an idle target starts a turn, and an inactive teammate cold-resumes. The sender
|
|
70
|
+
Every message uses Steer: a running target receives it at the nearest step boundary, an idle target starts a turn, and an inactive teammate cold-resumes. The sender either sees the accepted message id or one specific rejection: an unknown target name, a self-addressed message, an oversized message, or cancellation before acceptance. A successful send is already durable, so it must never be resent.
|
|
72
71
|
|
|
73
72
|
### Shared task board
|
|
74
73
|
|
|
@@ -82,11 +81,11 @@ File hints produce warnings when two in-progress tasks plan to touch overlapping
|
|
|
82
81
|
|
|
83
82
|
A member can wait for the next team change — a teammate's status, an incoming message, or a task update — instead of polling repeatedly; the wait reports only whether it timed out, and the caller re-reads the current state afterward.
|
|
84
83
|
|
|
85
|
-
The Lead can stop a teammate's current turn without deleting its
|
|
84
|
+
The Lead can stop a teammate's current turn without deleting messages already in its inbox; task ownership is unchanged.
|
|
86
85
|
|
|
87
86
|
### What success and failure look like
|
|
88
87
|
|
|
89
|
-
Success looks like a teammate appearing in the roster, a message reporting
|
|
88
|
+
Success looks like a teammate appearing in the roster, a message reporting its accepted id, and task revisions advancing with each change. Likely failures are reported as specific errors instead of silently corrupting state: sending to a name that is not a member, claiming a task that is not ready, editing with an outdated revision, or creating a teammate beyond the member limit.
|
|
90
89
|
|
|
91
90
|
-----
|
|
92
91
|
|
|
@@ -102,7 +101,7 @@ This section explains the design decisions behind the service and points at the
|
|
|
102
101
|
|
|
103
102
|
The service is built on one separation and three commitments:
|
|
104
103
|
|
|
105
|
-
- **Durable log, derived state.** The Lead Session log is the single source of truth; roster,
|
|
104
|
+
- **Durable log, derived state.** The Lead Session log is the single source of truth; roster, message, and task state are replayed from it on every read.
|
|
106
105
|
- **Process-local ownership.** All coordination lives in one process; the guarantee is retry plus de-duplication, never cross-process consensus.
|
|
107
106
|
- **Explicit authority.** Every service method takes the exact live calling `Agent`; only the Lead spawns, reassigns, or interrupts.
|
|
108
107
|
- **Bounds that fail loud.** Every limit is a validated deployment value, and exhaustion reports a typed error instead of reusing an id or name.
|
|
@@ -115,7 +114,6 @@ The [Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-
|
|
|
115
114
|
|---|---|
|
|
116
115
|
| [`src/index.ts`](src/index.ts) | Plugin entry: `Config` schema, service registration, recovery scheduling |
|
|
117
116
|
| [`src/roster.ts`](src/roster.ts) | Team identity, membership resolution, provisioning, and roster teardown |
|
|
118
|
-
| [`src/mailbox.ts`](src/mailbox.ts) | Durable queue, target-local dispatch, acknowledgement, and recovery |
|
|
119
117
|
| [`src/task-board.ts`](src/task-board.ts) | Task CAS commands, DAG validation, and derived views |
|
|
120
118
|
| [`src/journal.ts`](src/journal.ts) | Serialized Lead-log transactions and commit notification |
|
|
121
119
|
| [`src/projection.ts`](src/projection.ts) | Strict replay projection that decodes and validates Team events and publishes the `agentTeam` client view |
|
|
@@ -128,11 +126,11 @@ The [Agent Teams Agent Note](../../../.agents/notes/implemented/feature/2026-08-
|
|
|
128
126
|
|
|
129
127
|
Every ordinary runtime root is the implicit Lead of a Team whose `TeamId` equals its `SessionId`; there is no creation event, and durable state begins with the first member, message, or task record. `spawnTeammate()` first appends and flushes a `provisioning` member record, then asks the configured provider to create the reserved child; a provider failure appends a durable `failed` member. A fresh child starts with no Lead history; a fork child captures the Lead's completed-turn prefix once. Recovery reconciles an unterminated provisioning record against the child's independently persisted Session: a matching direct-parent and continuable descriptor plus a recorded initial user message produces `active`, and anything else produces `failed`. If recovery wins a same-process race, the creator accepts the terminal state or reports `TEAM_PROVISIONING_CONFLICT` and drains the child. Names are reserved by the first provisioning record and never reused.
|
|
130
128
|
|
|
131
|
-
###
|
|
129
|
+
### Direct steering
|
|
132
130
|
|
|
133
|
-
`sendMessage()` validates peer membership,
|
|
131
|
+
`sendMessage()` validates peer membership, resolves the target, mints the message identity, and measures the framed content against `maxMessageBytes` before anything is delivered. The target message begins with `Team message <id> from <name>:` and keeps the same id and sender in `TeamMessageSource`, so the receiving model and the durable log agree on the sender's identity. Lead delivery calls `Agent.steer()` directly; teammate delivery uses the continuation owner's host-only Steer path, which authorizes the Lead-to-child edge and cold-resumes inactive targets. A send that cannot be admitted fails with its own error instead of being retained, so the sender never has to reason about a retry queue.
|
|
134
132
|
|
|
135
|
-
|
|
133
|
+
Sibling messages never impersonate the Lead through the public adjacent-Agent messaging operation.
|
|
136
134
|
|
|
137
135
|
### Shared task board
|
|
138
136
|
|
|
@@ -140,15 +138,15 @@ Tasks are complete versioned snapshots; every mutation carries `expectedRevision
|
|
|
140
138
|
|
|
141
139
|
### Waiting and interruption
|
|
142
140
|
|
|
143
|
-
`waitForChange()` waits for one roster, task,
|
|
141
|
+
`waitForChange()` waits for one roster, task, message, or live-status edge that occurs after registration, from ten seconds through one hour, and reports only whether it timed out; runtime disposal releases current waits. Cancellation preserves an Error reason or reports a non-Error reason through `TEAM_WAIT_ABORTED`. `interrupt()` is Lead-only and delegates to the continuable-subagent interrupt path, which cancels only a live teammate's current turn with `keepInbox`; it neither releases task ownership nor deletes durable mail.
|
|
144
142
|
|
|
145
143
|
### Durability model
|
|
146
144
|
|
|
147
|
-
Team events are appended to the exact live Lead Session and flushed before the operation reports success or wakes waiters. `team/member
|
|
145
|
+
Team events are appended to the exact live Lead Session and flushed before the operation reports success or wakes waiters. `team/member` and `team/task` are log-only, and the historical `team/message/queued` and `team/message/delivered` records stay readable: none of them enters the conversation surface, so derived model history is untouched by coordination records. Session event `seq` and `time` own ordering and timing; snapshots do not duplicate them.
|
|
148
146
|
|
|
149
147
|
### Disposal
|
|
150
148
|
|
|
151
|
-
Disposal closes admission, aborts and awaits admitted
|
|
149
|
+
Disposal closes admission, aborts and awaits admitted send and creation transactions, then asks the continuation owner to release the roster's exact live direct children and their descendants; non-Team continuable children of the Lead remain untouched. Cleanup failures make disposal fail visibly, bounded by `disposalTimeoutMs`.
|
|
152
150
|
|
|
153
151
|
</details>
|
|
154
152
|
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
`qilin-experimental-agent-team` 把一个编码会话变成一个小型工作团队:会话中的 agent 成为 Lead,创建具名 teammate 处理委派的工作,与它们交换持久消息,并在公共任务板上跟踪共享任务。消息与任务状态能挺过崩溃、reload
|
|
12
|
+
`qilin-experimental-agent-team` 把一个编码会话变成一个小型工作团队:会话中的 agent 成为 Lead,创建具名 teammate 处理委派的工作,与它们交换持久消息,并在公共任务板上跟踪共享任务。消息与任务状态能挺过崩溃、reload 与中断:发给离线 teammate 的消息会把它冷恢复。它本身不提供任何工具——请挂载兄弟包 `qilin-experimental-tool-agent-team`,让模型能够创建 teammate、给它们发消息并使用任务板。它以实验性名称公开发布、不承诺稳定性,并且需要持久会话存储才能激活。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -50,7 +50,6 @@ kind: "package-reference"
|
|
|
50
50
|
|---|---|---|
|
|
51
51
|
| `maxMembers` | `16` | 一支团队最多可创建的 teammate 数,包括失败的 |
|
|
52
52
|
| `maxTasks` | `256` | 任务板上最多的活动任务数 |
|
|
53
|
-
| `maxPendingMessagesPerMember` | `64` | 单个成员最多可排队的消息数 |
|
|
54
53
|
| `maxMessageBytes` | `65,536` | 单条发送消息的最大尺寸 |
|
|
55
54
|
| `disposalTimeoutMs` | `5,000` | 关闭清理允许的时间 |
|
|
56
55
|
|
|
@@ -66,9 +65,9 @@ roster 显示每个成员的职责(`lead` 或 `teammate`)与当前状态:`
|
|
|
66
65
|
|
|
67
66
|
### teammate 之间的消息
|
|
68
67
|
|
|
69
|
-
任何成员都可以向任何其他成员或 Lead 发送消息。live
|
|
68
|
+
任何成员都可以向任何其他成员或 Lead 发送消息。live 成员会在下一个步骤边界收到;idle 或离线的成员会被启动或冷恢复,消息照常到达。消息落地在目标自己的会话日志里,因此在投递与模型处理之间发生崩溃也不会丢失。
|
|
70
69
|
|
|
71
|
-
每条消息都使用 Steer:running target 在最近的步骤边界收到消息,idle target 启动一个轮次,inactive teammate
|
|
70
|
+
每条消息都使用 Steer:running target 在最近的步骤边界收到消息,idle target 启动一个轮次,inactive teammate 则冷恢复。发送方要么拿到已接受的消息 id,要么拿到一个明确的拒绝:目标名不存在、给自己发消息、消息超出字节上限,或在接受前被取消。发送成功即已落库,因此绝不能重发。
|
|
72
71
|
|
|
73
72
|
### 共享任务板
|
|
74
73
|
|
|
@@ -82,11 +81,11 @@ roster 显示每个成员的职责(`lead` 或 `teammate`)与当前状态:`
|
|
|
82
81
|
|
|
83
82
|
成员可以等待下一次团队变化——teammate 的状态、新消息或任务更新——而不必反复轮询;等待只报告是否超时,调用方随后重新读取当前状态。
|
|
84
83
|
|
|
85
|
-
Lead 可以停止 teammate
|
|
84
|
+
Lead 可以停止 teammate 的当前轮次,而不会删除其 inbox 中已有的消息;任务归属不变。
|
|
86
85
|
|
|
87
86
|
### 成功与失败的表现
|
|
88
87
|
|
|
89
|
-
成功的表现是:teammate 出现在 roster
|
|
88
|
+
成功的表现是:teammate 出现在 roster 中、消息报告其被接受的 id、任务 revision 随每次变更递增。可能的失败会以具体错误报告,而不会悄悄破坏状态:发给不存在的成员名字、claim 尚未就绪的任务、用过期 revision 编辑、或超出成员上限创建 teammate。
|
|
90
89
|
|
|
91
90
|
-----
|
|
92
91
|
|
|
@@ -102,7 +101,7 @@ Lead 可以停止 teammate 的当前轮次,而不会删除其排队的消息
|
|
|
102
101
|
|
|
103
102
|
本服务建立在一个分离与三项承诺之上:
|
|
104
103
|
|
|
105
|
-
- **持久日志,派生状态。** Lead 会话日志是唯一真源;roster
|
|
104
|
+
- **持久日志,派生状态。** Lead 会话日志是唯一真源;roster、消息与任务状态每次读取都从中回放。
|
|
106
105
|
- **进程内归属。** 所有协作都位于单一进程;保证是重试加去重,绝不是跨进程共识。
|
|
107
106
|
- **显式权限。** 每个服务方法都接收确切的实时调用方 `Agent`;只有 Lead 可以 spawn、reassign 或 interrupt。
|
|
108
107
|
- **超出上限时明确失败。** 每个限制都是经过校验的部署值,耗尽时报告类型化错误,而不是复用 id 或名字。
|
|
@@ -115,7 +114,6 @@ Lead 可以停止 teammate 的当前轮次,而不会删除其排队的消息
|
|
|
115
114
|
|---|---|
|
|
116
115
|
| [`src/index.ts`](src/index.ts) | 插件入口:`Config` schema、服务注册、恢复调度 |
|
|
117
116
|
| [`src/roster.ts`](src/roster.ts) | Team 身份、成员关系解析、provisioning 与 roster 拆除 |
|
|
118
|
-
| [`src/mailbox.ts`](src/mailbox.ts) | 持久队列、目标本地投递、确认与恢复 |
|
|
119
117
|
| [`src/task-board.ts`](src/task-board.ts) | 任务 CAS 命令、DAG 校验与派生视图 |
|
|
120
118
|
| [`src/journal.ts`](src/journal.ts) | 串行化的 Lead 日志事务与提交通知 |
|
|
121
119
|
| [`src/projection.ts`](src/projection.ts) | 解码并校验 Team 事件、发布 `agentTeam` 客户端视图的严格回放投影 |
|
|
@@ -128,9 +126,9 @@ Lead 可以停止 teammate 的当前轮次,而不会删除其排队的消息
|
|
|
128
126
|
|
|
129
127
|
每个普通运行时 root 都是一个隐式 Team 的 Lead,其 `TeamId` 等于 `SessionId`;不存在创建事件,持久状态从第一条成员、消息或任务记录开始。`spawnTeammate()` 先追加并 flush 一条 `provisioning` 成员记录,再要求配置的提供方创建预留 child;提供方失败会追加一条持久的 `failed` 成员。fresh child 不携带 Lead 历史;fork child 只捕获一次 Lead 的已完成 turn 前缀。恢复把未终结的 provisioning 记录对照 child 独立持久化的会话进行对账:直接 parent 与 continuable descriptor 匹配、且初始用户消息已记录则产生 `active`,其他任何情况都产生 `failed`。如果恢复在同进程竞争中先完成,creator 会接受终态,或报告 `TEAM_PROVISIONING_CONFLICT` 并 drain 该 child。名字由第一条 provisioning 记录保留,且永不复用。
|
|
130
128
|
|
|
131
|
-
###
|
|
129
|
+
### 直接 steering
|
|
132
130
|
|
|
133
|
-
`sendMessage()` 校验 peer
|
|
131
|
+
`sendMessage()` 校验 peer 成员关系、解析目标、铸出消息身份,并在投递任何内容之前按 `maxMessageBytes` 量取封帧后的内容。目标消息以 `Team message <id> from <name>:` 开头,并在 `TeamMessageSource` 中保留同一 id 与发送者,因此接收模型与持久日志对发送者身份的认定一致。发往 Lead 时直接调用 `Agent.steer()`;发往 teammate 时走 continuation owner 的 host-only Steer 路径,它授权 Lead→子代这条边并冷恢复非活跃目标。无法准入的发送以自己的错误失败而不是被保留,因此发送方无需推理重试队列。
|
|
134
132
|
|
|
135
133
|
投递给 Lead 时直接调用 `Agent.steer()`。投递给 teammate 时使用 continuation owner 的 host-only Steer 路径;该路径会保留 Team 发送者 source,同时授权 Lead-to-child edge 并冷恢复 inactive target。sibling 消息绝不会通过公开的相邻 Agent 消息操作伪装成 Lead。
|
|
136
134
|
|
|
@@ -140,15 +138,15 @@ Lead 可以停止 teammate 的当前轮次,而不会删除其排队的消息
|
|
|
140
138
|
|
|
141
139
|
### 等待与中断
|
|
142
140
|
|
|
143
|
-
`waitForChange()` 等待注册之后发生的下一条 roster、task
|
|
141
|
+
`waitForChange()` 等待注册之后发生的下一条 roster、task、消息或实时状态边,时长从 10 秒到 1 小时,并且只报告是否超时;运行时 dispose 会释放当前等待。取消会保留 Error reason;非 Error reason 则通过 `TEAM_WAIT_ABORTED` 报告。`interrupt()` 仅限 Lead,委托 continuable-subagent 的 interrupt 路径,以 `keepInbox` 只取消 live teammate 的当前 turn;它既不释放任务 owner,也不删除持久 mail。
|
|
144
142
|
|
|
145
143
|
### 持久性模型
|
|
146
144
|
|
|
147
|
-
Team 事件追加到精确的 live Lead 会话,并在操作报告成功或唤醒等待者之前 flush。`team/member
|
|
145
|
+
Team 事件追加到精确的 live Lead 会话,并在操作报告成功或唤醒等待者之前 flush。`team/member` 与 `team/task` 仅存在于日志,历史的 `team/message/queued` 与 `team/message/delivered` 记录保持可读:它们都不进入会话表面,因此派生模型历史不受协作记录影响。顺序与时间由会话事件的 `seq` 与 `time` 负责,快照不重复保存。
|
|
148
146
|
|
|
149
147
|
### Dispose
|
|
150
148
|
|
|
151
|
-
dispose
|
|
149
|
+
dispose 会关闭准入、中止并等待已获准的发送与创建事务,再让 continuation owner 释放 roster 中确切的 live direct child 及其后代;Lead 的非 Team continuable child 不受影响。cleanup 失败会让 dispose 明确失败,并以 `disposalTimeoutMs` 为上限。
|
|
152
150
|
|
|
153
151
|
</details>
|
|
154
152
|
|