@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
|
@@ -9,18 +9,7 @@
|
|
|
9
9
|
* @module @wowyuarm/dsh-agent-team/context-tools
|
|
10
10
|
*/
|
|
11
11
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
12
|
-
|
|
13
|
-
const host = agent.ctx.get('agentTeam');
|
|
14
|
-
if (host === undefined)
|
|
15
|
-
throw new Error('Agent Team Host is unavailable');
|
|
16
|
-
return host;
|
|
17
|
-
}
|
|
18
|
-
function member(agent) {
|
|
19
|
-
const current = service(agent).memberForAgent(agent);
|
|
20
|
-
if (current === undefined)
|
|
21
|
-
throw new Error('team tool requires an active Team Member');
|
|
22
|
-
return current;
|
|
23
|
-
}
|
|
12
|
+
import { member, service } from "./host-access.js";
|
|
24
13
|
const MAX_HANDOFF_CHARS = 32 * 1024;
|
|
25
14
|
const MAX_RELATED_FILES = 32;
|
|
26
15
|
const contextRollover = defineTool({
|
|
@@ -139,13 +128,19 @@ const contextTimeline = defineTool({
|
|
|
139
128
|
reason: { type: 'string' },
|
|
140
129
|
sourceSessionId: { type: 'string' },
|
|
141
130
|
} } },
|
|
131
|
+
incompleteFrom: { type: 'object', additionalProperties: false, properties: {
|
|
132
|
+
sessionId: { type: 'string', required: true },
|
|
133
|
+
reason: { type: 'string', required: true },
|
|
134
|
+
} },
|
|
142
135
|
} },
|
|
143
136
|
// The item list is the whole decision surface: without each anchor's
|
|
144
137
|
// ref, label, source, size estimates, affected Threads, and
|
|
145
138
|
// restorable/reason verdict, the model cannot pick a `checkpointRef` for
|
|
146
139
|
// `context_rollover` — the summary line alone left the tool unusable for
|
|
147
140
|
// seeded returns. The Host bounds items (default 12, at most 24), so this
|
|
148
|
-
// list cannot grow unbounded.
|
|
141
|
+
// list cannot grow unbounded. `incompleteFrom` states where and why the
|
|
142
|
+
// lineage walk stopped early, so history read up to that ancestor is
|
|
143
|
+
// known to be a truncation, not everything that exists.
|
|
149
144
|
render: (_args, value) => {
|
|
150
145
|
const lines = [`Context timeline: ${value.usageTokens} tokens used (handoff at ${value.handoffAt}, hard limit ${value.hardLimit}). ${value.items.length} item(s):`];
|
|
151
146
|
for (const item of value.items) {
|
|
@@ -156,6 +151,9 @@ const contextTimeline = defineTool({
|
|
|
156
151
|
: `not restorable — ${item.reason ?? 'no reason given'}`;
|
|
157
152
|
lines.push(`- ${item.name} [source: ${item.source}] (${size}; ${threads}) — ${restorable}`);
|
|
158
153
|
}
|
|
154
|
+
if (value.incompleteFrom !== undefined) {
|
|
155
|
+
lines.push(`History incomplete: the lineage walk stopped at Session ${value.incompleteFrom.sessionId} (${value.incompleteFrom.reason}); ancestors before it could not be read and are not reflected above.`);
|
|
156
|
+
}
|
|
159
157
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
160
158
|
},
|
|
161
159
|
},
|
|
@@ -169,7 +167,13 @@ const contextTimeline = defineTool({
|
|
|
169
167
|
const result = await host.contextTimelineForAgent(agent, { memberId: current.memberId, ...(limit === undefined ? {} : { limit }) });
|
|
170
168
|
// The Host result is deeply immutable; the tool output contract carries
|
|
171
169
|
// plain arrays, so re-shape without any semantic change.
|
|
172
|
-
return {
|
|
170
|
+
return {
|
|
171
|
+
usageTokens: result.usageTokens,
|
|
172
|
+
hardLimit: result.hardLimit,
|
|
173
|
+
handoffAt: result.handoffAt,
|
|
174
|
+
items: result.items.map(item => ({ ...item, affectedThreads: [...item.affectedThreads] })),
|
|
175
|
+
...(result.incompleteFrom === undefined ? {} : { incompleteFrom: result.incompleteFrom }),
|
|
176
|
+
};
|
|
173
177
|
},
|
|
174
178
|
});
|
|
175
179
|
export function registerContextTools(ctx) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Host accessors for every Team tool module. `agent.ctx.get` is the
|
|
3
|
+
* one resolution path a tool row has — the preset mounts these tools beside
|
|
4
|
+
* the Host, so a missing service or an inactive Member is a model-visible
|
|
5
|
+
* rejection rather than a silent no-op. Both messages are user-facing text.
|
|
6
|
+
*/
|
|
7
|
+
/** Resolve the Team Host service, or reject the tool call. */
|
|
8
|
+
export function service(agent) {
|
|
9
|
+
const host = agent.ctx.get('agentTeam');
|
|
10
|
+
if (host === undefined)
|
|
11
|
+
throw new Error('Agent Team Host is unavailable');
|
|
12
|
+
return host;
|
|
13
|
+
}
|
|
14
|
+
/** Resolve the calling Team Member, or reject the tool call. */
|
|
15
|
+
export function member(agent) {
|
|
16
|
+
const current = service(agent).memberForAgent(agent);
|
|
17
|
+
if (current === undefined)
|
|
18
|
+
throw new Error('team tool requires an active Team Member');
|
|
19
|
+
return current;
|
|
20
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { AgentTeamDmDeliveryError, markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
|
|
1
|
+
import { AGENT_TEAM_HUMAN_HANDLE, AgentTeamDmDeliveryError, markAgentTeamPreset } from '@wowyuarm/dsh-agent-team/host';
|
|
2
2
|
import { formatTeamTimestamp } from '@wowyuarm/dsh-agent-team/time-format';
|
|
3
3
|
import { registerContextTools } from "./context-tools.js";
|
|
4
|
+
import { member, service } from "./host-access.js";
|
|
4
5
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
5
6
|
export const name = 'wowyuarm-agent-team-tools';
|
|
6
7
|
export const inject = ['tools'];
|
|
@@ -76,18 +77,6 @@ function taskStanding(value) {
|
|
|
76
77
|
return '';
|
|
77
78
|
return `${value.taskRef}${value.taskNumber === undefined ? '' : ` (#${value.taskNumber})`}${value.status === undefined ? '' : `, ${value.status}${value.resolution === undefined ? '' : `/${value.resolution}`}`}`;
|
|
78
79
|
}
|
|
79
|
-
function service(agent) {
|
|
80
|
-
const host = agent.ctx.get('agentTeam');
|
|
81
|
-
if (host === undefined)
|
|
82
|
-
throw new Error('Agent Team Host is unavailable');
|
|
83
|
-
return host;
|
|
84
|
-
}
|
|
85
|
-
function member(agent) {
|
|
86
|
-
const current = service(agent).memberForAgent(agent);
|
|
87
|
-
if (current === undefined)
|
|
88
|
-
throw new Error('team tool requires an active Team Member');
|
|
89
|
-
return current;
|
|
90
|
-
}
|
|
91
80
|
function requestId(agentId, callId) {
|
|
92
81
|
return `agent-team:tool:${agentId}:${callId}`;
|
|
93
82
|
}
|
|
@@ -178,7 +167,7 @@ const teamInbox = defineTool({
|
|
|
178
167
|
});
|
|
179
168
|
const teamThread = defineTool({
|
|
180
169
|
name: 'team_thread',
|
|
181
|
-
description: 'Read or manage your Attention on one Thread. read acknowledges one chronological batch of unread facts and is the only read-side source of a next-write token — and only once no unread remains; your own committed public mutations hand off the token as well. history pages older facts without changing read state; status, follow, and unfollow change or report Attention only and render no Thread timeline. Prefer threadRef; taskRef is a compatibility alias when the Thread has a Task.',
|
|
170
|
+
description: 'Read or manage your Attention on one Thread. read acknowledges one chronological batch of unread facts and is the only read-side source of a next-write token — and only once no unread remains; your own committed public mutations hand off the token as well. A read orients on the Thread anchor and that batch, never the whole Thread: a Member re-entering one it has read before gets no background at all, so the facts between are its own to page back to. history pages older facts without changing read state; status, follow, and unfollow change or report Attention only and render no Thread timeline. Prefer threadRef; taskRef is a compatibility alias when the Thread has a Task.',
|
|
182
171
|
parameters: {
|
|
183
172
|
action: { type: 'string', required: true, enum: ['status', 'follow', 'unfollow', 'read', 'history'] },
|
|
184
173
|
threadRef: { type: 'string', description: "Full branded Thread ref exactly as returned by Team tools, including the 'thread:' prefix. An unambiguous abbreviation of the first 6+ UUID hex characters also resolves." },
|
|
@@ -189,7 +178,7 @@ const teamThread = defineTool({
|
|
|
189
178
|
schema: { type: 'object', additionalProperties: false, properties: {
|
|
190
179
|
kind: { type: 'string', required: true }, threadRef: { type: 'string', required: true }, taskRef: { type: 'string' },
|
|
191
180
|
revision: { type: 'number', required: true }, status: { type: 'string' }, resolution: { type: 'string' }, taskNumber: { type: 'number' },
|
|
192
|
-
following: { type: 'boolean', required: true }, readThroughSequence: { type: 'number' }, remainingUnreadCount: { type: 'number' }, cursor: { type: 'number' }, hasMore: { type: 'boolean' },
|
|
181
|
+
following: { type: 'boolean', required: true }, readThroughSequence: { type: 'number' }, remainingUnreadCount: { type: 'number' }, earlierFactCount: { type: 'number' }, cursor: { type: 'number' }, hasMore: { type: 'boolean' },
|
|
193
182
|
anchor: { type: 'object', required: true, additionalProperties: false, properties: {
|
|
194
183
|
messageRef: { type: 'string', required: true }, sender: { type: 'string', required: true }, body: { type: 'string', required: true }, sequence: { type: 'number', required: true }, occurredAt: { type: 'string' },
|
|
195
184
|
} },
|
|
@@ -243,8 +232,12 @@ const teamThread = defineTool({
|
|
|
243
232
|
const facts = value.facts;
|
|
244
233
|
const acknowledged = facts.filter(fact => fact.unread === true).length;
|
|
245
234
|
const remaining = value.remainingUnreadCount ?? 0;
|
|
235
|
+
// A read with nothing unread writes no durable operation, so the opening
|
|
236
|
+
// line claims a commit only when unread facts were actually acknowledged.
|
|
246
237
|
const lines = [
|
|
247
|
-
|
|
238
|
+
acknowledged === 0
|
|
239
|
+
? `Read — no unread updates on ${value.threadRef}; nothing remains.`
|
|
240
|
+
: `Read committed — acknowledged ${acknowledged} unread update(s) on ${value.threadRef}; ${remaining} remain.`,
|
|
248
241
|
`${value.threadRef}${standing === '' ? '' : ` · ${standing}`} · ${value.following ? 'following' : 'not following'}`,
|
|
249
242
|
];
|
|
250
243
|
// Orientation: A the anchor is one of the returned facts (renders as
|
|
@@ -270,6 +263,13 @@ const teamThread = defineTool({
|
|
|
270
263
|
else
|
|
271
264
|
lines.push(...facts.map(fact => factLine(fact)));
|
|
272
265
|
lines.push('', `Read through sequence ${value.readThroughSequence}; ${remaining} unread update(s) remaining${remaining > 0 ? ' — call team_thread read again.' : '.'}`);
|
|
266
|
+
// What this bounded read answered with is the newest batch; the span
|
|
267
|
+
// before the watermark is the orientation it did not supply. Rendering
|
|
268
|
+
// the count is what lets a returning reader see the size of that span
|
|
269
|
+
// instead of assuming the batch is the Thread.
|
|
270
|
+
const earlier = value.earlierFactCount ?? 0;
|
|
271
|
+
if (earlier > 0)
|
|
272
|
+
lines.push(`Earlier facts: ${earlier} — read older ones with team_thread.history.`);
|
|
273
273
|
if (value.contextAdvice !== undefined)
|
|
274
274
|
lines.push('', ...adviceLines(value.contextAdvice));
|
|
275
275
|
if (remaining === 0)
|
|
@@ -318,7 +318,7 @@ const teamThread = defineTool({
|
|
|
318
318
|
const read = await host.readThreadForAgent(agent, { requestId: requestId(agent.id, exec.callId), ...base });
|
|
319
319
|
return threadResult('read', read, read.attention, read.facts.map(entry => entry.fact.kind === 'message'
|
|
320
320
|
? { sequence: entry.fact.sequence, kind: 'message', body: entry.fact.message.body, sender: entry.fact.message.sender, mentions: [...entry.fact.mentions], unread: entry.unread, direct: entry.direct, occurredAt: entry.fact.occurredAt }
|
|
321
|
-
: activityFactView(entry.fact.sequence, entry.fact.activity, { unread: entry.unread, direct: entry.direct }, entry.fact.occurredAt)), { readThroughSequence: read.readThroughSequence, remainingUnreadCount: read.remainingUnreadCount, ...(read.contextAdvice === undefined ? {} : { contextAdvice: adviceView(read.contextAdvice) }), ...taskNumberOf(read.task) });
|
|
321
|
+
: activityFactView(entry.fact.sequence, entry.fact.activity, { unread: entry.unread, direct: entry.direct }, entry.fact.occurredAt)), { readThroughSequence: read.readThroughSequence, remainingUnreadCount: read.remainingUnreadCount, ...(read.earlierFactCount === undefined ? {} : { earlierFactCount: read.earlierFactCount }), ...(read.contextAdvice === undefined ? {} : { contextAdvice: adviceView(read.contextAdvice) }), ...taskNumberOf(read.task) });
|
|
322
322
|
},
|
|
323
323
|
});
|
|
324
324
|
/** One rendered fact line; markers are inline, never a separate ellipsis line. */
|
|
@@ -355,7 +355,7 @@ function adviceLines(advice) {
|
|
|
355
355
|
}
|
|
356
356
|
const teamMessage = markAgentTeamPreset(defineTool({
|
|
357
357
|
name: 'team_message',
|
|
358
|
-
description: 'Start a top-level Thread, reply to an existing Thread, or send a direct message (DM). Read the Thread first: a reply needs the current next-write token from a fully drained team_thread read (or your own last committed mutation), and unread work rejects before staleness is even checked. start defaults to a taskless Thread; pass asTask true to create a Task in the same send. A top-level start may mention related Agents directly; in replies, only a Human can invite
|
|
358
|
+
description: 'Start a top-level Thread, reply to an existing Thread, or send a direct message (DM). Read the Thread first: a reply needs the current next-write token from a fully drained team_thread read (or your own last committed mutation), and unread work rejects before staleness is even checked — and a mention only delivers its Message and restores Attention, never the Thread\'s earlier facts, so entering a Thread whose facts have left your context means reading back through it first. start defaults to a taskless Thread; pass asTask true to create a Task in the same send. A top-level start may mention related Agents directly; in replies, only a Human can invite a Member the Thread has never carried. Mention by writing `@Handle` in body — the `@` is required, matching ignores case, and each named Member is delivered to and renders as a mention chip; `@all` reaches every Member of the Channel. Naming a Member this Thread has never carried still commits, delivers nothing to that Member, and reports them under undeliveredMentions: ask the Human to invite them, or reach them with a dm. dm sends a private direct message to one enabled Agent Member in your Workspace: use it for quick clarifications and status syncs — never for task work, decisions, or anything that needs team visibility or traceability (use a Thread); if a DM exchange with the same Member exceeds about 3 exchanges, move it to a Thread, because every DM costs the recipient a full agent turn.',
|
|
359
359
|
parameters: {
|
|
360
360
|
action: { type: 'string', required: true, enum: ['start', 'reply', 'dm'] },
|
|
361
361
|
channelRef: { type: 'string', description: "Full branded Channel ref exactly as returned by Team tools, including the 'channel:' prefix. An unambiguous abbreviation of the first 6+ UUID hex characters also resolves." },
|
|
@@ -363,8 +363,7 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
363
363
|
taskRef: { type: 'string', description: "Optional Task ref alias for reply on a Taskful Thread. Prefer threadRef; an unambiguous abbreviation of the first 6+ UUID hex characters also resolves." },
|
|
364
364
|
memberRef: { type: 'string', description: "Full branded Member ref exactly as returned by Team tools, including the 'member:' prefix. An unambiguous abbreviation of the first 6+ UUID hex characters also resolves. Required for dm; the Member must be an enabled Agent in your Workspace (the Human cannot be DMed)." },
|
|
365
365
|
asTask: { type: 'boolean', description: 'When true, start creates a Task with the Thread. Default false creates a taskless Thread.' },
|
|
366
|
-
body: { type: 'string', required: true, description: "Markdown body. Cite Team refs exactly as returned, as bare text with one colon (e.g. task:0f0a…) — never a double colon, never inside backticks or quotes. Unambiguous UUID abbreviations (first 6+ hex chars) also resolve.
|
|
367
|
-
mentions: { type: 'array', items: { type: 'string' }, description: 'Member refs to mention. Mentioned Agents receive the Message directly; write their handles in the body (any casing, optional @) so the mention renders inline.' },
|
|
366
|
+
body: { type: 'string', required: true, description: "Markdown body. Lead with the conclusion or state. Mention the Human only when they must know or decide; when a decision is owed, say plainly what needs deciding and what happens by default if nobody answers — no fixed template. Keep it the shortest useful message for the recipients; mechanical detail follows below. Cite Team refs exactly as returned, as bare text with one colon (e.g. task:0f0a…) — never a double colon, never inside backticks or quotes. Unambiguous UUID abbreviations (first 6+ hex chars) also resolve. Mention a Member by writing `@Handle` (`@` required, case-insensitive) in the prose: that is what delivers the Message to them and renders the mention chip, and `@all` reaches the whole Channel." }, baseRevision: { type: 'number', description: "The next-write token from your latest fully drained team_thread read (or your own last committed mutation) on this Thread. Copy the explicitly rendered value verbatim; never increment, derive, compare, or cite it — it is an opaque concurrency token, not a fact about the Thread." },
|
|
368
367
|
attachments: { type: 'array', items: { type: 'string' }, description: 'Absolute file paths to share, e.g. screenshots or generated artifacts; images render as thumbnails for recipients. The Host validates each path and copies the file into the attachment cache, and members also receive one cached path per attachment; if any path fails validation the whole send is rejected.' },
|
|
369
368
|
},
|
|
370
369
|
output: {
|
|
@@ -372,6 +371,7 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
372
371
|
kind: { type: 'string', required: true }, action: { type: 'string' }, taskRef: { type: 'string' }, threadRef: { type: 'string' }, revision: { type: 'number' },
|
|
373
372
|
expectedRevision: { type: 'number' }, messageRef: { type: 'string' }, memberIds: { type: 'array', items: { type: 'string' } }, unreadCount: { type: 'number' }, directCount: { type: 'number' },
|
|
374
373
|
recipientMemberId: { type: 'string' }, recipientHandle: { type: 'string' }, delivered: { type: 'boolean' }, deliveryNote: { type: 'string' }, occurredAt: { type: 'string' },
|
|
374
|
+
undeliveredMentions: { type: 'array', items: { type: 'string' } },
|
|
375
375
|
} },
|
|
376
376
|
render: (_args, value) => {
|
|
377
377
|
if (value.kind === 'dm-sent') {
|
|
@@ -388,6 +388,9 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
388
388
|
value.action === 'start' ? 'Committed — Thread created.' : 'Committed — reply added.',
|
|
389
389
|
[value.messageRef, value.threadRef, ...(value.taskRef === undefined ? [] : [value.taskRef])].join(' · '),
|
|
390
390
|
...(value.occurredAt === undefined ? [] : [`Committed at ${formatTeamTimestamp(value.occurredAt)}`]),
|
|
391
|
+
...(value.undeliveredMentions === undefined || value.undeliveredMentions.length === 0 ? [] : [
|
|
392
|
+
`Mention not delivered — ${value.undeliveredMentions.join(', ')} never took part in this Thread, so nothing reached them. Only a Human can invite a Member: reach them with a dm, or ask the Human.`,
|
|
393
|
+
]),
|
|
391
394
|
nextWriteLine(value.revision),
|
|
392
395
|
].join('\n') }];
|
|
393
396
|
}
|
|
@@ -407,7 +410,6 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
407
410
|
throw new Error('team_message requires an Agent session');
|
|
408
411
|
const current = member(agent);
|
|
409
412
|
const host = service(agent);
|
|
410
|
-
const mentions = args.mentions;
|
|
411
413
|
const rawPaths = args.attachments;
|
|
412
414
|
const attachmentPaths = Array.isArray(rawPaths) ? rawPaths.filter((entry) => typeof entry === 'string' && entry.trim() !== '') : undefined;
|
|
413
415
|
const paths = attachmentPaths !== undefined && attachmentPaths.length > 0 ? { attachmentPaths } : {};
|
|
@@ -415,13 +417,13 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
415
417
|
if (args.channelRef === undefined || args.taskRef !== undefined || args.threadRef !== undefined || args.baseRevision !== undefined)
|
|
416
418
|
throw new Error('start requires channelRef and does not accept threadRef, taskRef, or baseRevision');
|
|
417
419
|
const result = await host.sendMessageForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
418
|
-
channelRef: args.channelRef, body: args.body, asTask: args.asTask === true, ...
|
|
420
|
+
channelRef: args.channelRef, body: args.body, asTask: args.asTask === true, ...paths });
|
|
419
421
|
return messageOutcome(result, 'start');
|
|
420
422
|
}
|
|
421
423
|
if (args.action === 'dm') {
|
|
422
424
|
if (args.memberRef === undefined || args.channelRef !== undefined || args.threadRef !== undefined || args.taskRef !== undefined
|
|
423
|
-
|| args.baseRevision !== undefined || args.asTask !== undefined ||
|
|
424
|
-
throw new Error('dm requires memberRef and body only; it does not accept channelRef, threadRef, taskRef, baseRevision, asTask,
|
|
425
|
+
|| args.baseRevision !== undefined || args.asTask !== undefined || attachmentPaths !== undefined) {
|
|
426
|
+
throw new Error('dm requires memberRef and body only; it does not accept channelRef, threadRef, taskRef, baseRevision, asTask, or attachments');
|
|
425
427
|
}
|
|
426
428
|
try {
|
|
427
429
|
const result = await host.dmForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
@@ -442,16 +444,20 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
442
444
|
const result = await host.replyForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
443
445
|
...(args.threadRef === undefined ? {} : { threadRef: args.threadRef }),
|
|
444
446
|
...(args.taskRef === undefined ? {} : { taskRef: args.taskRef }),
|
|
445
|
-
body: args.body, baseRevision,
|
|
446
|
-
...(mentions === undefined ? {} : { recipients: mentions }), ...paths });
|
|
447
|
+
body: args.body, baseRevision, ...paths });
|
|
447
448
|
return messageOutcome(result, 'reply');
|
|
448
449
|
},
|
|
449
450
|
}));
|
|
450
451
|
function messageOutcome(result, action) {
|
|
451
|
-
if (result.kind === 'committed')
|
|
452
|
+
if (result.kind === 'committed') {
|
|
453
|
+
// A start always delivers to the Members it names — they begin following the
|
|
454
|
+
// new Thread — so only a reply can report names the Thread has never carried.
|
|
455
|
+
const undelivered = 'undeliveredMentions' in result ? result.undeliveredMentions : undefined;
|
|
452
456
|
return { kind: result.kind, action, threadRef: result.thread.threadRef,
|
|
453
457
|
...(result.task === undefined ? {} : { taskRef: result.task.taskRef }),
|
|
454
|
-
revision: result.thread.revision, messageRef: result.message.messageRef, occurredAt: result.receipt.occurredAt
|
|
458
|
+
revision: result.thread.revision, messageRef: result.message.messageRef, occurredAt: result.receipt.occurredAt,
|
|
459
|
+
...(undelivered === undefined || undelivered.length === 0 ? {} : { undeliveredMentions: [...undelivered] }) };
|
|
460
|
+
}
|
|
455
461
|
if (result.kind === 'member_not_following')
|
|
456
462
|
return { kind: result.kind, memberIds: [...result.memberIds],
|
|
457
463
|
...(result.taskRef === undefined ? {} : { taskRef: result.taskRef }), ...(result.threadRef === undefined ? {} : { threadRef: result.threadRef, revision: result.revision }) };
|
|
@@ -563,7 +569,7 @@ const teamView = defineTool({
|
|
|
563
569
|
threadRef: { type: 'string', required: true }, channelRef: { type: 'string', required: true }, revision: { type: 'number', required: true }, messageCount: { type: 'number', required: true }, subject: { type: 'string', required: true },
|
|
564
570
|
taskRef: { type: 'string' }, status: { type: 'string' }, taskNumber: { type: 'number' }, lastActivityAt: { type: 'string' },
|
|
565
571
|
} } },
|
|
566
|
-
tasks: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: { taskRef: { type: 'string', required: true }, threadRef: { type: 'string', required: true }, channelRef: { type: 'string', required: true }, status: { type: 'string', required: true }, revision: { type: 'number'
|
|
572
|
+
tasks: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: { taskRef: { type: 'string', required: true }, threadRef: { type: 'string', required: true }, channelRef: { type: 'string', required: true }, status: { type: 'string', required: true }, revision: { type: 'number' } } } },
|
|
567
573
|
cursor: { type: 'number', required: true }, hasMore: { type: 'boolean', required: true }, page: { type: 'string' },
|
|
568
574
|
} },
|
|
569
575
|
// Address book, newest Thread first: labelled sections, one bounded
|
|
@@ -611,7 +617,7 @@ const teamView = defineTool({
|
|
|
611
617
|
return {
|
|
612
618
|
channels: view.channels.map(channel => ({ channelRef: channel.channelRef, name: channel.name })),
|
|
613
619
|
members: [
|
|
614
|
-
{ memberId: view.humanMemberId, kind: 'human', handle:
|
|
620
|
+
{ memberId: view.humanMemberId, kind: 'human', handle: AGENT_TEAM_HUMAN_HANDLE, description: 'Human Team Member', presence: 'available' },
|
|
615
621
|
...host.members().filter(status => visibleMemberIds.has(status.member.memberId)).map(status => ({ memberId: status.member.memberId,
|
|
616
622
|
kind: 'agent', handle: status.member.handle, description: status.member.description, presence: status.presence })),
|
|
617
623
|
],
|
|
@@ -622,8 +628,14 @@ const teamView = defineTool({
|
|
|
622
628
|
subject: boundedSubject(item.message.body), lastActivityAt: item.lastActivityAt,
|
|
623
629
|
...(task === undefined ? {} : { taskRef: task.taskRef, status: task.status, ...(item.taskNumber === undefined ? {} : { taskNumber: item.taskNumber }) }) };
|
|
624
630
|
}),
|
|
625
|
-
|
|
626
|
-
|
|
631
|
+
// A Task's revision is its Thread's; it is omitted rather than reported as
|
|
632
|
+
// `0` when the Task's Thread is outside this directory page's scope. A
|
|
633
|
+
// fabricated revision would read as "this Thread has never been written".
|
|
634
|
+
tasks: view.tasks.map(task => {
|
|
635
|
+
const revision = view.threads.find(thread => thread.threadRef === task.threadRef)?.revision;
|
|
636
|
+
return { taskRef: task.taskRef, threadRef: task.threadRef, channelRef: task.channelRef, status: task.status,
|
|
637
|
+
...(revision === undefined ? {} : { revision }) };
|
|
638
|
+
}),
|
|
627
639
|
cursor: view.cursor, hasMore: view.hasMore,
|
|
628
640
|
...(args.cursor === undefined ? {} : { page: 'threads' }),
|
|
629
641
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../src/context-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../src/context-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAuKH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,GAAG,IAAI,CAIrG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Host accessors for every Team tool module. `agent.ctx.get` is the
|
|
3
|
+
* one resolution path a tool row has — the preset mounts these tools beside
|
|
4
|
+
* the Host, so a missing service or an inactive Member is a model-visible
|
|
5
|
+
* rejection rather than a silent no-op. Both messages are user-facing text.
|
|
6
|
+
*/
|
|
7
|
+
import AgentTeam from '@wowyuarm/dsh-agent-team/host';
|
|
8
|
+
/** The Agent shape every Team tool receives. */
|
|
9
|
+
export type TeamToolAgent = NonNullable<Parameters<AgentTeam['memberForAgent']>[0]>;
|
|
10
|
+
/** Resolve the Team Host service, or reject the tool call. */
|
|
11
|
+
export declare function service(agent: TeamToolAgent): AgentTeam;
|
|
12
|
+
/** Resolve the calling Team Member, or reject the tool call. */
|
|
13
|
+
export declare function member(agent: TeamToolAgent): import("@wowyuarm/dsh-agent-team/types").AgentTeamAgentMember;
|
|
14
|
+
//# sourceMappingURL=host-access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-access.d.ts","sourceRoot":"","sources":["../../src/host-access.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAAS,MAAM,+BAA+B,CAAA;AAErD,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnF,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAIvD;AAED,gEAAgE;AAChE,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,iEAI1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAelD,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAC/C,eAAO,MAAM,MAAM,UAAY,CAAA;AAoqB/B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAOxC"}
|