@wowyuarm/dsh-agent-team 0.1.11 → 0.1.13

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.
Files changed (114) hide show
  1. package/README.md +6 -4
  2. package/README.zh.md +6 -4
  3. package/cordis.patch.yml +7 -3
  4. package/package.json +16 -3
  5. package/packages/agent-team/README.md +4 -4
  6. package/packages/agent-team/README.zh.md +4 -4
  7. package/packages/agent-team/lib/context-projection.js +5 -1
  8. package/packages/agent-team/lib/index.js +162 -113
  9. package/packages/agent-team/lib/ledger.js +496 -169
  10. package/packages/agent-team/lib/member-context.js +18 -1
  11. package/packages/agent-team/lib/member-runtime.js +48 -9
  12. package/packages/agent-team/lib/mentions.js +80 -0
  13. package/packages/agent-team/lib/spec.js +20 -0
  14. package/packages/agent-team/lib/typert.host.js +241 -46
  15. package/packages/agent-team/lib/typert.remote-client.d.ts +7 -3
  16. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  17. package/packages/agent-team/lib/typert.remote-client.js +178 -28
  18. package/packages/agent-team/lib/types/context-projection.d.ts.map +1 -1
  19. package/packages/agent-team/lib/types/index.d.ts +33 -14
  20. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  21. package/packages/agent-team/lib/types/ledger.d.ts +120 -18
  22. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  23. package/packages/agent-team/lib/types/member-context.d.ts +6 -0
  24. package/packages/agent-team/lib/types/member-context.d.ts.map +1 -1
  25. package/packages/agent-team/lib/types/member-runtime.d.ts +2 -1
  26. package/packages/agent-team/lib/types/member-runtime.d.ts.map +1 -1
  27. package/packages/agent-team/lib/types/mentions.d.ts +47 -0
  28. package/packages/agent-team/lib/types/mentions.d.ts.map +1 -0
  29. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  30. package/packages/agent-team/lib/types/types/entities.d.ts +3 -20
  31. package/packages/agent-team/lib/types/types/entities.d.ts.map +1 -1
  32. package/packages/agent-team/lib/types/types/operations.d.ts +37 -1
  33. package/packages/agent-team/lib/types/types/operations.d.ts.map +1 -1
  34. package/packages/agent-team/lib/types/types/requests-results.d.ts +107 -25
  35. package/packages/agent-team/lib/types/types/requests-results.d.ts.map +1 -1
  36. package/packages/agent-team/lib/types/vendor/storage-sqlite/index.d.ts +87 -0
  37. package/packages/agent-team/lib/types/vendor/storage-sqlite/index.d.ts.map +1 -0
  38. package/packages/agent-team/lib/types/vendor/storage-sqlite/schema.d.ts +59 -0
  39. package/packages/agent-team/lib/types/vendor/storage-sqlite/schema.d.ts.map +1 -0
  40. package/packages/agent-team/lib/types/vendor/storage-sqlite/unit.d.ts +57 -0
  41. package/packages/agent-team/lib/types/vendor/storage-sqlite/unit.d.ts.map +1 -0
  42. package/packages/agent-team/lib/vendor/storage-sqlite/index.js +139 -0
  43. package/packages/agent-team/lib/vendor/storage-sqlite/schema.js +120 -0
  44. package/packages/agent-team/lib/vendor/storage-sqlite/unit.js +132 -0
  45. package/packages/agent-team/preset/team-member/agent.cordis.yml +48 -8
  46. package/packages/client-agent-team/README.md +1 -1
  47. package/packages/client-agent-team/README.zh.md +1 -1
  48. package/packages/client-agent-team/lib/client.js +2123 -1406
  49. package/packages/client-agent-team/lib/client.js.map +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamAgentImport.d.ts +12 -0
  51. package/packages/client-agent-team/lib/types/client/TeamAgentImport.d.ts.map +1 -0
  52. package/packages/client-agent-team/lib/types/client/TeamAgentImport.js +69 -0
  53. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +3 -1
  54. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  55. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +31 -19
  56. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts +18 -0
  57. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.d.ts.map +1 -0
  58. package/packages/client-agent-team/lib/types/client/TeamAvatarStack.js +22 -0
  59. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts +3 -1
  60. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  61. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +111 -24
  62. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
  63. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +10 -3
  64. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  65. package/packages/client-agent-team/lib/types/client/TeamComposer.js +11 -17
  66. package/packages/client-agent-team/lib/types/client/TeamConversation.js +1 -1
  67. package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts +20 -0
  68. package/packages/client-agent-team/lib/types/client/TeamCountBadge.d.ts.map +1 -0
  69. package/packages/client-agent-team/lib/types/client/TeamCountBadge.js +25 -0
  70. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts +9 -5
  71. package/packages/client-agent-team/lib/types/client/TeamInboxPage.d.ts.map +1 -1
  72. package/packages/client-agent-team/lib/types/client/TeamInboxPage.js +92 -23
  73. package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts +43 -0
  74. package/packages/client-agent-team/lib/types/client/TeamMemberRow.d.ts.map +1 -0
  75. package/packages/client-agent-team/lib/types/client/TeamMemberRow.js +27 -0
  76. package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts +2 -2
  77. package/packages/client-agent-team/lib/types/client/TeamMembersAction.d.ts.map +1 -1
  78. package/packages/client-agent-team/lib/types/client/TeamMembersAction.js +2 -2
  79. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts +1 -1
  80. package/packages/client-agent-team/lib/types/client/TeamPresenceDot.d.ts.map +1 -1
  81. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  82. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +21 -31
  83. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
  84. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  85. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +29 -11
  86. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  87. package/packages/client-agent-team/lib/types/client/index.js +11 -5
  88. package/packages/client-agent-team/lib/types/client/locales.d.ts +54 -16
  89. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  90. package/packages/client-agent-team/lib/types/client/locales.js +54 -16
  91. package/packages/client-agent-team/lib/types/client/slots.d.ts +3 -2
  92. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  93. package/packages/client-agent-team/lib/types/client/team-changes.d.ts +15 -25
  94. package/packages/client-agent-team/lib/types/client/team-changes.d.ts.map +1 -1
  95. package/packages/client-agent-team/lib/types/client/team-changes.js +82 -80
  96. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +45 -10
  97. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  98. package/packages/client-agent-team/lib/types/client/team-formatters.js +71 -30
  99. package/packages/tool-agent-team/README.md +3 -3
  100. package/packages/tool-agent-team/README.zh.md +3 -3
  101. package/packages/tool-agent-team/lib/host-access.js +19 -0
  102. package/packages/tool-agent-team/lib/index.js +71 -49
  103. package/packages/tool-agent-team/lib/types/host-access.d.ts +10 -0
  104. package/packages/tool-agent-team/lib/types/host-access.d.ts.map +1 -1
  105. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
  106. package/packages/agent-team/lib/progress-nudge.js +0 -328
  107. package/packages/agent-team/lib/types/progress-nudge.d.ts +0 -136
  108. package/packages/agent-team/lib/types/progress-nudge.d.ts.map +0 -1
  109. package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts +0 -3
  110. package/packages/client-agent-team/lib/types/client/TeamSettings.d.ts.map +0 -1
  111. package/packages/client-agent-team/lib/types/client/TeamSettings.js +0 -5
  112. package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts +0 -41
  113. package/packages/client-agent-team/lib/types/client/scope-coverage.d.ts.map +0 -1
  114. package/packages/client-agent-team/lib/types/client/scope-coverage.js +0 -64
@@ -1,328 +0,0 @@
1
- /**
2
- * Progress-visibility nudges: advisory Session notices that keep Member agents
3
- * reporting progress into their Threads. Two regimes over one shared
4
- * per-Member silent-tool-call counter:
5
- *
6
- * - Thread progress (A): a Member holding an active Claim, or following a
7
- * taskless Thread, that has run many tool calls since its last committed
8
- * public communication is reminded to post a brief update. The reminder
9
- * ladder advances 20 → 40 → 60… per Member.
10
- * - Claim suggestion (B): a Member following a still-`todo` Task it has never
11
- * claimed is reminded — once per (Member, Thread) within the current Member
12
- * Session — that team_claim exists.
13
- *
14
- * The Coordinator owns counting, thresholds, notice formatting, dedupe,
15
- * in-flight revocation, and the deferred steer. It consumes only facts the
16
- * Host already holds: live `tool/call`/`user/message` session events in their
17
- * real `{type, seq, time, data}` envelope, the Session log for one-time
18
- * recovery, committed ledger operations, and a ledger-owned eligibility
19
- * projection (`progressNudgeTargets`). It never writes Team facts and never
20
- * wakes idle agents on its own — a nudge rides the member's next tool call.
21
- *
22
- * @module @wowyuarm/dsh-agent-team/progress-nudge
23
- */
24
- import { createUserMessage } from '@deepseek-ai/dsh-llm';
25
- import { AGENT_TEAM_PLUGIN_ID, isCheckpointContinuationMessage } from "./context-source.js";
26
- /** Notice summary for every nudge this Coordinator injects. */
27
- export const PROGRESS_NUDGE_NOTICE_SUMMARY = 'Progress visibility reminder';
28
- export const PROGRESS_NUDGE_TOOL_CALLS_START = 20;
29
- export const PROGRESS_NUDGE_TOOL_CALLS_STEP = 20;
30
- export const CLAIM_SUGGESTION_TOOL_CALLS = 5;
31
- /** Stable line prefix marking Claim-suggestion targets inside a nudge notice; the only text this module ever parses back. */
32
- const CLAIM_TARGET_LINE_PREFIX = '- Claim target: Task ';
33
- const CLAIM_TARGET_LINE = /^- Claim target: Task (task:[0-9a-f-]+) — Thread (thread:[0-9a-f-]+)$/;
34
- /** Ledger operation kinds that count as committed public communication and reset silence. */
35
- export function isPublicCommunicationOperationKind(kind) {
36
- return kind === 'team/message-sent' || kind === 'team/thread-replied'
37
- || kind === 'team/claim-created' || kind === 'team/claim-done' || kind === 'team/claim-released';
38
- }
39
- /** Whether one message is a nudge notice this module injected. */
40
- export function isProgressNudgeNotice(message) {
41
- const source = message.source;
42
- return source.kind === 'plugin' && source.plugin === AGENT_TEAM_PLUGIN_ID
43
- && source.form === 'notice' && source.summary === PROGRESS_NUDGE_NOTICE_SUMMARY;
44
- }
45
- /**
46
- * Event-driven per-Member nudge state machine. All state is in-process and
47
- * scoped to one Member Session; nothing is persisted. The Host feeds it live
48
- * session events in their real envelope, committed operations, and lifecycle
49
- * stop points.
50
- */
51
- export class ProgressNudgeCoordinator {
52
- members = new Map();
53
- agentForMember;
54
- targetsForMember;
55
- sessionLogForMember;
56
- log;
57
- scheduleSteer;
58
- progressThresholdStart;
59
- progressThresholdStep;
60
- claimSuggestionThreshold;
61
- constructor(options) {
62
- this.agentForMember = options.agentForMember;
63
- this.targetsForMember = options.targetsForMember;
64
- this.sessionLogForMember = options.sessionLogForMember;
65
- this.log = options.log;
66
- this.scheduleSteer = options.scheduleSteer ?? (run => { queueMicrotask(run); });
67
- this.progressThresholdStart = options.progressThresholdStart ?? PROGRESS_NUDGE_TOOL_CALLS_START;
68
- this.progressThresholdStep = options.progressThresholdStep ?? PROGRESS_NUDGE_TOOL_CALLS_STEP;
69
- this.claimSuggestionThreshold = options.claimSuggestionThreshold ?? CLAIM_SUGGESTION_TOOL_CALLS;
70
- }
71
- /**
72
- * One live session event for a Member, in its real `{type, seq, time, data}`
73
- * envelope. Only `tool/call` counts toward silence; a `user/message` whose
74
- * source is exactly this module's own notice records that the model consumed
75
- * the nudge (a Claim suggestion becomes final only then). The live `agent`
76
- * is passed in by the caller because it exists at event time even before
77
- * the Host finishes publishing the handle.
78
- */
79
- onSessionEvent(memberId, sessionId, agent, event) {
80
- if (event.type === 'user/message') {
81
- if (!isProgressNudgeNotice(event.data))
82
- return;
83
- const state = this.members.get(memberId);
84
- if (state === undefined)
85
- return;
86
- const notice = state.pending;
87
- if (notice !== undefined && notice.messageId === event.data.id)
88
- state.pending = undefined;
89
- for (const threadRef of claimTargetThreadRefs(event.data))
90
- state.claimSuggested.add(threadRef);
91
- return;
92
- }
93
- if (event.type !== 'tool/call')
94
- return;
95
- let state = this.members.get(memberId);
96
- if (state === undefined || state.sessionId !== sessionId) {
97
- // First event of this Member Session (or a generation the Host did not
98
- // stop explicitly): fresh tracking replaces whatever was there, and
99
- // consumed one-time suggestions are recovered from the durable log so a
100
- // Host restart or suspend/resume within the same Session cannot repeat
101
- // them. A Human-initiated new Session has a different id and starts
102
- // empty, exactly as specified.
103
- this.dropState(memberId, state);
104
- state = { sessionId, silentToolCalls: 0, nextProgressThreshold: this.progressThresholdStart,
105
- claimSuggested: this.recoverClaimSuggestions(memberId, sessionId), };
106
- this.members.set(memberId, state);
107
- }
108
- state.silentToolCalls += 1;
109
- if (state.lastNudgeTurn === event.data.turn)
110
- return;
111
- this.maybeNudge(memberId, state, agent, event.data.turn);
112
- }
113
- /**
114
- * One ledger operation committed. A Member actor's public communication
115
- * resets its silence; every commit also reconciles pending notices whose
116
- * targets may have just disappeared (Task accepted, Channel archived, the
117
- * Claim taken by someone else).
118
- */
119
- onCommitted(operation) {
120
- if (operation.actor.kind === 'member' && operation.actor.memberId !== undefined
121
- && isPublicCommunicationOperationKind(operation.kind)) {
122
- const state = this.members.get(operation.actor.memberId);
123
- if (state !== undefined) {
124
- state.silentToolCalls = 0;
125
- state.nextProgressThreshold = this.progressThresholdStart;
126
- this.revokePending(operation.actor.memberId, state);
127
- }
128
- }
129
- this.reconcileAll();
130
- }
131
- /** Revoke one Member's queued-but-unconsumed nudge, e.g. when a higher-priority Team notice is injected. */
132
- revokePendingNotice(memberId) {
133
- const state = this.members.get(memberId);
134
- if (state !== undefined)
135
- this.revokePending(memberId, state);
136
- }
137
- /** Drop all tracking for one Member (suspend/archive/remove/renew/context-clear/steer failure). */
138
- stopTracking(memberId) {
139
- this.dropState(memberId, this.members.get(memberId));
140
- this.members.delete(memberId);
141
- }
142
- /** Stop tracking every Member. */
143
- dispose() {
144
- for (const memberId of this.members.keys())
145
- this.stopTracking(memberId);
146
- }
147
- /** Rebuild the consumed one-time suggestion set from this Session's durable log. */
148
- recoverClaimSuggestions(memberId, sessionId) {
149
- const suggested = new Set();
150
- const log = this.sessionLogForMember(memberId, sessionId);
151
- if (log === undefined)
152
- return suggested;
153
- for (const event of log.events) {
154
- if (event.type !== 'user/message')
155
- continue;
156
- if (!isProgressNudgeNotice(event.data))
157
- continue;
158
- for (const threadRef of claimTargetThreadRefs(event.data))
159
- suggested.add(threadRef);
160
- }
161
- return suggested;
162
- }
163
- dropState(memberId, state) {
164
- if (state === undefined)
165
- return;
166
- this.revokePending(memberId, state);
167
- this.members.delete(memberId);
168
- }
169
- revokePending(memberId, state) {
170
- const notice = state.pending;
171
- if (notice !== undefined) {
172
- notice.canceled = true;
173
- if (notice.steered) {
174
- const agent = this.agentForMember(memberId);
175
- const pending = agent === undefined ? undefined
176
- : [...agent.inbox.nextStep, ...agent.inbox.nextTurn].find(message => message.id === notice.messageId);
177
- // A just-consumed notice is simply gone; remove() returning false is expected.
178
- if (pending !== undefined)
179
- agent.inbox.remove(pending.id);
180
- }
181
- }
182
- state.pending = undefined;
183
- }
184
- /** Re-check every live Member's pending notice against the targets it actually listed. */
185
- reconcileAll() {
186
- for (const [memberId, state] of this.members) {
187
- const notice = state.pending;
188
- if (notice === undefined)
189
- continue;
190
- const agent = this.agentForMember(memberId);
191
- if (agent === undefined) {
192
- this.dropState(memberId, state);
193
- continue;
194
- }
195
- const targets = this.targetsForMember(memberId);
196
- // The notice is stale when ANY target it listed is no longer eligible:
197
- // the body names threads whose work may be finished, so a partial
198
- // survival must not keep the whole stale notice alive.
199
- const progressAlive = notice.progressThreadRefs.length === 0
200
- || notice.progressThreadRefs.every(threadRef => targets.progress.some(target => target.threadRef === threadRef));
201
- const claimAlive = notice.claimThreadRefs.length === 0
202
- || notice.claimThreadRefs.every(threadRef => targets.claim.some(target => target.threadRef === threadRef));
203
- if (!progressAlive || !claimAlive)
204
- this.revokePending(memberId, state);
205
- }
206
- }
207
- maybeNudge(memberId, state, agent, turn) {
208
- const targets = this.targetsForMember(memberId);
209
- const progressDue = state.silentToolCalls >= state.nextProgressThreshold && targets.progress.length > 0;
210
- const freshClaimTargets = targets.claim
211
- .filter(target => !state.claimSuggested.has(target.threadRef) && state.pending?.claimThreadRefs.includes(target.threadRef) !== true);
212
- const claimDue = state.silentToolCalls >= this.claimSuggestionThreshold && freshClaimTargets.length > 0;
213
- if (!progressDue && !claimDue)
214
- return;
215
- if (this.hasBlockingNotice(agent))
216
- return;
217
- const progressTargets = progressDue ? targets.progress : [];
218
- const claimTargets = claimDue ? freshClaimTargets : [];
219
- const notice = createUserMessage({
220
- content: [{ type: 'text', text: nudgeNoticeText(state.silentToolCalls, progressTargets, claimTargets) }],
221
- source: { kind: 'plugin', plugin: AGENT_TEAM_PLUGIN_ID, form: 'notice', summary: PROGRESS_NUDGE_NOTICE_SUMMARY },
222
- });
223
- const pending = {
224
- messageId: notice.id,
225
- progressThreadRefs: progressTargets.map(target => target.threadRef),
226
- claimThreadRefs: claimTargets.map(target => target.threadRef),
227
- steered: false,
228
- canceled: false,
229
- };
230
- // Record intent first: the scheduled steer, its cancellation check, and
231
- // its failure handling all live on this single PendingNotice object, so a
232
- // revoke between queueing and the microtask leaves no orphan injection.
233
- // lastNudgeTurn stays as the same-turn intent guard, but the A threshold
234
- // only commits after the real steer succeeds — a canceled or failed
235
- // schedule leaves the rung due so the next tool call retries it.
236
- state.pending = pending;
237
- state.lastNudgeTurn = turn;
238
- this.scheduleSteer(() => {
239
- if (pending.canceled)
240
- return;
241
- try {
242
- agent.steer(notice);
243
- }
244
- catch (error) {
245
- this.log?.(`progress nudge steer failed for member '${memberId}': ${error instanceof Error ? error.message : String(error)}`);
246
- pending.canceled = true;
247
- if (state.pending === pending)
248
- state.pending = undefined;
249
- this.stopTracking(memberId);
250
- return;
251
- }
252
- pending.steered = true;
253
- if (pending.progressThreadRefs.length > 0) {
254
- // Advance the ladder past the count at real success in one move: a
255
- // long silence held back by higher-priority notices must not replay
256
- // every skipped rung on successive tool calls after the blocker
257
- // clears.
258
- while (state.nextProgressThreshold <= state.silentToolCalls)
259
- state.nextProgressThreshold += this.progressThresholdStep;
260
- }
261
- });
262
- }
263
- /**
264
- * Recovery, Inbox, and pre-compaction notices outrank a progress nudge. If
265
- * one is already pending, this nudge stays due and retries on the next tool
266
- * call; a DM relay is not a notice and never blocks.
267
- */
268
- hasBlockingNotice(agent) {
269
- for (const message of [...agent.inbox.nextStep, ...agent.inbox.nextTurn]) {
270
- const source = message.source;
271
- if (source.kind !== 'plugin' || source.plugin !== AGENT_TEAM_PLUGIN_ID)
272
- continue;
273
- // A queued checkpoint continuation is a pending wake that outranks a
274
- // nudge exactly as the notice families above do. It rides the snapshot
275
- // form (it must carry its checkpoint ref in a section), so it cannot be
276
- // recognized by the notice summary check below.
277
- if (isCheckpointContinuationMessage(message))
278
- return true;
279
- if (source.form !== 'notice')
280
- continue;
281
- if (source.summary !== PROGRESS_NUDGE_NOTICE_SUMMARY)
282
- return true;
283
- }
284
- return false;
285
- }
286
- }
287
- /** Extract the threadRefs this module itself wrote as Claim targets in one notice. */
288
- function claimTargetThreadRefs(message) {
289
- const refs = [];
290
- for (const block of message.content) {
291
- if (block.type !== 'text')
292
- continue;
293
- for (const line of block.text.split('\n')) {
294
- const match = CLAIM_TARGET_LINE.exec(line);
295
- if (match !== null)
296
- refs.push(match[2]);
297
- }
298
- }
299
- return refs;
300
- }
301
- function nudgeNoticeText(silentToolCalls, progress, claim) {
302
- const sections = [];
303
- if (progress.length > 0) {
304
- sections.push([
305
- 'Progress visibility reminder',
306
- '',
307
- `You have made ${silentToolCalls} tool calls since your last visible Team update. Please briefly update the relevant Thread(s): what you confirmed, what remains, and any blocker. Read the Thread first if needed, then continue working.`,
308
- '',
309
- ...progress.map(target => target.reason === 'active-claim'
310
- ? `- Task ${target.taskRef} — Thread ${target.threadRef}`
311
- : `- Taskless Thread ${target.threadRef} (reply only if your current work relates to it)`),
312
- ].join('\n'));
313
- }
314
- if (claim.length > 0) {
315
- sections.push([
316
- 'Claim visibility reminder',
317
- '',
318
- 'You have been working while following the Task(s) below, but you have never claimed a direction there.',
319
- '',
320
- ...claim.map(target => `${CLAIM_TARGET_LINE_PREFIX}${target.taskRef} — Thread ${target.threadRef}`),
321
- '',
322
- 'If your current work belongs to one of these Tasks, briefly state your direction in its Thread and consider team_claim. If it does not, no action is required. This is advisory, not a claim requirement.',
323
- ].join('\n'));
324
- }
325
- if (progress.length > 0)
326
- sections.push('This is advisory; do not stop useful work merely to produce a long status report.');
327
- return sections.join('\n\n');
328
- }
@@ -1,136 +0,0 @@
1
- /**
2
- * Progress-visibility nudges: advisory Session notices that keep Member agents
3
- * reporting progress into their Threads. Two regimes over one shared
4
- * per-Member silent-tool-call counter:
5
- *
6
- * - Thread progress (A): a Member holding an active Claim, or following a
7
- * taskless Thread, that has run many tool calls since its last committed
8
- * public communication is reminded to post a brief update. The reminder
9
- * ladder advances 20 → 40 → 60… per Member.
10
- * - Claim suggestion (B): a Member following a still-`todo` Task it has never
11
- * claimed is reminded — once per (Member, Thread) within the current Member
12
- * Session — that team_claim exists.
13
- *
14
- * The Coordinator owns counting, thresholds, notice formatting, dedupe,
15
- * in-flight revocation, and the deferred steer. It consumes only facts the
16
- * Host already holds: live `tool/call`/`user/message` session events in their
17
- * real `{type, seq, time, data}` envelope, the Session log for one-time
18
- * recovery, committed ledger operations, and a ledger-owned eligibility
19
- * projection (`progressNudgeTargets`). It never writes Team facts and never
20
- * wakes idle agents on its own — a nudge rides the member's next tool call.
21
- *
22
- * @module @wowyuarm/dsh-agent-team/progress-nudge
23
- */
24
- import { type UserMessage } from '@deepseek-ai/dsh-llm';
25
- import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session';
26
- import type { AgentTeamMemberId, AgentTeamProgressNudgeTargets } from './types.ts';
27
- /** Notice summary for every nudge this Coordinator injects. */
28
- export declare const PROGRESS_NUDGE_NOTICE_SUMMARY = "Progress visibility reminder";
29
- export declare const PROGRESS_NUDGE_TOOL_CALLS_START = 20;
30
- export declare const PROGRESS_NUDGE_TOOL_CALLS_STEP = 20;
31
- export declare const CLAIM_SUGGESTION_TOOL_CALLS = 5;
32
- /** Minimal Agent surface the Coordinator depends on; real Agents satisfy it, tests fake it. */
33
- export interface ProgressNudgeAgent {
34
- readonly inbox: {
35
- readonly nextStep: readonly UserMessage[];
36
- readonly nextTurn: readonly UserMessage[];
37
- remove(messageId: UserMessage['id']): boolean;
38
- };
39
- steer(message: UserMessage): void;
40
- }
41
- /**
42
- * Read-only view of one Session log used to recover consumed one-time Claim
43
- * suggestions when a Member Session's tracking is (re)established.
44
- */
45
- export interface ProgressNudgeSessionLog {
46
- /** Durable events in sequence order; the real `Session.ownEvents()`. */
47
- readonly events: readonly SessionEvent[];
48
- }
49
- /** Minimal operation fact the Coordinator consumes; the ledger's full record satisfies it structurally. */
50
- export interface ProgressNudgeOperation {
51
- readonly actor: {
52
- readonly kind: string;
53
- readonly memberId?: AgentTeamMemberId | undefined;
54
- };
55
- readonly kind: string;
56
- }
57
- export interface ProgressNudgeCoordinatorOptions {
58
- /** Live Agent lookup for revocation and injection. */
59
- readonly agentForMember: (memberId: AgentTeamMemberId) => ProgressNudgeAgent | undefined;
60
- /** Current eligibility projection from the ledger. */
61
- readonly targetsForMember: (memberId: AgentTeamMemberId) => AgentTeamProgressNudgeTargets;
62
- /** Durable Session log lookup for one-time recovery on (re)activation. */
63
- readonly sessionLogForMember: (memberId: AgentTeamMemberId, sessionId: SessionId) => ProgressNudgeSessionLog | undefined;
64
- /** Log one line when steer fails; the Host wires its logger. */
65
- readonly log?: (message: string) => void;
66
- /**
67
- * Schedule the actual steer past an in-flight session append publication.
68
- * The default defers one microtask; tests may substitute a synchronous or
69
- * manually triggered scheduler. The callback runs the real steer.
70
- */
71
- readonly scheduleSteer?: (run: () => void) => void;
72
- /** Initial ladder start; tests override to keep runs small. */
73
- readonly progressThresholdStart?: number;
74
- /** Ladder step; tests override to keep runs small. */
75
- readonly progressThresholdStep?: number;
76
- /** Claim-suggestion threshold; tests override to keep runs small. */
77
- readonly claimSuggestionThreshold?: number;
78
- }
79
- /** Ledger operation kinds that count as committed public communication and reset silence. */
80
- export declare function isPublicCommunicationOperationKind(kind: string): boolean;
81
- /** Whether one message is a nudge notice this module injected. */
82
- export declare function isProgressNudgeNotice(message: UserMessage): boolean;
83
- /**
84
- * Event-driven per-Member nudge state machine. All state is in-process and
85
- * scoped to one Member Session; nothing is persisted. The Host feeds it live
86
- * session events in their real envelope, committed operations, and lifecycle
87
- * stop points.
88
- */
89
- export declare class ProgressNudgeCoordinator {
90
- private readonly members;
91
- private readonly agentForMember;
92
- private readonly targetsForMember;
93
- private readonly sessionLogForMember;
94
- private readonly log;
95
- private readonly scheduleSteer;
96
- private readonly progressThresholdStart;
97
- private readonly progressThresholdStep;
98
- private readonly claimSuggestionThreshold;
99
- constructor(options: ProgressNudgeCoordinatorOptions);
100
- /**
101
- * One live session event for a Member, in its real `{type, seq, time, data}`
102
- * envelope. Only `tool/call` counts toward silence; a `user/message` whose
103
- * source is exactly this module's own notice records that the model consumed
104
- * the nudge (a Claim suggestion becomes final only then). The live `agent`
105
- * is passed in by the caller because it exists at event time even before
106
- * the Host finishes publishing the handle.
107
- */
108
- onSessionEvent(memberId: AgentTeamMemberId, sessionId: SessionId, agent: ProgressNudgeAgent, event: SessionEvent): void;
109
- /**
110
- * One ledger operation committed. A Member actor's public communication
111
- * resets its silence; every commit also reconciles pending notices whose
112
- * targets may have just disappeared (Task accepted, Channel archived, the
113
- * Claim taken by someone else).
114
- */
115
- onCommitted(operation: ProgressNudgeOperation): void;
116
- /** Revoke one Member's queued-but-unconsumed nudge, e.g. when a higher-priority Team notice is injected. */
117
- revokePendingNotice(memberId: AgentTeamMemberId): void;
118
- /** Drop all tracking for one Member (suspend/archive/remove/renew/context-clear/steer failure). */
119
- stopTracking(memberId: AgentTeamMemberId): void;
120
- /** Stop tracking every Member. */
121
- dispose(): void;
122
- /** Rebuild the consumed one-time suggestion set from this Session's durable log. */
123
- private recoverClaimSuggestions;
124
- private dropState;
125
- private revokePending;
126
- /** Re-check every live Member's pending notice against the targets it actually listed. */
127
- private reconcileAll;
128
- private maybeNudge;
129
- /**
130
- * Recovery, Inbox, and pre-compaction notices outrank a progress nudge. If
131
- * one is already pending, this nudge stays due and retries on the next tool
132
- * call; a DM relay is not a notice and never blocks.
133
- */
134
- private hasBlockingNotice;
135
- }
136
- //# sourceMappingURL=progress-nudge.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"progress-nudge.d.ts","sourceRoot":"","sources":["../../src/progress-nudge.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import type { TeamSettingsProps } from './slots.ts';
2
- export declare function TeamSettings({ wide, loadMemberGroups, t }: TeamSettingsProps): import("react").JSX.Element;
3
- //# sourceMappingURL=TeamSettings.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TeamSettings.d.ts","sourceRoot":"","sources":["../../../src/client/TeamSettings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGnD,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,iBAAiB,+BAE5E"}
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { TeamMembersAction } from "./TeamMembersAction.js";
3
- export function TeamSettings({ wide, loadMemberGroups, t }) {
4
- return _jsx(TeamMembersAction, { wide: wide, loadMemberGroups: loadMemberGroups, t: t });
5
- }
@@ -1,41 +0,0 @@
1
- /** The change scopes whose wakes one surface answers with a shared refresh round. */
2
- export type SupplementalScope = 'workspace' | 'presence';
3
- /** One change wake, carrying a version from the scope that issued it. */
4
- export interface ScopeWake {
5
- readonly scope: SupplementalScope;
6
- readonly version: number;
7
- }
8
- /**
9
- * Per-scope coverage of the change versions one surface has already answered.
10
- *
11
- * A version is only comparable inside the scope that issued it: the Host
12
- * answers a workspace scope from the durable ledger position and a presence
13
- * scope from its process-local wake epoch, which starts low and climbs on every
14
- * Agent transition. One high-water mark shared by both would therefore let a
15
- * presence epoch swallow a later, smaller ledger sequence and park the surface
16
- * on stale data, so coverage and pending versions are kept per scope.
17
- *
18
- * One round answers one version per scope. The Host delivers one event to every
19
- * matching scope, so the first version a round sees in a scope it has not
20
- * answered yet is that event reaching a second scope, and joins the round
21
- * already fetching instead of earning a second identical read. A newer version
22
- * in a scope the round has answered arrived after the round issued its fetch,
23
- * so it owes one trailing round.
24
- */
25
- export declare class ScopeCoverage {
26
- private readonly covered;
27
- private readonly pending;
28
- /** The scopes the open round has an answer for. */
29
- private readonly answered;
30
- private fetching;
31
- /** Folds one wake in and answers whether it opens a round. */
32
- wake(scope: SupplementalScope, version: number): boolean;
33
- /** Opens a round's fetch window; versions observed from here on are pending. */
34
- beginRound(): void;
35
- /** Closes a round's fetch window and answers whether a trailing round is owed. */
36
- finishRound(): boolean;
37
- /** Drops every observation: a new owner starts with nothing covered. */
38
- reset(): void;
39
- private coveredOf;
40
- }
41
- //# sourceMappingURL=scope-coverage.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scope-coverage.d.ts","sourceRoot":"","sources":["../../../src/client/scope-coverage.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAAA;AAExD,yEAAyE;AACzE,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAQ;IAExB,8DAA8D;IAC9D,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAWxD,gFAAgF;IAChF,UAAU,IAAI,IAAI;IAKlB,kFAAkF;IAClF,WAAW,IAAI,OAAO;IAYtB,wEAAwE;IACxE,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,SAAS;CAGlB"}
@@ -1,64 +0,0 @@
1
- /**
2
- * Per-scope coverage of the change versions one surface has already answered.
3
- *
4
- * A version is only comparable inside the scope that issued it: the Host
5
- * answers a workspace scope from the durable ledger position and a presence
6
- * scope from its process-local wake epoch, which starts low and climbs on every
7
- * Agent transition. One high-water mark shared by both would therefore let a
8
- * presence epoch swallow a later, smaller ledger sequence and park the surface
9
- * on stale data, so coverage and pending versions are kept per scope.
10
- *
11
- * One round answers one version per scope. The Host delivers one event to every
12
- * matching scope, so the first version a round sees in a scope it has not
13
- * answered yet is that event reaching a second scope, and joins the round
14
- * already fetching instead of earning a second identical read. A newer version
15
- * in a scope the round has answered arrived after the round issued its fetch,
16
- * so it owes one trailing round.
17
- */
18
- export class ScopeCoverage {
19
- covered = new Map();
20
- pending = new Map();
21
- /** The scopes the open round has an answer for. */
22
- answered = new Set();
23
- fetching = false;
24
- /** Folds one wake in and answers whether it opens a round. */
25
- wake(scope, version) {
26
- if (version <= this.coveredOf(scope))
27
- return false;
28
- if (this.fetching && this.answered.has(scope)) {
29
- this.pending.set(scope, Math.max(this.pending.get(scope) ?? 0, version));
30
- return false;
31
- }
32
- this.answered.add(scope);
33
- this.covered.set(scope, version);
34
- return !this.fetching;
35
- }
36
- /** Opens a round's fetch window; versions observed from here on are pending. */
37
- beginRound() {
38
- this.pending.clear();
39
- this.fetching = true;
40
- }
41
- /** Closes a round's fetch window and answers whether a trailing round is owed. */
42
- finishRound() {
43
- this.fetching = false;
44
- this.answered.clear();
45
- let owed = false;
46
- for (const [scope, version] of this.pending) {
47
- if (version <= this.coveredOf(scope))
48
- continue;
49
- this.covered.set(scope, version);
50
- owed = true;
51
- }
52
- return owed;
53
- }
54
- /** Drops every observation: a new owner starts with nothing covered. */
55
- reset() {
56
- this.covered.clear();
57
- this.pending.clear();
58
- this.answered.clear();
59
- this.fetching = false;
60
- }
61
- coveredOf(scope) {
62
- return this.covered.get(scope) ?? 0;
63
- }
64
- }