@wowyuarm/dsh-agent-team 0.1.10 → 0.1.12
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.md +17 -4
- package/README.zh.md +17 -4
- package/package.json +53 -47
- package/packages/agent-team/README.md +6 -4
- package/packages/agent-team/README.zh.md +6 -4
- package/packages/agent-team/lib/context-management.js +40 -50
- package/packages/agent-team/lib/context-projection.js +15 -1
- package/packages/agent-team/lib/index.js +244 -154
- package/packages/agent-team/lib/invariant.js +38 -4
- package/packages/agent-team/lib/ledger.js +775 -383
- package/packages/agent-team/lib/member-context.js +6 -2
- package/packages/agent-team/lib/member-runtime.js +47 -9
- package/packages/agent-team/lib/member-time-context.js +20 -5
- package/packages/agent-team/lib/mentions.js +56 -0
- package/packages/agent-team/lib/pressure-policy.js +33 -9
- package/packages/agent-team/lib/session-event-cursor.js +116 -0
- package/packages/agent-team/lib/session-remediation.js +38 -26
- package/packages/agent-team/lib/spec.js +47 -34
- package/packages/agent-team/lib/stored-session-reader.js +138 -0
- package/packages/agent-team/lib/typert.host.js +157 -41
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +129 -32
- package/packages/agent-team/lib/types/context-management.d.ts +7 -0
- package/packages/agent-team/lib/types/context-management.d.ts.map +1 -1
- package/packages/agent-team/lib/types/context-projection.d.ts +8 -0
- package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
- package/packages/agent-team/lib/types/index.d.ts +77 -7
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/invariant.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +251 -20
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-runtime.d.ts +2 -1
- package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -1
- package/packages/agent-team/lib/types/member-time-context.d.ts.map +1 -1
- package/packages/agent-team/lib/types/mentions.d.ts +34 -0
- package/packages/agent-team/lib/types/mentions.d.ts.map +1 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts +18 -0
- package/packages/agent-team/lib/types/pressure-policy.d.ts.map +1 -1
- package/packages/agent-team/lib/types/session-event-cursor.d.ts +119 -0
- package/packages/agent-team/lib/types/session-event-cursor.d.ts.map +1 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts +23 -0
- package/packages/agent-team/lib/types/session-remediation.d.ts.map +1 -1
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/stored-session-reader.d.ts +92 -0
- package/packages/agent-team/lib/types/stored-session-reader.d.ts.map +1 -0
- package/packages/agent-team/lib/types/types/entities.d.ts +28 -20
- package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/operations.d.ts +45 -19
- package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types/requests-results.d.ts +87 -4
- package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +49 -7
- package/packages/client-agent-team/README.md +1 -1
- package/packages/client-agent-team/README.zh.md +1 -1
- package/packages/client-agent-team/lib/client.js +2357 -1207
- package/packages/client-agent-team/lib/client.js.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +27 -7
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts +18 -0
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamAvatarStack.js +22 -0
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +3 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +167 -35
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +23 -27
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +11 -5
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +26 -26
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamConversation.js +9 -2
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts +20 -0
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamCountBadge.js +25 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +25 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +139 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +8 -24
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts +43 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberRow.js +27 -0
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +9 -2
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +11 -4
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +8 -0
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamPresenceDot.js +21 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +108 -30
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +68 -7
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +19 -9
- package/packages/client-agent-team/lib/types/client/locales.d.ts +40 -2
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +40 -2
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +10 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.js +18 -7
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts +41 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/scope-coverage.js +64 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +7 -2
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts +33 -2
- package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-changes.js +107 -25
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts +20 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/team-dialog-save.js +36 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +43 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-formatters.js +81 -6
- package/packages/tool-agent-team/README.md +2 -2
- package/packages/tool-agent-team/README.zh.md +2 -2
- package/packages/tool-agent-team/lib/context-tools.js +18 -14
- package/packages/tool-agent-team/lib/host-access.js +20 -0
- package/packages/tool-agent-team/lib/index.js +44 -32
- package/packages/tool-agent-team/lib/types/context-tools.d.ts.map +1 -1
- package/packages/tool-agent-team/lib/types/host-access.d.ts +14 -0
- package/packages/tool-agent-team/lib/types/host-access.d.ts.map +1 -0
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/progress-nudge.js +0 -328
- package/packages/agent-team/lib/types/progress-nudge.d.ts +0 -136
- package/packages/agent-team/lib/types/progress-nudge.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts +0 -3
- package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamSettings.js +0 -5
package/README.md
CHANGED
|
@@ -21,13 +21,13 @@ An opt-in plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-
|
|
|
21
21
|
|
|
22
22
|
## Preview
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Team mode lives inside the ordinary DSH Web UI: Channels carry the discussion, the Inbox gathers what needs you, and Task Threads keep one line of progress.
|
|
25
25
|
|
|
26
|
-

|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
The Human Inbox leads with unread Threads that need you, followed by recently active ones:
|
|
29
29
|
|
|
30
|
-

|
|
31
31
|
|
|
32
32
|
### Task Threads
|
|
33
33
|
|
|
@@ -80,6 +80,19 @@ Team mode
|
|
|
80
80
|
|
|
81
81
|
Create an Agent only in a trusted Workspace. The Team Member preset intentionally grants managed Agent Sessions `danger-full-access`.
|
|
82
82
|
|
|
83
|
+
## Not to be confused with
|
|
84
|
+
|
|
85
|
+
Three other DSH plugins carry similar names and solve a different problem — one of them may fit you better:
|
|
86
|
+
|
|
87
|
+
| Plugin | What it is | Its unit of work |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| [`NanmiCoder/dsh-agent-teams`](https://github.com/NanmiCoder/dsh-agent-teams) | Turns the current DSH session into a captain that assembles sub-agents, splits a goal into dependency-aware tasks, and coordinates them through direct messages | one **session** |
|
|
90
|
+
| [`toolclub/dsh-agent-team-gui`](https://github.com/toolclub/dsh-agent-team-gui) | A reusable plan → implement → review team with a model chosen per member, and a Run Center for token usage | one **workflow run** |
|
|
91
|
+
| [`limuyang2/agent-team`](https://github.com/limuyang2/agent-team) — publishes `@limuyang2/dsh-agent-team` | Builds a team of independent root agents inside one DSH window: mix models and providers, assign one Leader, and let every member work in its own conversation over a shared Workspace | one **assembled team** |
|
|
92
|
+
| **`dsh-agent-team`** (this plugin) | Every agent is a durable Member identity with its own private memory, notes and skills; Channels and responsibilities are yours to assign, and a Task Thread is one line of progress | a **standing team** |
|
|
93
|
+
|
|
94
|
+
The practical difference: a Member you created last week is still the same Member today — same memory, same responsibilities, same private notes — after its session ended, its context rolled over, or DSH restarted. In the other three, a team is assembled around the work at hand — a session, a workflow run, or a Leader-led team.
|
|
95
|
+
|
|
83
96
|
## Uninstall
|
|
84
97
|
|
|
85
98
|
Remove the bundle from the profile; this also removes its composed layers:
|
package/README.zh.md
CHANGED
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
|
|
22
22
|
## 预览
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Team mode 就在普通 DSH Web UI 里:Channel 承载讨论,收件箱收拢需要你的事项,Task Thread 把一条工作线保留在同一条上下文里。
|
|
25
25
|
|
|
26
|
-

|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Human 收件箱把需要你的未读 Thread 置顶,其下是最近活跃:
|
|
29
29
|
|
|
30
|
-

|
|
31
31
|
|
|
32
32
|
### Task Thread
|
|
33
33
|
|
|
@@ -80,6 +80,19 @@ Team mode
|
|
|
80
80
|
|
|
81
81
|
只在可信 Workspace 中创建 Agent。Team Member preset 会给被管理的 Agent Session 授予 `danger-full-access`。
|
|
82
82
|
|
|
83
|
+
## 与同名插件的区别
|
|
84
|
+
|
|
85
|
+
另外三个 DSH 插件名字相近,但解决的是不同的问题 —— 其中一个可能更适合你:
|
|
86
|
+
|
|
87
|
+
| 插件 | 它是什么 | 工作单位 |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| [`NanmiCoder/dsh-agent-teams`](https://github.com/NanmiCoder/dsh-agent-teams) | 把**当前** DSH session 变成 captain,由它组建 sub-agent、把目标拆成带依赖的任务、并通过直接通信协调 | 一个 **session** |
|
|
90
|
+
| [`toolclub/dsh-agent-team-gui`](https://github.com/toolclub/dsh-agent-team-gui) | 可复用的「规划 → 实现 → 评审」团队,每个成员可选不同模型,Run Center 查看 token 用量 | 一次 **workflow run** |
|
|
91
|
+
| [`limuyang2/agent-team`](https://github.com/limuyang2/agent-team)(npm 名 `@limuyang2/dsh-agent-team`) | 在一个 DSH 窗口里组一支独立 root agent 的队:混用模型与 provider、指定一个 Leader,每个成员在自己的会话里工作、共享同一个 Workspace | 一支**组起来执行任务的队** |
|
|
92
|
+
| **`dsh-agent-team`**(本插件) | 每个 agent 是持久 Member 身份,带自己的私有记忆、笔记与技能;Channel 与职责由你分配,Task Thread 是一条进度线 | 一支**常驻团队** |
|
|
93
|
+
|
|
94
|
+
实际差别:你上周创建的 Member,今天还是同一个 Member —— 同样的记忆、职责和私有笔记 —— 即使它的 session 已结束、上下文已滚动、或 DSH 重启过。另外三个里,团队是围绕手头这次工作组建的 —— 一次 session、一次 workflow run,或一支有 Leader 的队。
|
|
95
|
+
|
|
83
96
|
## 卸载
|
|
84
97
|
|
|
85
98
|
从 profile 移除 bundle,同时会移除它组合进来的层:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wowyuarm/dsh-agent-team",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "A persistent agent team for long-running collaboration in DeepSeek Harness",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
"generate:typert": "node --import tsx scripts/generate-typert.mjs",
|
|
24
24
|
"prepack": "npm run build",
|
|
25
25
|
"clean:build-outputs": "node scripts/clean-build-outputs.mjs",
|
|
26
|
-
"
|
|
26
|
+
"check:docs": "node scripts/check-docs.mjs",
|
|
27
|
+
"check:core-skills": "node scripts/check-core-skills.mjs",
|
|
28
|
+
"check:boundaries": "node scripts/check-package-boundaries.mjs",
|
|
29
|
+
"test": "npm run generate:typert && npm run check:docs && npm run check:core-skills && npm run check:boundaries && vitest run",
|
|
27
30
|
"test:browser": "npm run build && node scripts/run-browser-test.mjs",
|
|
28
31
|
"preview": "node scripts/check-preview-credentials.mjs && npm run build && node scripts/run-preview.mjs",
|
|
29
32
|
"preview:ui": "npm run build && node scripts/run-ui-preview.mjs",
|
|
@@ -130,57 +133,60 @@
|
|
|
130
133
|
},
|
|
131
134
|
"peerDependencies": {
|
|
132
135
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
133
|
-
"@deepseek-ai/dsh-agent": ">=0.1.5-rc.1 <0.
|
|
134
|
-
"@deepseek-ai/dsh-agent-default-model": ">=0.1.5-rc.1 <0.
|
|
135
|
-
"@deepseek-ai/dsh-agent-presets": ">=0.1.5-rc.1 <0.
|
|
136
|
-
"@deepseek-ai/dsh-agent-tool-presentation": ">=0.1.5-rc.1 <0.
|
|
137
|
-
"@deepseek-ai/dsh-api-remotes": ">=0.1.5-rc.1 <0.
|
|
138
|
-
"@deepseek-ai/dsh-api-session-controller": ">=0.1.5-rc.1 <0.
|
|
139
|
-
"@deepseek-ai/dsh-api-workspace-controller": ">=0.1.5-rc.1 <0.
|
|
140
|
-
"@deepseek-ai/dsh-brand": ">=0.1.5-rc.1 <0.
|
|
141
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1 <0.
|
|
142
|
-
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1 <0.
|
|
143
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": ">=0.1.5-rc.1 <0.
|
|
144
|
-
"@deepseek-ai/dsh-client-ui-layout": ">=0.1.5-rc.1 <0.
|
|
145
|
-
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.1 <0.
|
|
146
|
-
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.1 <0.
|
|
147
|
-
"@deepseek-ai/dsh-client-ui-settings-general": ">=0.1.5-rc.1 <0.
|
|
148
|
-
"@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.5-rc.1 <0.
|
|
149
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1 <0.
|
|
150
|
-
"@deepseek-ai/dsh-client-ui-workspace": ">=0.1.5-rc.1 <0.
|
|
151
|
-
"@deepseek-ai/dsh-command-compact": ">=0.1.5-rc.1 <0.
|
|
152
|
-
"@deepseek-ai/dsh-compaction": ">=0.1.5-rc.1 <0.
|
|
153
|
-
"@deepseek-ai/dsh-home-paths": ">=0.1.5-rc.1 <0.
|
|
154
|
-
"@deepseek-ai/dsh-invariants": ">=0.1.5-rc.1 <0.
|
|
155
|
-
"@deepseek-ai/dsh-llm": ">=0.1.5-rc.1 <0.
|
|
156
|
-
"@deepseek-ai/dsh-sandbox-policy": ">=0.1.5-rc.1 <0.
|
|
157
|
-
"@deepseek-ai/dsh-scope": ">=0.1.5-rc.1 <0.
|
|
158
|
-
"@deepseek-ai/dsh-session": ">=0.1.5-rc.1 <0.
|
|
159
|
-
"@deepseek-ai/dsh-session-format-catalog": ">=0.1.5-rc.1 <0.
|
|
160
|
-
"@deepseek-ai/dsh-session-persistence": ">=0.1.5-rc.1 <0.
|
|
161
|
-
"@deepseek-ai/dsh-skill": ">=0.1.5-rc.1 <0.
|
|
162
|
-
"@deepseek-ai/dsh-skill-filesystem": ">=0.1.5-rc.1 <0.
|
|
163
|
-
"@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.1 <0.
|
|
164
|
-
"@deepseek-ai/dsh-token-meter": ">=0.1.5-rc.1 <0.
|
|
165
|
-
"@deepseek-ai/dsh-tool-bash": ">=0.1.5-rc.1 <0.
|
|
166
|
-
"@deepseek-ai/dsh-tool-fs": ">=0.1.5-rc.1 <0.
|
|
167
|
-
"@deepseek-ai/dsh-tool-fs-search": ">=0.1.5-rc.1 <0.
|
|
168
|
-
"@deepseek-ai/dsh-tool-jobs": ">=0.1.5-rc.1 <0.
|
|
169
|
-
"@deepseek-ai/dsh-tool-pwsh": ">=0.1.5-rc.1 <0.
|
|
170
|
-
"@deepseek-ai/dsh-tool-skill": ">=0.1.5-rc.1 <0.
|
|
171
|
-
"@deepseek-ai/dsh-tool-todo": ">=0.1.5-rc.1 <0.
|
|
172
|
-
"@deepseek-ai/dsh-tool-web": ">=0.1.5-rc.1 <0.
|
|
173
|
-
"@deepseek-ai/dsh-tools": ">=0.1.5-rc.1 <0.
|
|
174
|
-
"@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.1 <0.
|
|
175
|
-
"@deepseek-ai/dsh-workspace": ">=0.1.5-rc.1 <0.
|
|
136
|
+
"@deepseek-ai/dsh-agent": ">=0.1.5-rc.1 <0.1.6",
|
|
137
|
+
"@deepseek-ai/dsh-agent-default-model": ">=0.1.5-rc.1 <0.1.6",
|
|
138
|
+
"@deepseek-ai/dsh-agent-presets": ">=0.1.5-rc.1 <0.1.6",
|
|
139
|
+
"@deepseek-ai/dsh-agent-tool-presentation": ">=0.1.5-rc.1 <0.1.6",
|
|
140
|
+
"@deepseek-ai/dsh-api-remotes": ">=0.1.5-rc.1 <0.1.6",
|
|
141
|
+
"@deepseek-ai/dsh-api-session-controller": ">=0.1.5-rc.1 <0.1.6",
|
|
142
|
+
"@deepseek-ai/dsh-api-workspace-controller": ">=0.1.5-rc.1 <0.1.6",
|
|
143
|
+
"@deepseek-ai/dsh-brand": ">=0.1.5-rc.1 <0.1.6",
|
|
144
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1 <0.1.6",
|
|
145
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1 <0.1.6",
|
|
146
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": ">=0.1.5-rc.1 <0.1.6",
|
|
147
|
+
"@deepseek-ai/dsh-client-ui-layout": ">=0.1.5-rc.1 <0.1.6",
|
|
148
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.1 <0.1.6",
|
|
149
|
+
"@deepseek-ai/dsh-client-ui-renderer": ">=0.1.5-rc.1 <0.1.6",
|
|
150
|
+
"@deepseek-ai/dsh-client-ui-settings-general": ">=0.1.5-rc.1 <0.1.6",
|
|
151
|
+
"@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.5-rc.1 <0.1.6",
|
|
152
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-rc.1 <0.1.6",
|
|
153
|
+
"@deepseek-ai/dsh-client-ui-workspace": ">=0.1.5-rc.1 <0.1.6",
|
|
154
|
+
"@deepseek-ai/dsh-command-compact": ">=0.1.5-rc.1 <0.1.6",
|
|
155
|
+
"@deepseek-ai/dsh-compaction": ">=0.1.5-rc.1 <0.1.6",
|
|
156
|
+
"@deepseek-ai/dsh-home-paths": ">=0.1.5-rc.1 <0.1.6",
|
|
157
|
+
"@deepseek-ai/dsh-invariants": ">=0.1.5-rc.1 <0.1.6",
|
|
158
|
+
"@deepseek-ai/dsh-llm": ">=0.1.5-rc.1 <0.1.6",
|
|
159
|
+
"@deepseek-ai/dsh-sandbox-policy": ">=0.1.5-rc.1 <0.1.6",
|
|
160
|
+
"@deepseek-ai/dsh-scope": ">=0.1.5-rc.1 <0.1.6",
|
|
161
|
+
"@deepseek-ai/dsh-session": ">=0.1.5-rc.1 <0.1.6",
|
|
162
|
+
"@deepseek-ai/dsh-session-format-catalog": ">=0.1.5-rc.1 <0.1.6",
|
|
163
|
+
"@deepseek-ai/dsh-session-persistence": ">=0.1.5-rc.1 <0.1.6",
|
|
164
|
+
"@deepseek-ai/dsh-skill": ">=0.1.5-rc.1 <0.1.6",
|
|
165
|
+
"@deepseek-ai/dsh-skill-filesystem": ">=0.1.5-rc.1 <0.1.6",
|
|
166
|
+
"@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.1 <0.1.6",
|
|
167
|
+
"@deepseek-ai/dsh-token-meter": ">=0.1.5-rc.1 <0.1.6",
|
|
168
|
+
"@deepseek-ai/dsh-tool-bash": ">=0.1.5-rc.1 <0.1.6",
|
|
169
|
+
"@deepseek-ai/dsh-tool-fs": ">=0.1.5-rc.1 <0.1.6",
|
|
170
|
+
"@deepseek-ai/dsh-tool-fs-search": ">=0.1.5-rc.1 <0.1.6",
|
|
171
|
+
"@deepseek-ai/dsh-tool-jobs": ">=0.1.5-rc.1 <0.1.6",
|
|
172
|
+
"@deepseek-ai/dsh-tool-pwsh": ">=0.1.5-rc.1 <0.1.6",
|
|
173
|
+
"@deepseek-ai/dsh-tool-skill": ">=0.1.5-rc.1 <0.1.6",
|
|
174
|
+
"@deepseek-ai/dsh-tool-todo": ">=0.1.5-rc.1 <0.1.6",
|
|
175
|
+
"@deepseek-ai/dsh-tool-web": ">=0.1.5-rc.1 <0.1.6",
|
|
176
|
+
"@deepseek-ai/dsh-tools": ">=0.1.5-rc.1 <0.1.6",
|
|
177
|
+
"@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.1 <0.1.6",
|
|
178
|
+
"@deepseek-ai/dsh-workspace": ">=0.1.5-rc.1 <0.1.6",
|
|
176
179
|
"react": "^18.2.0"
|
|
177
180
|
},
|
|
178
181
|
"keywords": [
|
|
182
|
+
"agent-team",
|
|
179
183
|
"deepseek-harness",
|
|
180
184
|
"dsh",
|
|
181
185
|
"dsh-plugin",
|
|
182
|
-
"agent-team",
|
|
183
186
|
"multi-agent",
|
|
184
|
-
"
|
|
187
|
+
"agent-orchestration",
|
|
188
|
+
"ai-agents",
|
|
189
|
+
"deepseek",
|
|
190
|
+
"multi-agent-systems"
|
|
185
191
|
]
|
|
186
192
|
}
|
|
@@ -8,10 +8,12 @@ The Host capability for one Agent Team in a dshHome. `ctx.agentTeam` owns the ap
|
|
|
8
8
|
|
|
9
9
|
The Service consumes `ctx.storageDomain`, `ctx.workspaceRegistry`, `ctx.agents`, `ctx.agentDefaultModel`, `ctx.agentPresets`, `ctx.tools`, `ctx.sessions`, and `ctx.sessionPersistence`. It opens the versioned `agent_team` Domain before Cordis publishes `ctx.agentTeam`. The first boot appends one `team/initialized` operation for the stable Human Member; later boots replay the same operation and do not append another record.
|
|
10
10
|
|
|
11
|
-
`status()` returns the current durable sequence, operation count, channel count, Agent Member count, and Human Member ref. It performs no model request and no storage write. `validateLedger()` checks the package-owned projection against the durable operation table.
|
|
11
|
+
`status()` returns the current durable sequence, operation count, channel count, Agent Member count, and Human Member ref. It performs no model request and no storage write. `validateLedger()` checks the package-owned projection against the durable operation table. The invariant companion re-derives that whole table at mount — an unreplayable ledger fails startup — but adopts the record-level replay the ledger constructor already ran while nothing has committed since, gated on the record count, head sequence, and head operation id, which only the operations table's single writer can change. Any commit in between, and every later validation, replays the durable records again. Afterwards the invariant re-derives once per burst of commits, after the committing call has returned, so a Thread read never waits on an O(ledger) replay; a divergence is logged where it is detected and re-raised on every later commit until a replay comes back clean.
|
|
12
12
|
|
|
13
13
|
Every operation record carries a positive global sequence, unique operation and request ids, an actor snapshot, and the previous operation id. Replay rejects invalid record fields, table-key/id mismatches, sequence gaps, broken previous links, repeated ids, and invalid state transitions. An identical request-id retry returns the original receipt; a changed payload with the same request id rejects.
|
|
14
14
|
|
|
15
|
+
One durable record stores progress instead of the projection it reported. A `team/thread-read` receipt carries the Workspace, Member, Thread ref, optional Task ref, read watermark, and Inbox delta; the Thread, its facts, the anchor, the reader's Attention, and the unread count left behind are re-derived from the projection on every replay. Records written before this form froze that whole picture beside the delta: one strict union accepts both shapes, the legacy record keeps its own full derivation as its expected value, and loading normalizes and validates it without rewriting a stored byte. A record that fits neither shape — a receipt carrying a picture field, a legacy record missing the Task it belongs to or one of its facts — fails the domain open rather than being guessed at. An identical retry of a committed read returns the original receipt with the picture the current projection derives.
|
|
16
|
+
|
|
15
17
|
## Durability and lifecycle
|
|
16
18
|
|
|
17
19
|
`storage-domain` validates every record at the durable read boundary and rejects a backend unit stamped with another version. The Team updates its projection only after `KvTable.put()` resolves. Its Fiber owns the Domain handle; disposal rejects new Service calls through Cordis removal, drains accepted Domain writes, and closes the backend unit before the name can reopen.
|
|
@@ -26,13 +28,13 @@ Activation applies `tools.allow` as a scoped restriction over the composed prese
|
|
|
26
28
|
|
|
27
29
|
Skills are Member-private: the preset has no shared skill-filesystem row, and the Host registers one provider per Member that scans exactly the plugin's bundled read-only core skills (`packages/agent-team/core-skills/` — the `member-skill-manager` meta skill that owns all skill craft guidance) plus that Member's writable `skills/` directory under its private memory path (default roots excluded). Installing is writing into the Member's own directory — directory form `skills/<name>/SKILL.md` with optional references and scripts, or a flat `.md` — and there is deliberately no upload Remote. The persona itself only states the private-space physical facts; the meta skill's description routes skill-management work to it. `skills.allow` filters the catalog through a live selection ref swapped at the same turn boundary; the filesystem watcher feeds discovery after a self-install.
|
|
28
30
|
|
|
29
|
-
Every team-managed session records `danger-full-access`. Project cwd remains the Workspace path, while private memory lives under `$DSH_HOME/agent-team/members/<memberId>/`. An untitled Member session is named with its handle through the session-title service, so the ordinary Session list shows the Member identity; an explicit rename or any earlier title always wins. The isolated `team-member` preset also provides coding tools including model-facing web search, Workspace instruction discovery, and Team protocol guidance. The host owns the shared Web service and provider; the preset mounts only the model-facing web tool. Its lowercase `memory.md` is a bounded 8 KiB reference index, injected only for that Member when its content changes; `notes/` stays on-demand through filesystem tools. Over-budget indexes receive a maintenance warning, not silent truncation. Ordinary sessions and forks receive no Team identity or private-memory context. At Host startup
|
|
31
|
+
Every team-managed session records `danger-full-access`. Project cwd remains the Workspace path, while private memory lives under `$DSH_HOME/agent-team/members/<memberId>/`. An untitled Member session is named with its handle through the session-title service, so the ordinary Session list shows the Member identity; an explicit rename or any earlier title always wins. The isolated `team-member` preset also provides coding tools including model-facing web search, Workspace instruction discovery, and Team protocol guidance. The host owns the shared Web service and provider; the preset mounts only the model-facing web tool. Its lowercase `memory.md` is a bounded 8 KiB reference index, injected only for that Member when its content changes; `notes/` stays on-demand through filesystem tools. Over-budget indexes receive a maintenance warning, not silent truncation. Ordinary sessions and forks receive no Team identity or private-memory context. At Host startup every enabled Member's private memory is provisioned and an `inactive` Member's is removed with its Session archived; directories the replayed ledger does not reference are never pruned, so leftovers from a discarded ledger stay on disk for the operator. Both that removal and the activation-time migration of a pre-fix colon directory act only on paths inside the running process's own `$DSH_HOME/agent-team/members/`: a recorded path naming a different DSH home (an isolated test home, a second instance) is refused with a warning rather than renamed or deleted, because acting on it would take a Member's real private memory out of its home.
|
|
30
32
|
|
|
31
33
|
Adding a Member to a Channel grants future read/send/claim authority but injects no historical Messages into the member session. Every top-level Message creates a Thread; new Client/tool starts explicitly choose taskless while released-client omission remains taskful, and a Human can later promote a taskless Thread by atomically adding its Task overlay and a structured `promote` Task activity. Thread Attention starts when a Thread is created, a Claim is created, a member follows, a top-level Message mentions them, or a Human confirms an invitation. Ordinary unread is derived from Attention; structured mentions create durable direct markers, while terminal Task changes retain sparse Activity markers for affected followers after Attention ends. `team_inbox` and Thread reads are Host projections, not Session inbox contents. A direct mention context includes its Message body and source; Task/Claim changes — including promotion — include concise transition facts; ordinary unread carries a body-free Thread-first route. Pending hints are coalesced, ignored hints do not loop, and resume/error recovery derives a new hint from durable unread state. For recoverable service failures, the Host wakes a Member after each of the first two consecutive `agent/error` occurrences, then leaves the third failure for the operator; only a clean turn resets that run.
|
|
32
34
|
|
|
33
|
-
Member replies require the exact current Thread revision and atomically update Message and Thread facts. `threadRef` is the primary collaboration identity; released task-only Clients may send a Host-resolved `taskRef` alias for taskful Threads, while Task/Claim operations remain Task-ref based. Unread work must be read before a mutation; stale revisions are rejected after that unread gate. A closed Task rejects replies and new Attention; reopening restores the Task without restoring prior Attention. Taskless Threads still support replies, follow, mentions, Inbox, read, and history, but have no Claims or Task-resolution path. Top-level Messages may mention Agents directly: mentioned Members start following the new Thread. In an existing Thread, a Human reply mentioning
|
|
35
|
+
Member replies require the exact current Thread revision and atomically update Message and Thread facts. `threadRef` is the primary collaboration identity; released task-only Clients may send a Host-resolved `taskRef` alias for taskful Threads, while Task/Claim operations remain Task-ref based. Unread work must be read before a mutation; stale revisions are rejected after that unread gate. A closed Task rejects replies and new Attention; reopening restores the Task without restoring prior Attention. Taskless Threads still support replies, follow, mentions, Inbox, read, and history, but have no Claims or Task-resolution path. Top-level Messages may mention Agents directly: mentioned Members start following the new Thread. In an existing Thread, a Human reply mentioning a Member that is not currently following requires a process-local, one-use confirmation token before the operation commits, while such a Member reply commits and delivers only to Members the Thread has ever carried, reporting the rest as undelivered. Mentions are authored in the Message body as `@Handle` and resolved by the Host against the Channel's addressable names; Message facts carry the resolved refs, and the Client renders mention chips only for those Members. Claim/done/release and Task changes are ordered host-authored Activities. Active Claims exclude only the same normalized Direction; different Directions can run concurrently. Task state is derived from Claims unless Human acceptance or closure overrides it. Close releases active Claims and clears Thread Attention atomically. Member removal marks the member inactive, releases owned active Claims, clears its Attention and direct markers, and archives the session after the durable commit. Message and Activity facts share one bounded sequence cursor.
|
|
34
36
|
|
|
35
|
-
`changes()` is the Client invalidation stream. Each request declares one optional `scope` — workspace, channel, or thread — plus an abortable transport signal; a committed operation wakes only waiters whose scope matches the scopes derived from that operation (member lifecycle and presence wake their Workspace; content operations wake their Channel and Thread). A Thread read
|
|
37
|
+
`changes()` is the Client invalidation stream. Each request declares one optional `scope` — workspace, channel, or thread — plus an abortable transport signal; a committed operation wakes only waiters whose scope matches the scopes derived from that operation (member lifecycle and presence wake their Workspace; content operations wake their Channel and Thread). A Thread read derives no scope, because it advances only the reader's private watermark — and a read that finds nothing unread for its reader (no watermark to advance, no marker to consume) appends no operation at all: it answers with the same projection-derived picture and no receipt, so an already-read Thread costs neither a durable write nor a replay. After each commit the Host notifies only the Members whose Inbox projection the operation can have changed — the operation's Attention/marker delta plus current followers of the touched Threads — never every live Agent.
|
|
36
38
|
|
|
37
39
|
M1 supports one Host writer. The ledger is permanent and has no snapshot or compaction path.
|
|
38
40
|
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
Service 使用 `ctx.storageDomain`、`ctx.workspaceRegistry`、`ctx.agents`、`ctx.agentDefaultModel`、`ctx.agentPresets`、`ctx.tools`、`ctx.sessions` 和 `ctx.sessionPersistence`,并在 Cordis 发布 `ctx.agentTeam` 前打开带版本的 `agent_team` Domain。首次启动为稳定 Human Member 追加一条 `team/initialized` operation;后续启动重放同一 operation,不追加新记录。
|
|
10
10
|
|
|
11
|
-
`status()` 返回当前持久 sequence、operation 数量、channel 数量、Agent Member 数量和 Human Member ref。它不发起模型请求,也不写 storage。`validateLedger()` 对照持久 operation table 检查包内 projection。
|
|
11
|
+
`status()` 返回当前持久 sequence、operation 数量、channel 数量、Agent Member 数量和 Human Member ref。它不发起模型请求,也不写 storage。`validateLedger()` 对照持久 operation table 检查包内 projection。invariant companion 在挂载时完整重导该表——重放不通过的账本会让启动失败——但当这期间没有任何提交落地时,它会复用账本构造期已经跑过的那次记录级重放:该复用只能用一次,并受三项同一性检查把关(记录条数、末条 sequence、末条 operation id),而这三项只有 operations 表的唯一写者——账本的 commit 路径——能改变。期间任何一次提交、以及此后的每次校验,都会重新重放持久记录。此后每批提交只跑一次,且安排在这次提交调用返回**之后**执行,所以打开 Thread 不会等待 O(账本) 的重放。漂移由这次延后重放记录日志,并在随后每次提交上重新抛出,直到某次重放干净为止。
|
|
12
12
|
|
|
13
13
|
每条 operation record 包含正数全局 sequence、唯一 operation/request id、actor snapshot 和前一条 operation id。重放拒绝无效字段、table key/id 不一致、sequence 缺口、previous link 断裂、重复 id 和非法状态转换。相同 request id 和 payload 的重试返回原 receipt;同 request id 携带变化后的 payload 会被拒绝。
|
|
14
14
|
|
|
15
|
+
有一类记录存的是「进度」,而不是它当场报告的那份投影。`team/thread-read` receipt 只携带 Workspace、Member、Thread ref、可选 Task ref、read watermark 与 Inbox delta;Thread、其 facts、anchor、读者的 Attention 与读完后剩余的未读计数,都在每次重放时从 projection 重新派生,因此重放一条读不再需要克隆一份假设投影、也不再重新数未读。这个形态之前写入的记录会把整份画面连同 delta 一起冻结:同一个 strict union 同时接受两形,旧记录以自身完整派生作为 expected 值,加载时就地 normalize 与校验,绝不改写任何已存储字节。两形都不符的记录——receipt 里多带画面字段、旧记录缺了所属 Task 或缺了一条 fact——会让整个 domain 打不开,而不是被猜测。对一次已提交读的相同重试返回原 receipt,画面取自当前 projection,从不返回冻结的旧画面。
|
|
16
|
+
|
|
15
17
|
## 持久化与生命周期
|
|
16
18
|
|
|
17
19
|
`storage-domain` 在持久读取处校验每条 record,并拒绝被其他版本标记的 backend unit。Team 只在 `KvTable.put()` 完成后更新 projection。其 Fiber 持有 Domain handle;dispose 通过 Cordis 移除拒绝新的 Service 调用,排空已接受的 Domain write,并在名称可重新打开前关闭 backend unit。
|
|
@@ -26,13 +28,13 @@ Activation 把 `tools.allow` 作为 scoped restriction 应用在已组合的 pre
|
|
|
26
28
|
|
|
27
29
|
Skills 是 Member 私有的:preset 不带共享 skill-filesystem row,Host 为每个 Member 注册一个 provider,只扫插件内置的只读 core skills(`packages/agent-team/core-skills/`——`member-skill-manager` meta skill,全部 skill 写作/安装/credentials 引导都在它里面)加该 Member 可写的私有 `skills/` 目录(排除默认 roots)。安装就是往自己目录写——目录形态 `skills/<name>/SKILL.md` + 可选 references/scripts,或平铺 `.md`——有意不提供上传 Remote。persona 只陈述私有空间物理事实,meta skill 的 description 负责"涉及 skill 管理工作时先读我"。`skills.allow` 通过同一 turn 边界换装的 live selection ref 过滤 catalog;自装后的发现由 filesystem watcher 驱动。
|
|
28
30
|
|
|
29
|
-
每个 Team 管理的 session 都会持久写入 `danger-full-access`。项目 cwd 仍是 Workspace 路径,私有记忆位于 `$DSH_HOME/agent-team/members/<memberId>/`。没有标题的 Member session 会通过 session-title service 以 handle 命名,普通 Session 列表因此直接显示 Member 身份;显式重命名或任何既有标题始终优先。隔离的 `team-member` preset 还提供 coding 工具、面向模型的 Web 搜索、Workspace instruction discovery 和 Team protocol guidance。共享的 Web service 与 provider 仍由 Host 持有;preset 只挂载面向模型的 Web tool。小写 `memory.md` 是有界的 8 KiB 参考索引,只有该 Member 的内容变化时才注入;`notes/` 只通过 filesystem tools 按需读取。超预算索引只产生维护警告,不静默截断。普通 session 和 fork 不获得 Team 身份或私有记忆上下文。Host
|
|
31
|
+
每个 Team 管理的 session 都会持久写入 `danger-full-access`。项目 cwd 仍是 Workspace 路径,私有记忆位于 `$DSH_HOME/agent-team/members/<memberId>/`。没有标题的 Member session 会通过 session-title service 以 handle 命名,普通 Session 列表因此直接显示 Member 身份;显式重命名或任何既有标题始终优先。隔离的 `team-member` preset 还提供 coding 工具、面向模型的 Web 搜索、Workspace instruction discovery 和 Team protocol guidance。共享的 Web service 与 provider 仍由 Host 持有;preset 只挂载面向模型的 Web tool。小写 `memory.md` 是有界的 8 KiB 参考索引,只有该 Member 的内容变化时才注入;`notes/` 只通过 filesystem tools 按需读取。超预算索引只产生维护警告,不静默截断。普通 session 和 fork 不获得 Team 身份或私有记忆上下文。Host 启动时会为每个 enabled Member 准备其私有记忆,并对 `inactive` Member 归档其 Session 后删除其私有记忆;重放 ledger 不引用的目录一律不清理,被丢弃 ledger 的遗留物留在磁盘上交给操作者处置。这项删除与 activation 时对旧式 colon 目录的迁移都只作用于当前进程自己的 `$DSH_HOME/agent-team/members/` 之内的路径:记录里指向另一个 DSH home(隔离测试 home、第二个实例)的路径会被拒绝并告警,既不改名也不删除——对它动手等于把 Member 的真实私有记忆搬出它自己的 home。
|
|
30
32
|
|
|
31
33
|
把 Member 加入 Channel 只授予之后的 read/send/claim authority,不向 Member session 注入历史 Message。每条顶层 Message 都创建 Thread;新 Client/tool 显式选择 taskless,released Client 省略意图时仍保持 taskful;Human 可之后 promotion taskless Thread,原子附加 Task overlay 与结构化 `promote` Task activity。创建 Thread、创建 Claim、显式 follow、顶层消息 mention 到、或 Human 确认邀请会开始 Thread Attention。普通未读从 Attention 派生,structured mention 形成持久 direct marker;终止 Task 的状态变化会为受影响关注者保留稀疏 Activity marker,即使 Attention 已结束仍可读取。`team_inbox` 和 Thread read 是 Host projection,不是 Session inbox 内容。Direct mention context 包含消息正文和来源,Task/Claim 变化(含 promotion)包含简短状态事实,普通未读提供无正文的 Thread-first 路由。提示会合并,忽略提示不会形成循环,resume/runtime error recovery 会从持久未读状态重新判断是否提示。对于可恢复的服务错误,Host 会在连续 `agent/error` occurrence 的前两次后唤醒 Member;第 3 次错误则交给 operator,只有 clean turn 才会重置这段连续错误。
|
|
32
34
|
|
|
33
|
-
Member reply 必须携带准确的当前 Thread revision,并在一个 operation 内更新 Message 和 Thread facts。`threadRef` 是协作主身份;released task-only Client 可为 taskful Thread 传入 Host-resolved `taskRef` alias,而 Task/Claim 操作仍以 Task ref 为准。未读工作必须先 read;revision 过期时拒绝写入。Closed Task 拒绝 reply 和新的 Attention;reopen 恢复 Task,但不恢复之前的 Attention。taskless Thread 仍支持 reply、follow、mention、Inbox、read 和 history,但没有 Claim 或 Task resolution path。顶层消息可以直接 mention Agent:被 mention 的 Member 会开始关注新 Thread。在既有 Thread 中,Human 的 reply
|
|
35
|
+
Member reply 必须携带准确的当前 Thread revision,并在一个 operation 内更新 Message 和 Thread facts。`threadRef` 是协作主身份;released task-only Client 可为 taskful Thread 传入 Host-resolved `taskRef` alias,而 Task/Claim 操作仍以 Task ref 为准。未读工作必须先 read;revision 过期时拒绝写入。Closed Task 拒绝 reply 和新的 Attention;reopen 恢复 Task,但不恢复之前的 Attention。taskless Thread 仍支持 reply、follow、mention、Inbox、read 和 history,但没有 Claim 或 Task resolution path。顶层消息可以直接 mention Agent:被 mention 的 Member 会开始关注新 Thread。在既有 Thread 中,Human 的 reply 提到当前未 follow 的 Member 时必须先取得 process-local one-use confirmation token 才提交 operation;Member 的此类 reply 会提交,但只送达该 Thread 曾经承载过的 Member,其余在结果里报告为未送达。mention 在 Message 正文里以 `@Handle` 撰写,由 Host 按 Channel 的可寻址名字解析;Message fact 携带解析后的 refs,Client 只为这些 Member 渲染 mention chip。claim/done/release 和 Task change 是有序的 host-authored Activity。Active Claim 只排斥相同的 normalized Direction;不同 Direction 可以并行。Task status 从 Claims 派生,Human accept/close 是覆盖事实。Close 原子释放 active Claims 并清除 Thread Attention。Member remove 原子标记 inactive、释放 owned active Claims、清除该成员的 Attention 和 direct markers,再归档 session。Message 与 Activity facts 共用一个有界 sequence cursor。
|
|
34
36
|
|
|
35
|
-
`changes()` 是 Client 失效通知流。每个请求声明一个可选 `scope`(workspace、channel 或 thread)和可取消的传输 signal;一次提交的 operation 只唤醒 scope 与该 operation 派生范围匹配的 waiter(成员生命周期与 presence 唤醒其 Workspace,内容操作唤醒其 Channel 与 Thread)。Thread read
|
|
37
|
+
`changes()` 是 Client 失效通知流。每个请求声明一个可选 `scope`(workspace、channel 或 thread)和可取消的传输 signal;一次提交的 operation 只唤醒 scope 与该 operation 派生范围匹配的 waiter(成员生命周期与 presence 唤醒其 Workspace,内容操作唤醒其 Channel 与 Thread)。Thread read 不派生任何 scope,因为它只推进读者自己的私有水位——而一次读如果对读者没有任何未读(没有水位可推进、没有 marker 可消费),就完全不追加 operation:它返回同一份由 projection 派生的画面且不带 receipt,所以已读完的 Thread 既不付一次持久写、也不付一次重放。每次提交后,Host 只通知 Inbox projection 可能被该 operation 改变的 Member——即 operation 的 Attention/marker delta 加上被触及 Thread 的当前关注者——而不是全部在线 Agent。
|
|
36
38
|
|
|
37
39
|
M1 支持单个 Host writer。Ledger 永久保留,不提供 snapshot 或 compaction。
|
|
38
40
|
|
|
@@ -23,6 +23,22 @@ import { AGENT_TEAM_PLUGIN_ID, createCheckpointContinuationMessage, createHandof
|
|
|
23
23
|
import { CONTEXT_CHECKPOINT_TOOL_NAME, CONTEXT_ROLLOVER_TOOL_NAME, continuationDelivered, foldContextProjection, } from "./context-projection.js";
|
|
24
24
|
/** Stable summary of the one-shot rollover pressure notice (ticket 03 wires delivery). */
|
|
25
25
|
export const CONTEXT_PRESSURE_NOTICE_SUMMARY = 'Context pressure: prepare a handoff';
|
|
26
|
+
/**
|
|
27
|
+
* Rebuild one Member's in-process intent from the projection's pending
|
|
28
|
+
* rollover. Three call sites consume it — the live result, crash recovery
|
|
29
|
+
* with the turn still open, and crash recovery past the turn end — and they
|
|
30
|
+
* must agree field for field; this is the single definition of that list.
|
|
31
|
+
*/
|
|
32
|
+
function intentFromPending(pending) {
|
|
33
|
+
return {
|
|
34
|
+
toolCallId: pending.toolCallId,
|
|
35
|
+
resultSeq: pending.resultSeq,
|
|
36
|
+
turn: pending.turn,
|
|
37
|
+
handoff: pending.handoff,
|
|
38
|
+
...(pending.checkpointRef === undefined ? {} : { checkpointRef: pending.checkpointRef }),
|
|
39
|
+
relatedFiles: pending.relatedFiles,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
26
42
|
export class ContextManagementCoordinator {
|
|
27
43
|
options;
|
|
28
44
|
members = new Map();
|
|
@@ -166,18 +182,7 @@ export class ContextManagementCoordinator {
|
|
|
166
182
|
return;
|
|
167
183
|
if (this.members.has(memberId))
|
|
168
184
|
return;
|
|
169
|
-
this.members.set(memberId, {
|
|
170
|
-
agent,
|
|
171
|
-
intent: {
|
|
172
|
-
toolCallId: pending.toolCallId,
|
|
173
|
-
resultSeq: pending.resultSeq,
|
|
174
|
-
turn: pending.turn,
|
|
175
|
-
handoff: pending.handoff,
|
|
176
|
-
...(pending.checkpointRef === undefined ? {} : { checkpointRef: pending.checkpointRef }),
|
|
177
|
-
relatedFiles: pending.relatedFiles,
|
|
178
|
-
},
|
|
179
|
-
turnEnded: false,
|
|
180
|
-
});
|
|
185
|
+
this.members.set(memberId, { agent, intent: intentFromPending(pending), turnEnded: false });
|
|
181
186
|
}
|
|
182
187
|
onUserMessage(memberId, _agent, event) {
|
|
183
188
|
// Quiet-continuation delivery bookkeeping is projection-owned; the
|
|
@@ -216,6 +221,23 @@ export class ContextManagementCoordinator {
|
|
|
216
221
|
this.members.delete(memberId);
|
|
217
222
|
});
|
|
218
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Claim the in-process latch for one resolved checkpoint continuation.
|
|
226
|
+
* Returns the latch key when this caller won it, or undefined when the
|
|
227
|
+
* checkpoint never concluded a turn, was already delivered durably, or is
|
|
228
|
+
* latched already. The caller releases the latch on its own failure path.
|
|
229
|
+
*/
|
|
230
|
+
claimContinuationLatch(memberId, state, checkpoint) {
|
|
231
|
+
if (checkpoint.turnEndSeq === -1)
|
|
232
|
+
return undefined;
|
|
233
|
+
if (continuationDelivered(state, checkpoint.checkpointRef))
|
|
234
|
+
return undefined;
|
|
235
|
+
const latch = `${memberId}:${checkpoint.checkpointRef}`;
|
|
236
|
+
if (this.scheduledContinuations.has(latch))
|
|
237
|
+
return undefined;
|
|
238
|
+
this.scheduledContinuations.add(latch);
|
|
239
|
+
return latch;
|
|
240
|
+
}
|
|
219
241
|
/**
|
|
220
242
|
* Quiet follow-ups for checkpoints resolved by the turn that just ended.
|
|
221
243
|
* A successful `context_checkpoint` result concludes its turn; the Host
|
|
@@ -233,14 +255,9 @@ export class ContextManagementCoordinator {
|
|
|
233
255
|
if (state === undefined)
|
|
234
256
|
return;
|
|
235
257
|
for (const checkpoint of state.checkpoints) {
|
|
236
|
-
|
|
258
|
+
const latch = this.claimContinuationLatch(memberId, state, checkpoint);
|
|
259
|
+
if (latch === undefined)
|
|
237
260
|
continue;
|
|
238
|
-
if (continuationDelivered(state, checkpoint.checkpointRef))
|
|
239
|
-
continue;
|
|
240
|
-
const latch = `${memberId}:${checkpoint.checkpointRef}`;
|
|
241
|
-
if (this.scheduledContinuations.has(latch))
|
|
242
|
-
continue;
|
|
243
|
-
this.scheduledContinuations.add(latch);
|
|
244
261
|
// The turn/end observer fires inside the session append publication
|
|
245
262
|
// (a synchronous followup would reenter the publishing append), and a
|
|
246
263
|
// next-turn message queued while the driver is still converging never
|
|
@@ -310,18 +327,7 @@ export class ContextManagementCoordinator {
|
|
|
310
327
|
if (pending.turnEndSeq === -1) {
|
|
311
328
|
// The containing turn never ended durably; treat the intent as still
|
|
312
329
|
// waiting and observe the live events from here.
|
|
313
|
-
this.members.set(memberId, {
|
|
314
|
-
agent,
|
|
315
|
-
intent: {
|
|
316
|
-
toolCallId: pending.toolCallId,
|
|
317
|
-
resultSeq: pending.resultSeq,
|
|
318
|
-
turn: pending.turn,
|
|
319
|
-
handoff: pending.handoff,
|
|
320
|
-
...(pending.checkpointRef === undefined ? {} : { checkpointRef: pending.checkpointRef }),
|
|
321
|
-
relatedFiles: pending.relatedFiles,
|
|
322
|
-
},
|
|
323
|
-
turnEnded: false,
|
|
324
|
-
});
|
|
330
|
+
this.members.set(memberId, { agent, intent: intentFromPending(pending), turnEnded: false });
|
|
325
331
|
return;
|
|
326
332
|
}
|
|
327
333
|
// The turn already ended before the crash; the Agent is idle at
|
|
@@ -329,18 +335,7 @@ export class ContextManagementCoordinator {
|
|
|
329
335
|
const member = this.options.memberForAgent(agent);
|
|
330
336
|
if (member === undefined)
|
|
331
337
|
return;
|
|
332
|
-
const transition = {
|
|
333
|
-
agent,
|
|
334
|
-
intent: {
|
|
335
|
-
toolCallId: pending.toolCallId,
|
|
336
|
-
resultSeq: pending.resultSeq,
|
|
337
|
-
turn: pending.turn,
|
|
338
|
-
handoff: pending.handoff,
|
|
339
|
-
...(pending.checkpointRef === undefined ? {} : { checkpointRef: pending.checkpointRef }),
|
|
340
|
-
relatedFiles: pending.relatedFiles,
|
|
341
|
-
},
|
|
342
|
-
turnEnded: true,
|
|
343
|
-
};
|
|
338
|
+
const transition = { agent, intent: intentFromPending(pending), turnEnded: true };
|
|
344
339
|
this.members.set(memberId, transition);
|
|
345
340
|
void this.performTransition(memberId, member, transition);
|
|
346
341
|
}
|
|
@@ -358,14 +353,9 @@ export class ContextManagementCoordinator {
|
|
|
358
353
|
if (memberId === undefined)
|
|
359
354
|
return;
|
|
360
355
|
for (const checkpoint of state.checkpoints) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (continuationDelivered(state, checkpoint.checkpointRef))
|
|
364
|
-
continue;
|
|
365
|
-
const latch = `${memberId}:${checkpoint.checkpointRef}`;
|
|
366
|
-
if (this.scheduledContinuations.has(latch))
|
|
356
|
+
const latch = this.claimContinuationLatch(memberId, state, checkpoint);
|
|
357
|
+
if (latch === undefined)
|
|
367
358
|
continue;
|
|
368
|
-
this.scheduledContinuations.add(latch);
|
|
369
359
|
try {
|
|
370
360
|
agent.followup(createCheckpointContinuationMessage(checkpoint.checkpointRef));
|
|
371
361
|
}
|
|
@@ -34,7 +34,11 @@ const TEAM_ATTENTION_BOUNDARY_LABEL = 'Team attention change';
|
|
|
34
34
|
const TEAM_CLAIM_BOUNDARY_LABEL = 'Team task claim change';
|
|
35
35
|
/**
|
|
36
36
|
* Notice summaries that are pure reminders, never semantic Team facts: a
|
|
37
|
-
*
|
|
37
|
+
* recovery instruction must not become a return anchor. `Progress visibility
|
|
38
|
+
* reminder` is a historical decoder — the progress-nudge system was removed,
|
|
39
|
+
* but session logs recorded before its removal still carry those notices, and
|
|
40
|
+
* the projection keeps recognizing them (same pattern as the legacy
|
|
41
|
+
* `new_context` tool name below).
|
|
38
42
|
*/
|
|
39
43
|
const REMINDER_NOTICE_SUMMARIES = new Set(['Progress visibility reminder', 'Recovery: continue your interrupted work.']);
|
|
40
44
|
/** Whether one notice summary is a pure reminder (never a semantic Team fact). */
|
|
@@ -176,6 +180,16 @@ export function foldContextProjection(events, inheritedEventCount = 0, sessionId
|
|
|
176
180
|
}
|
|
177
181
|
return state;
|
|
178
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* The same fold as {@link foldContextProjection}, as the `{ start, step }` pair
|
|
185
|
+
* the incremental Session cursor consumes. The cursor route and the cold fold
|
|
186
|
+
* therefore share one transition function: a Session's projection cannot
|
|
187
|
+
* depend on which of the two read it.
|
|
188
|
+
*/
|
|
189
|
+
export const contextProjectionFold = (sessionId) => ({
|
|
190
|
+
start: emptyState(),
|
|
191
|
+
step: (state, event) => applyContextEvent(state, event, sessionId),
|
|
192
|
+
});
|
|
179
193
|
/**
|
|
180
194
|
* The host-only projection unit; no wire view is published. The definition is
|
|
181
195
|
* a factory: each Session folds with its own identity so checkpoint refs
|