@wowyuarm/dsh-agent-team 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/README.zh.md +9 -1
- package/package.json +12 -3
- package/packages/agent-team/README.md +3 -3
- package/packages/agent-team/README.zh.md +3 -3
- package/packages/agent-team/lib/attachments.js +11 -12
- package/packages/agent-team/lib/auto-compaction.js +163 -0
- package/packages/agent-team/lib/index.js +252 -139
- package/packages/agent-team/lib/ledger.js +344 -170
- package/packages/agent-team/lib/recovery.js +30 -35
- package/packages/agent-team/lib/spec.js +27 -11
- package/packages/agent-team/lib/typert.host.js +197 -88
- package/packages/agent-team/lib/typert.remote-client.d.ts +3 -1
- package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
- package/packages/agent-team/lib/typert.remote-client.js +139 -59
- package/packages/agent-team/lib/types/attachments.d.ts +2 -2
- package/packages/agent-team/lib/types/attachments.d.ts.map +1 -1
- package/packages/agent-team/lib/types/auto-compaction.d.ts +38 -0
- package/packages/agent-team/lib/types/auto-compaction.d.ts.map +1 -0
- package/packages/agent-team/lib/types/index.d.ts +52 -19
- package/packages/agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/agent-team/lib/types/ledger.d.ts +29 -2
- package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
- package/packages/agent-team/lib/types/recovery.d.ts +15 -16
- package/packages/agent-team/lib/types/recovery.d.ts.map +1 -1
- package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
- package/packages/agent-team/lib/types/types.d.ts +69 -30
- package/packages/agent-team/lib/types/types.d.ts.map +1 -1
- package/packages/agent-team/preset/team-member/agent.cordis.yml +7 -2
- package/packages/client-agent-team/README.md +2 -1
- package/packages/client-agent-team/README.zh.md +2 -1
- package/packages/client-agent-team/lib/client.js +1577 -863
- 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 +35 -174
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +20 -30
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +3 -2
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +6 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamComposer.js +4 -5
- 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 +3 -3
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts +34 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberEditor.js +169 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts +17 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +120 -0
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +4 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamMessage.js +94 -47
- package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -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 +81 -39
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +2 -1
- package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/index.js +72 -1
- package/packages/client-agent-team/lib/types/client/locales.d.ts +24 -0
- package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/locales.js +24 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts +22 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/member-session-input.js +98 -0
- package/packages/client-agent-team/lib/types/client/navigation.d.ts +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/navigation.js +12 -6
- package/packages/client-agent-team/lib/types/client/requests.d.ts +16 -0
- package/packages/client-agent-team/lib/types/client/requests.d.ts.map +1 -0
- package/packages/client-agent-team/lib/types/client/requests.js +22 -0
- package/packages/client-agent-team/lib/types/client/slots.d.ts +2 -1
- package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts +6 -1
- package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/task-refs.js +19 -0
- package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +52 -3
- 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 +74 -4
- package/packages/client-agent-team/lib/types/client/team-membership.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/team-membership.js +2 -1
- package/packages/tool-agent-team/README.md +7 -7
- package/packages/tool-agent-team/README.zh.md +7 -7
- package/packages/tool-agent-team/lib/index.js +38 -28
- package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts +0 -13
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.d.ts.map +0 -1
- package/packages/client-agent-team/lib/types/client/TeamInboxPanel.js +0 -90
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
|
|
7
7
|
## 工具
|
|
8
8
|
|
|
9
|
-
- `team_inbox` 列出调用方 Member 的有界未读 Thread 摘要,先按 direct work
|
|
10
|
-
- `team_thread` 读取 Thread、分页历史、follow 或 unfollow。`read` 原子返回
|
|
11
|
-
- `team_message` 创建顶层
|
|
12
|
-
- `team_claim` 通过 `list`、`claim`、`done`、`release` 读取或修改调用方 Member 的 Direction Claim。Direction 互斥键执行 Unicode NFKC normalization、trim、空白压缩和确定性大小写折叠。
|
|
13
|
-
- `team_view` 发现有界、按 membership 授权的 Channel
|
|
9
|
+
- `team_inbox` 列出调用方 Member 的有界未读 Thread 摘要,先按 direct work、再按最近活动排序;只有 Thread 存在真实 Task overlay 时才出现 Task status/number。
|
|
10
|
+
- `team_thread` 读取 Thread、分页历史、follow 或 unfollow。`threadRef` 是主身份;`taskRef` 只对 released task-only Client 是 Host alias。`read` 原子返回 Thread anchor、可选的当前 Task 与 Claim 快照、有界背景和一批连续未读事实,并推进持久 watermark;`history` 不改变 read 状态。
|
|
11
|
+
- `team_message` 创建顶层 Thread,或回复已有 Thread。它默认创建 taskless Thread;传入 `asTask: true` 才原子创建 Task。Reply 必须携带准确的 `baseRevision`,并在检查 revision 前先处理未读门禁。
|
|
12
|
+
- `team_claim` 通过 `list`、`claim`、`done`、`release` 读取或修改调用方 Member 的 Direction Claim;它只适用于真实 Task。Direction 互斥键执行 Unicode NFKC normalization、trim、空白压缩和确定性大小写折叠。
|
|
13
|
+
- `team_view` 发现有界、按 membership 授权的 Channel、真实 Task 和 Member 摘要,不返回 Thread Message 或 Activity。
|
|
14
14
|
|
|
15
|
-
Agent 不能通过 mention 静默把另一个 unfollowed Agent 加入 Thread;Host 返回 `member_not_following`。Human confirmation 属于单独的 Host/Client 流程。Closed Task 在 Human reopen 前拒绝 reply、Claim 和新的 Attention。
|
|
15
|
+
Agent 不能通过 mention 静默把另一个 unfollowed Agent 加入 Thread;Host 返回 `member_not_following`。Human confirmation 属于单独的 Host/Client 流程。Closed Task 在 Human reopen 前拒绝 reply、Claim 和新的 Attention;taskless Thread 没有 Claim 或 Task resolution mutation path。
|
|
16
16
|
|
|
17
|
-
Canonical result 包含稳定 refs
|
|
17
|
+
Canonical result 包含稳定 refs、可选的 Task status、Thread revision、Claim history、Attention 和未读 facts。类型化的 `unread_required` 与 `stale_revision` 结果包含重新读取和审慎重试所需字段。工具执行通过准确的 live `exec.agent` 解析 actor;参数不能选择或冒充 actor 或 Workspace。写操作的 request identity 由 sessionId 与 tool callId 派生。Team tools 将结果返回模型循环,不主动结束 turn。
|
|
18
18
|
|
|
19
19
|
完整的已实现协议见 [`../../docs/team-collaboration.md`](../../docs/team-collaboration.md)。
|
|
20
20
|
|
|
@@ -25,13 +25,13 @@ const teamInbox = defineTool({
|
|
|
25
25
|
schema: { type: 'object', additionalProperties: false, properties: {
|
|
26
26
|
totalUnreadCount: { type: 'number', required: true }, totalDirectCount: { type: 'number', required: true },
|
|
27
27
|
items: { type: 'array', required: true, items: { type: 'object', additionalProperties: false, properties: {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
threadRef: { type: 'string', required: true }, channelRef: { type: 'string', required: true },
|
|
29
|
+
taskRef: { type: 'string' }, status: { type: 'string' }, revision: { type: 'number', required: true }, unreadCount: { type: 'number', required: true }, directCount: { type: 'number', required: true },
|
|
30
30
|
taskNumber: { type: 'number' },
|
|
31
31
|
} } },
|
|
32
32
|
} },
|
|
33
33
|
render: (_args, value) => [{ type: 'text', text: value.items.length === 0 ? 'No unread Team work.'
|
|
34
|
-
: value.items.map(item => `${item.taskRef}${item.taskNumber === undefined ? '' : ` (#${item.taskNumber})`} · ${item.directCount > 0 ? 'direct' : 'unread'}, ${item.unreadCount} update(s), revision ${item.revision}`).join('\n') }],
|
|
34
|
+
: value.items.map(item => `${item.threadRef}${item.taskRef === undefined ? '' : ` · ${item.taskRef}`}${item.taskNumber === undefined ? '' : ` (#${item.taskNumber})`} · ${item.directCount > 0 ? 'direct' : 'unread'}, ${item.unreadCount} update(s), revision ${item.revision}`).join('\n') }],
|
|
35
35
|
},
|
|
36
36
|
async execute(args, exec) {
|
|
37
37
|
const agent = exec.agent;
|
|
@@ -45,9 +45,10 @@ const teamInbox = defineTool({
|
|
|
45
45
|
return {
|
|
46
46
|
totalUnreadCount: inbox.totalUnreadCount, totalDirectCount: inbox.totalDirectCount,
|
|
47
47
|
items: inbox.items.map(item => {
|
|
48
|
-
const taskNumber = taskNumbers.get(item.task.taskRef);
|
|
49
|
-
return {
|
|
50
|
-
|
|
48
|
+
const taskNumber = item.task === undefined ? undefined : taskNumbers.get(item.task.taskRef);
|
|
49
|
+
return { threadRef: item.thread.threadRef, channelRef: item.channelRef,
|
|
50
|
+
...(item.task === undefined ? {} : { taskRef: item.task.taskRef, status: item.task.status }),
|
|
51
|
+
revision: item.thread.revision, unreadCount: item.unreadCount, directCount: item.directCount,
|
|
51
52
|
...(taskNumber === undefined ? {} : { taskNumber }) };
|
|
52
53
|
}),
|
|
53
54
|
};
|
|
@@ -55,16 +56,17 @@ const teamInbox = defineTool({
|
|
|
55
56
|
});
|
|
56
57
|
const teamThread = defineTool({
|
|
57
58
|
name: 'team_thread',
|
|
58
|
-
description: 'Read or manage your Attention on one
|
|
59
|
+
description: 'Read or manage your Attention on one Thread. read acknowledges one chronological batch; history does not change read state. Prefer threadRef; taskRef is a compatibility alias when the Thread has a Task.',
|
|
59
60
|
parameters: {
|
|
60
61
|
action: { type: 'string', required: true, enum: ['status', 'follow', 'unfollow', 'read', 'history'] },
|
|
61
|
-
|
|
62
|
+
threadRef: { type: 'string', description: "Full branded Thread ref exactly as returned by Team tools, including the 'thread:' prefix." },
|
|
63
|
+
taskRef: { type: 'string', description: "Optional Task ref alias for released clients. Prefer threadRef; if both are given they must identify the same Thread." },
|
|
62
64
|
beforeSequence: { type: 'number' }, limit: { type: 'number' },
|
|
63
65
|
},
|
|
64
66
|
output: {
|
|
65
67
|
schema: { type: 'object', additionalProperties: false, properties: {
|
|
66
|
-
kind: { type: 'string', required: true },
|
|
67
|
-
revision: { type: 'number', required: true }, status: { type: 'string'
|
|
68
|
+
kind: { type: 'string', required: true }, threadRef: { type: 'string', required: true }, taskRef: { type: 'string' },
|
|
69
|
+
revision: { type: 'number', required: true }, status: { type: 'string' }, resolution: { type: 'string' },
|
|
68
70
|
following: { type: 'boolean', required: true }, readThroughSequence: { type: 'number' }, remainingUnreadCount: { type: 'number' }, cursor: { type: 'number' }, hasMore: { type: 'boolean' },
|
|
69
71
|
anchor: { type: 'object', required: true, additionalProperties: false, properties: {
|
|
70
72
|
messageRef: { type: 'string', required: true }, sender: { type: 'string', required: true }, body: { type: 'string', required: true }, sequence: { type: 'number', required: true },
|
|
@@ -88,7 +90,9 @@ const teamThread = defineTool({
|
|
|
88
90
|
throw new Error('team_thread requires an Agent session');
|
|
89
91
|
const current = member(agent);
|
|
90
92
|
const host = service(agent);
|
|
91
|
-
|
|
93
|
+
if (args.threadRef === undefined && args.taskRef === undefined)
|
|
94
|
+
throw new Error('team_thread requires threadRef');
|
|
95
|
+
const base = { workspaceId: current.workspaceId, ...(args.threadRef === undefined ? {} : { threadRef: args.threadRef }), ...(args.taskRef === undefined ? {} : { taskRef: args.taskRef }) };
|
|
92
96
|
if (args.action === 'status') {
|
|
93
97
|
if (args.beforeSequence !== undefined || args.limit !== undefined)
|
|
94
98
|
throw new Error('status does not accept history arguments');
|
|
@@ -120,8 +124,9 @@ const teamThread = defineTool({
|
|
|
120
124
|
});
|
|
121
125
|
function threadResult(kind, snapshot, attention, facts, extra = {}) {
|
|
122
126
|
return {
|
|
123
|
-
kind,
|
|
124
|
-
status: snapshot.task.status, resolution: snapshot.task.resolution
|
|
127
|
+
kind, threadRef: snapshot.thread.threadRef, revision: snapshot.thread.revision,
|
|
128
|
+
...(snapshot.task === undefined ? {} : { taskRef: snapshot.task.taskRef, status: snapshot.task.status, resolution: snapshot.task.resolution }),
|
|
129
|
+
following: attention !== undefined,
|
|
125
130
|
...extra,
|
|
126
131
|
...(attention === undefined || extra.readThroughSequence !== undefined ? {} : { readThroughSequence: attention.readThroughSequence }),
|
|
127
132
|
anchor: { messageRef: snapshot.anchor.messageRef, sender: snapshot.anchor.sender, body: snapshot.anchor.body, sequence: snapshot.anchor.sequence },
|
|
@@ -131,12 +136,14 @@ function threadResult(kind, snapshot, attention, facts, extra = {}) {
|
|
|
131
136
|
}
|
|
132
137
|
const teamMessage = markAgentTeamPreset(defineTool({
|
|
133
138
|
name: 'team_message',
|
|
134
|
-
description: '
|
|
139
|
+
description: 'Start a top-level Thread or reply to an existing Thread. start defaults to a taskless Thread; pass asTask true to create a Task in the same send. Read the Thread first; replies require its current revision (an internal concurrency token carried by baseRevision, never quoted in bodies). A top-level start may mention related Agents directly; in replies, only a Human can invite an unfollowed Agent. Pass Member refs in mentions and spell their handles inside the body; only mentioned Members render as mention chips.',
|
|
135
140
|
parameters: {
|
|
136
141
|
action: { type: 'string', required: true, enum: ['start', 'reply'] },
|
|
137
142
|
channelRef: { type: 'string', description: "Full branded Channel ref exactly as returned by Team tools, including the 'channel:' prefix." },
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
threadRef: { type: 'string', description: "Full branded Thread ref exactly as returned by Team tools, including the 'thread:' prefix." },
|
|
144
|
+
taskRef: { type: 'string', description: "Optional Task ref alias for reply on a Taskful Thread. Prefer threadRef." },
|
|
145
|
+
asTask: { type: 'boolean', description: 'When true, start creates a Task with the Thread. Default false creates a taskless Thread.' },
|
|
146
|
+
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. Spell each mentioned Member's handle in the prose so the mention renders inline." }, baseRevision: { type: 'number', description: "Positive integer; use the current Thread revision as shown by the latest team_inbox or team_thread result for this Thread. The revision is an internal concurrency token, not a citable fact." },
|
|
140
147
|
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.' },
|
|
141
148
|
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.' },
|
|
142
149
|
},
|
|
@@ -146,7 +153,7 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
146
153
|
expectedRevision: { type: 'number' }, messageRef: { type: 'string' }, memberIds: { type: 'array', items: { type: 'string' } }, unreadCount: { type: 'number' }, directCount: { type: 'number' },
|
|
147
154
|
} },
|
|
148
155
|
render: (_args, value) => [{ type: 'text', text: value.kind === 'committed' ? `Message ${value.messageRef} committed at revision ${value.revision}.`
|
|
149
|
-
: `${value.kind}: ${value.memberIds?.join(', ') ??
|
|
156
|
+
: `${value.kind}: ${value.memberIds?.join(', ') ?? `${value.threadRef ?? ''}${value.taskRef === undefined ? '' : ` · Task ${value.taskRef}`} revision ${value.revision ?? ''}`}` }],
|
|
150
157
|
},
|
|
151
158
|
async execute(args, exec) {
|
|
152
159
|
const agent = exec.agent;
|
|
@@ -159,34 +166,37 @@ const teamMessage = markAgentTeamPreset(defineTool({
|
|
|
159
166
|
const attachmentPaths = Array.isArray(rawPaths) ? rawPaths.filter((entry) => typeof entry === 'string' && entry.trim() !== '') : undefined;
|
|
160
167
|
const paths = attachmentPaths !== undefined && attachmentPaths.length > 0 ? { attachmentPaths } : {};
|
|
161
168
|
if (args.action === 'start') {
|
|
162
|
-
if (args.channelRef === undefined || args.taskRef !== undefined || args.baseRevision !== undefined)
|
|
163
|
-
throw new Error('start requires channelRef and does not accept taskRef or baseRevision');
|
|
169
|
+
if (args.channelRef === undefined || args.taskRef !== undefined || args.threadRef !== undefined || args.baseRevision !== undefined)
|
|
170
|
+
throw new Error('start requires channelRef and does not accept threadRef, taskRef, or baseRevision');
|
|
164
171
|
const result = await host.sendMessageForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
165
|
-
channelRef: args.channelRef, body: args.body, ...(mentions === undefined ? {} : { recipients: mentions }), ...paths });
|
|
172
|
+
channelRef: args.channelRef, body: args.body, asTask: args.asTask === true, ...(mentions === undefined ? {} : { recipients: mentions }), ...paths });
|
|
166
173
|
return messageOutcome(result);
|
|
167
174
|
}
|
|
168
175
|
const baseRevision = args.baseRevision;
|
|
169
|
-
if (args.taskRef === undefined || args.channelRef !== undefined || typeof baseRevision !== 'number' || !Number.isSafeInteger(baseRevision) || baseRevision < 1) {
|
|
170
|
-
throw new Error("reply requires
|
|
176
|
+
if ((args.threadRef === undefined && args.taskRef === undefined) || args.channelRef !== undefined || args.asTask !== undefined || typeof baseRevision !== 'number' || !Number.isSafeInteger(baseRevision) || baseRevision < 1) {
|
|
177
|
+
throw new Error("reply requires threadRef and a positive baseRevision, and does not accept channelRef; use the current Thread 'revision' returned by team_inbox or team_thread");
|
|
171
178
|
}
|
|
172
179
|
const result = await host.replyForAgent(agent, { requestId: requestId(agent.id, exec.callId), workspaceId: current.workspaceId,
|
|
173
|
-
|
|
180
|
+
...(args.threadRef === undefined ? {} : { threadRef: args.threadRef }),
|
|
181
|
+
...(args.taskRef === undefined ? {} : { taskRef: args.taskRef }),
|
|
182
|
+
body: args.body, baseRevision,
|
|
174
183
|
...(mentions === undefined ? {} : { recipients: mentions }), ...paths });
|
|
175
184
|
return messageOutcome(result);
|
|
176
185
|
},
|
|
177
186
|
}));
|
|
178
187
|
function messageOutcome(result) {
|
|
179
188
|
if (result.kind === 'committed')
|
|
180
|
-
return { kind: result.kind,
|
|
189
|
+
return { kind: result.kind, threadRef: result.thread.threadRef,
|
|
190
|
+
...(result.task === undefined ? {} : { taskRef: result.task.taskRef }),
|
|
181
191
|
revision: result.thread.revision, messageRef: result.message.messageRef };
|
|
182
192
|
if (result.kind === 'member_not_following')
|
|
183
193
|
return { kind: result.kind, memberIds: [...result.memberIds],
|
|
184
194
|
...(result.taskRef === undefined ? {} : { taskRef: result.taskRef }), ...(result.threadRef === undefined ? {} : { threadRef: result.threadRef, revision: result.revision }) };
|
|
185
195
|
if (result.kind === 'unread_required')
|
|
186
|
-
return { kind: result.kind, taskRef: result.taskRef, threadRef: result.threadRef,
|
|
196
|
+
return { kind: result.kind, ...(result.taskRef === undefined ? {} : { taskRef: result.taskRef }), threadRef: result.threadRef,
|
|
187
197
|
revision: result.revision, unreadCount: result.unreadCount, directCount: result.directCount };
|
|
188
198
|
if (result.kind === 'stale_revision')
|
|
189
|
-
return { kind: result.kind, taskRef: result.taskRef, threadRef: result.threadRef,
|
|
199
|
+
return { kind: result.kind, ...(result.taskRef === undefined ? {} : { taskRef: result.taskRef }), threadRef: result.threadRef,
|
|
190
200
|
expectedRevision: result.expectedRevision, revision: result.revision };
|
|
191
201
|
throw new Error('Agents cannot receive invitation confirmations');
|
|
192
202
|
}
|
|
@@ -238,9 +248,9 @@ const teamClaim = defineTool({
|
|
|
238
248
|
return { kind: result.kind, taskRef: result.task.taskRef, threadRef: result.thread.threadRef,
|
|
239
249
|
revision: result.thread.revision, status: result.task.status, claims };
|
|
240
250
|
if (result.kind === 'unread_required')
|
|
241
|
-
return { kind: result.kind, taskRef:
|
|
251
|
+
return { kind: result.kind, taskRef: listed.task.taskRef, threadRef: result.threadRef,
|
|
242
252
|
revision: result.revision, status: listed.task.status, unreadCount: result.unreadCount, directCount: result.directCount, claims };
|
|
243
|
-
return { kind: result.kind, taskRef:
|
|
253
|
+
return { kind: result.kind, taskRef: listed.task.taskRef, threadRef: result.threadRef, expectedRevision: result.expectedRevision,
|
|
244
254
|
revision: result.revision, status: listed.task.status, claims };
|
|
245
255
|
},
|
|
246
256
|
});
|
|
@@ -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;AAWlD,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAC/C,eAAO,MAAM,MAAM,UAAY,CAAA;AAqS/B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAMxC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { WorkspaceId } from '@deepseek-ai/dsh-client-runtime/client';
|
|
2
|
-
import type { TeamConversationProps } from './slots.ts';
|
|
3
|
-
interface TeamInboxPanelProps {
|
|
4
|
-
readonly workspaceId: WorkspaceId;
|
|
5
|
-
readonly loadInbox: TeamConversationProps['loadInbox'];
|
|
6
|
-
readonly loadChannels: TeamConversationProps['loadChannels'];
|
|
7
|
-
readonly loadChanges: TeamConversationProps['loadChanges'];
|
|
8
|
-
readonly selectThread: TeamConversationProps['selectThread'];
|
|
9
|
-
readonly t: TeamConversationProps['t'];
|
|
10
|
-
}
|
|
11
|
-
export declare function TeamInboxPanel({ workspaceId, loadInbox, loadChannels, loadChanges, selectThread, t }: TeamInboxPanelProps): import("react").JSX.Element;
|
|
12
|
-
export {};
|
|
13
|
-
//# sourceMappingURL=TeamInboxPanel.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"TeamInboxPanel.d.ts","sourceRoot":"","sources":["../../../src/client/TeamInboxPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAEzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAIvD,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAA;IACtD,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,WAAW,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAA;IAC1D,QAAQ,CAAC,YAAY,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAA;IAC5D,QAAQ,CAAC,CAAC,EAAE,qBAAqB,CAAC,GAAG,CAAC,CAAA;CACvC;AAED,wBAAgB,cAAc,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,mBAAmB,+BAkGzH"}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import { Button } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
|
-
import { formatTaskStatus } from "./team-formatters.js";
|
|
5
|
-
import css from './inbox.module.css';
|
|
6
|
-
export function TeamInboxPanel({ workspaceId, loadInbox, loadChannels, loadChanges, selectThread, t }) {
|
|
7
|
-
const [inbox, setInbox] = useState();
|
|
8
|
-
const [view, setView] = useState();
|
|
9
|
-
const [error, setError] = useState();
|
|
10
|
-
const [loading, setLoading] = useState(true);
|
|
11
|
-
const active = useRef(false);
|
|
12
|
-
const refreshSequence = useRef(0);
|
|
13
|
-
const refresh = async (clearError = false) => {
|
|
14
|
-
const sequence = refreshSequence.current + 1;
|
|
15
|
-
refreshSequence.current = sequence;
|
|
16
|
-
if (clearError)
|
|
17
|
-
setError(undefined);
|
|
18
|
-
try {
|
|
19
|
-
const [nextInbox, nextView] = await Promise.all([
|
|
20
|
-
loadInbox({ workspaceId }),
|
|
21
|
-
loadChannels({ workspaceId, topLevelOnly: true, includeActivities: false, limit: 100 }),
|
|
22
|
-
]);
|
|
23
|
-
if (!active.current || sequence !== refreshSequence.current)
|
|
24
|
-
return;
|
|
25
|
-
if (!nextInbox.ok) {
|
|
26
|
-
setError(nextInbox.error.message);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (!nextView.ok) {
|
|
30
|
-
setError(nextView.error.message);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
setInbox(nextInbox.value);
|
|
34
|
-
setView(nextView.value);
|
|
35
|
-
setError(undefined);
|
|
36
|
-
}
|
|
37
|
-
catch (cause) {
|
|
38
|
-
if (active.current && sequence === refreshSequence.current)
|
|
39
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
40
|
-
}
|
|
41
|
-
finally {
|
|
42
|
-
if (active.current && sequence === refreshSequence.current)
|
|
43
|
-
setLoading(false);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
let listening = true;
|
|
48
|
-
active.current = true;
|
|
49
|
-
setInbox(undefined);
|
|
50
|
-
setView(undefined);
|
|
51
|
-
setError(undefined);
|
|
52
|
-
setLoading(true);
|
|
53
|
-
void refresh();
|
|
54
|
-
void (async () => {
|
|
55
|
-
let version = 0;
|
|
56
|
-
while (listening) {
|
|
57
|
-
try {
|
|
58
|
-
const changed = await loadChanges({ afterVersion: version });
|
|
59
|
-
if (!listening)
|
|
60
|
-
return;
|
|
61
|
-
if (!changed.ok) {
|
|
62
|
-
setError(changed.error.message);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
if (changed.value.version > version) {
|
|
66
|
-
version = changed.value.version;
|
|
67
|
-
await refresh();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
catch (cause) {
|
|
71
|
-
if (listening)
|
|
72
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
})();
|
|
77
|
-
return () => {
|
|
78
|
-
listening = false;
|
|
79
|
-
active.current = false;
|
|
80
|
-
refreshSequence.current += 1;
|
|
81
|
-
};
|
|
82
|
-
}, [workspaceId]);
|
|
83
|
-
const channels = useMemo(() => new Map(view?.channels.map(channel => [channel.channelRef, channel]) ?? []), [view]);
|
|
84
|
-
const taskNumbers = useMemo(() => new Map(view?.taskNumbers.map(item => [item.taskRef, item.taskNumber]) ?? []), [view]);
|
|
85
|
-
return _jsxs("main", { className: css.surface, "data-team-inbox": true, children: [_jsxs("header", { className: css.header, children: [_jsxs("div", { children: [_jsx("h1", { children: t('inbox') }), inbox !== undefined && _jsx("p", { children: inbox.totalUnreadCount === 0 ? t('inboxEmpty') : t('inboxUnreadCount', { count: inbox.totalUnreadCount }) })] }), inbox !== undefined && inbox.totalDirectCount > 0 && _jsx("span", { className: css.directTotal, children: t('inboxDirectCount', { count: inbox.totalDirectCount }) })] }), _jsxs("section", { className: css.list, "aria-label": t('inbox'), children: [loading && inbox === undefined && error === undefined && _jsx("p", { className: css.state, children: t('loadingInbox') }), !loading && inbox?.items.length === 0 && error === undefined && _jsx("p", { className: css.state, children: t('inboxEmpty') }), error !== undefined && _jsxs("div", { className: css.error, role: "alert", children: [_jsx("span", { children: error }), _jsx(Button, { size: "sm", variant: "outline", onClick: () => { void refresh(true); }, children: t('retry') })] }), inbox?.items.map(item => {
|
|
86
|
-
const channel = channels.get(item.channelRef);
|
|
87
|
-
const taskNumber = taskNumbers.get(item.task.taskRef);
|
|
88
|
-
return _jsxs("button", { type: "button", className: css.item, onClick: () => { selectThread(item.task.taskRef, item.thread.threadRef, item.channelRef, taskNumber); }, children: [_jsx("span", { className: css.priority, "data-direct": item.directCount > 0, "aria-hidden": "true" }), _jsxs("span", { className: css.copy, children: [_jsx("strong", { children: taskNumber === undefined ? t('task') : `Task #${taskNumber}` }), _jsxs("small", { children: [channel === undefined ? t('channelUnknown') : `# ${channel.name}`, " \u00B7 ", formatTaskStatus(item.task.status, t)] })] }), _jsxs("span", { className: css.count, "aria-label": `${t('inboxUnreadCount', { count: item.unreadCount })}${item.directCount > 0 ? `, ${t('inboxDirectCount', { count: item.directCount })}` : ''}`, children: [t('inboxUnreadCount', { count: item.unreadCount }), item.directCount > 0 && _jsxs(_Fragment, { children: [" \u00B7 ", t('inboxDirectCount', { count: item.directCount })] })] })] }, item.thread.threadRef);
|
|
89
|
-
})] })] });
|
|
90
|
-
}
|