@wowyuarm/dsh-agent-team 0.1.3 → 0.1.5

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 (79) hide show
  1. package/README.md +7 -1
  2. package/README.zh.md +12 -3
  3. package/package.json +1 -1
  4. package/packages/agent-team/README.md +3 -3
  5. package/packages/agent-team/README.zh.md +3 -3
  6. package/packages/agent-team/lib/auto-compaction.js +39 -1
  7. package/packages/agent-team/lib/index.js +123 -14
  8. package/packages/agent-team/lib/ledger.js +355 -110
  9. package/packages/agent-team/lib/spec.js +39 -11
  10. package/packages/agent-team/lib/typert.host.js +257 -86
  11. package/packages/agent-team/lib/typert.remote-client.d.ts +5 -1
  12. package/packages/agent-team/lib/typert.remote-client.d.ts.map +1 -1
  13. package/packages/agent-team/lib/typert.remote-client.js +196 -59
  14. package/packages/agent-team/lib/types/auto-compaction.d.ts +9 -0
  15. package/packages/agent-team/lib/types/auto-compaction.d.ts.map +1 -1
  16. package/packages/agent-team/lib/types/index.d.ts +24 -7
  17. package/packages/agent-team/lib/types/index.d.ts.map +1 -1
  18. package/packages/agent-team/lib/types/ledger.d.ts +36 -2
  19. package/packages/agent-team/lib/types/ledger.d.ts.map +1 -1
  20. package/packages/agent-team/lib/types/spec.d.ts.map +1 -1
  21. package/packages/agent-team/lib/types/types.d.ts +109 -30
  22. package/packages/agent-team/lib/types/types.d.ts.map +1 -1
  23. package/packages/agent-team/preset/team-member/agent.cordis.yml +1 -1
  24. package/packages/client-agent-team/README.md +2 -1
  25. package/packages/client-agent-team/README.zh.md +2 -1
  26. package/packages/client-agent-team/lib/client.js +1082 -380
  27. package/packages/client-agent-team/lib/client.js.map +1 -1
  28. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts +2 -1
  29. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.d.ts.map +1 -1
  30. package/packages/client-agent-team/lib/types/client/TeamAgentsPanel.js +73 -15
  31. package/packages/client-agent-team/lib/types/client/TeamChannelPage.d.ts.map +1 -1
  32. package/packages/client-agent-team/lib/types/client/TeamChannelPage.js +34 -10
  33. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.d.ts.map +1 -1
  34. package/packages/client-agent-team/lib/types/client/TeamChannelsPanel.js +3 -1
  35. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts +6 -1
  36. package/packages/client-agent-team/lib/types/client/TeamComposer.d.ts.map +1 -1
  37. package/packages/client-agent-team/lib/types/client/TeamComposer.js +76 -20
  38. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts +1 -1
  39. package/packages/client-agent-team/lib/types/client/TeamConversation.d.ts.map +1 -1
  40. package/packages/client-agent-team/lib/types/client/TeamConversation.js +3 -3
  41. package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.d.ts.map +1 -1
  42. package/packages/client-agent-team/lib/types/client/TeamMemberSessionComposer.js +16 -1
  43. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts +4 -1
  44. package/packages/client-agent-team/lib/types/client/TeamMessage.d.ts.map +1 -1
  45. package/packages/client-agent-team/lib/types/client/TeamMessage.js +62 -25
  46. package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts +3 -2
  47. package/packages/client-agent-team/lib/types/client/TeamRowMenu.d.ts.map +1 -1
  48. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.d.ts +5 -2
  49. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.d.ts.map +1 -1
  50. package/packages/client-agent-team/lib/types/client/TeamSidebarSection.js +2 -4
  51. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts +2 -1
  52. package/packages/client-agent-team/lib/types/client/TeamThreadPage.d.ts.map +1 -1
  53. package/packages/client-agent-team/lib/types/client/TeamThreadPage.js +92 -18
  54. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts +1 -1
  55. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.d.ts.map +1 -1
  56. package/packages/client-agent-team/lib/types/client/TeamWorkspaceBrowser.js +5 -2
  57. package/packages/client-agent-team/lib/types/client/index.d.ts.map +1 -1
  58. package/packages/client-agent-team/lib/types/client/index.js +16 -13
  59. package/packages/client-agent-team/lib/types/client/locales.d.ts +40 -0
  60. package/packages/client-agent-team/lib/types/client/locales.d.ts.map +1 -1
  61. package/packages/client-agent-team/lib/types/client/locales.js +40 -0
  62. package/packages/client-agent-team/lib/types/client/navigation.d.ts +1 -1
  63. package/packages/client-agent-team/lib/types/client/navigation.d.ts.map +1 -1
  64. package/packages/client-agent-team/lib/types/client/navigation.js +12 -6
  65. package/packages/client-agent-team/lib/types/client/sidebar-sections.d.ts +16 -0
  66. package/packages/client-agent-team/lib/types/client/sidebar-sections.d.ts.map +1 -0
  67. package/packages/client-agent-team/lib/types/client/sidebar-sections.js +102 -0
  68. package/packages/client-agent-team/lib/types/client/slots.d.ts +3 -1
  69. package/packages/client-agent-team/lib/types/client/slots.d.ts.map +1 -1
  70. package/packages/client-agent-team/lib/types/client/task-refs.d.ts +1 -1
  71. package/packages/client-agent-team/lib/types/client/task-refs.d.ts.map +1 -1
  72. package/packages/client-agent-team/lib/types/client/task-refs.js +1 -1
  73. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts +9 -0
  74. package/packages/client-agent-team/lib/types/client/team-formatters.d.ts.map +1 -1
  75. package/packages/client-agent-team/lib/types/client/team-formatters.js +22 -2
  76. package/packages/tool-agent-team/README.md +7 -7
  77. package/packages/tool-agent-team/README.zh.md +7 -7
  78. package/packages/tool-agent-team/lib/index.js +38 -28
  79. package/packages/tool-agent-team/lib/types/index.d.ts.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"team-formatters.d.ts","sourceRoot":"","sources":["../../../src/client/team-formatters.ts"],"names":[],"mappings":"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"}
@@ -116,7 +116,11 @@ export function splitMentionNames(text, names) {
116
116
  }
117
117
  /** Canonical chip handles for one Message's structured mention refs. */
118
118
  export function mentionNamesOf(mentions, handles) {
119
- return mentions.map(memberId => handles.get(memberId)).filter((name) => name !== undefined);
119
+ return mentions
120
+ // The Human is Team authority, not an Agent projection, so `members()` does
121
+ // not include it. Keep its stable public handle available for rendering.
122
+ .map(memberId => memberId === 'member:human' ? 'human' : handles.get(memberId))
123
+ .filter((name) => name !== undefined);
120
124
  }
121
125
  const MARKDOWN_BLOCK_CONSTRUCT = /(^|\n)[ \t]{0,3}(?:#{1,6}[ \t]|>[ \t]|[-*+][ \t]|\d+[.)][ \t])|^[ \t]*\|.+\|/m;
122
126
  const MARKDOWN_INLINE_CONSTRUCT = /[`*_[\]!]|~~~|```/;
@@ -155,6 +159,8 @@ export function formatActivity(activity, options) {
155
159
  ? options.t('activityAcceptedWithClaims', { actor, count: activity.completedClaimRefs.length })
156
160
  : options.t('activityAccepted', { actor });
157
161
  }
162
+ if (activity.kind === 'promote')
163
+ return options.t('activityPromoted', { actor });
158
164
  if (activity.kind === 'close')
159
165
  return options.t('activityClosed', { actor });
160
166
  if (activity.kind === 'reopen')
@@ -176,6 +182,17 @@ export function formatActivity(activity, options) {
176
182
  export function stripAttachmentLines(body) {
177
183
  return body.replaceAll(/^\[attachment\] .*$(\n)?/gm, '').replace(/\n+$/, '');
178
184
  }
185
+ /**
186
+ * Displayed bodies past this character count render clamped behind an expand
187
+ * control. The rule is deterministic from the body alone, so every surface
188
+ * derives the same default for the same Message and no client has to remember
189
+ * a fold state.
190
+ */
191
+ export const MESSAGE_COLLAPSE_CHARS = 600;
192
+ /** Whether one displayed Message body starts clamped behind the expand control. */
193
+ export function shouldClampMessage(displayBody) {
194
+ return displayBody.length > MESSAGE_COLLAPSE_CHARS;
195
+ }
179
196
  /**
180
197
  * Decide how one Message body renders. Human input and plain-prose Agent
181
198
  * bodies stay literal, with structured mention chips inline where possible;
@@ -205,7 +222,10 @@ export function planMessageBody(body, options) {
205
222
  render,
206
223
  ...(inline === undefined ? {} : { inline }),
207
224
  fallbackNames,
208
- fallbackRefs: richAgentBody && options.canOpenRefs ? refs.filter(ref => !ref.startsWith('task:')) : [],
225
+ // Rich Markdown refs are painted at their authored position after the
226
+ // Markdown primitive has built its DOM; do not duplicate them in the
227
+ // trailing chip row when navigation is available.
228
+ fallbackRefs: richAgentBody && !options.canOpenRefs ? refs : [],
209
229
  taskRefs: options.canOpenRefs && !richAgentBody
210
230
  ? refs.filter(ref => ref.startsWith('task:')).map(ref => ref)
211
231
  : [],
@@ -6,15 +6,15 @@ Model-facing tools for Agent Team Members. The package registers tools in the ca
6
6
 
7
7
  ## Tools
8
8
 
9
- - `team_inbox` lists bounded unread Thread summaries for the calling Member, ordered by direct work and then recency.
10
- - `team_thread` reads a Thread, pages history, follows, or unfollows. `read` atomically returns the Task anchor, current Task and Claim snapshot, bounded orientation facts, and one contiguous unread batch while advancing the durable watermark; `history` never changes read state.
11
- - `team_message` starts a top-level Task or replies to an existing Thread. Replies require the exact `baseRevision` and reject unread work before checking revision freshness.
12
- - `team_claim` lists or mutates the calling Member's Direction Claims through `list`, `claim`, `done`, and `release`. Direction exclusion uses Unicode NFKC normalization, trim, whitespace compression, and deterministic case folding.
13
- - `team_view` discovers bounded, membership-authorized Channel, Task, and Member summaries. It does not return Thread messages or activities.
9
+ - `team_inbox` lists bounded unread Thread summaries for the calling Member, ordered by direct work and then recency; Task status/number appear only where the Thread has a real Task overlay.
10
+ - `team_thread` reads a Thread, pages history, follows, or unfollows. `threadRef` is primary; a `taskRef` is a Host alias only for released task-only Clients. `read` atomically returns the Thread anchor, optional current Task and Claim snapshot, bounded orientation facts, and one contiguous unread batch while advancing the durable watermark; `history` never changes read state.
11
+ - `team_message` starts a top-level Thread or replies to an existing Thread. It defaults to a taskless Thread; pass `asTask: true` for atomic Task creation. Replies require the exact `baseRevision` and reject unread work before checking revision freshness.
12
+ - `team_claim` lists or mutates the calling Member's Direction Claims through `list`, `claim`, `done`, and `release`; it applies only to real Tasks. Direction exclusion uses Unicode NFKC normalization, trim, whitespace compression, and deterministic case folding.
13
+ - `team_view` discovers bounded, membership-authorized Channel, real Task, and Member summaries. It does not return Thread messages or activities.
14
14
 
15
- An Agent cannot silently enroll an unfollowed Agent through a mention; the Host returns `member_not_following`. Human confirmation is a separate Host/Client flow. Closed Tasks reject replies, Claims, and new Attention until a Human reopens them.
15
+ An Agent cannot silently enroll an unfollowed Agent through a mention; the Host returns `member_not_following`. Human confirmation is a separate Host/Client flow. Closed Tasks reject replies, Claims, and new Attention until a Human reopens them; taskless Threads have no Claim or Task-resolution mutation path.
16
16
 
17
- Canonical results expose stable refs, current Task status, Thread revision, Claim history, Attention, and unread facts. Typed `unread_required` and `stale_revision` results include the fields needed to reread and retry deliberately. Tool execution resolves the exact live `exec.agent`; arguments cannot select or impersonate the actor or Workspace. Write request identity derives from sessionId plus tool callId. Team tools return to the model loop and never conclude the turn.
17
+ Canonical results expose stable refs, optional Task status, Thread revision, Claim history, Attention, and unread facts. Typed `unread_required` and `stale_revision` results include the fields needed to reread and retry deliberately. Tool execution resolves the exact live `exec.agent`; arguments cannot select or impersonate the actor or Workspace. Write request identity derives from sessionId plus tool callId. Team tools return to the model loop and never conclude the turn.
18
18
 
19
19
  The complete implemented protocol is documented in [`../../docs/team-collaboration.md`](../../docs/team-collaboration.md).
20
20
 
@@ -6,15 +6,15 @@
6
6
 
7
7
  ## 工具
8
8
 
9
- - `team_inbox` 列出调用方 Member 的有界未读 Thread 摘要,先按 direct work、再按最近活动排序。
10
- - `team_thread` 读取 Thread、分页历史、follow 或 unfollow。`read` 原子返回 Task anchor、当前 Task 与 Claim 快照、有界背景和一批连续未读事实,并推进持久 watermark;`history` 不改变 read 状态。
11
- - `team_message` 创建顶层 Task,或回复已有 Thread。Reply 必须携带准确的 `baseRevision`,并在检查 revision 前先处理未读门禁。
12
- - `team_claim` 通过 `list`、`claim`、`done`、`release` 读取或修改调用方 Member 的 Direction Claim。Direction 互斥键执行 Unicode NFKC normalization、trim、空白压缩和确定性大小写折叠。
13
- - `team_view` 发现有界、按 membership 授权的 ChannelTask 和 Member 摘要,不返回 Thread Message 或 Activity。
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、当前 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。
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
- taskRef: { type: 'string', required: true }, threadRef: { type: 'string', required: true }, channelRef: { type: 'string', required: true },
29
- status: { type: 'string', required: true }, revision: { type: 'number', required: true }, unreadCount: { type: 'number', required: true }, directCount: { type: 'number', required: true },
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 { taskRef: item.task.taskRef, threadRef: item.thread.threadRef, channelRef: item.channelRef,
50
- status: item.task.status, revision: item.thread.revision, unreadCount: item.unreadCount, directCount: item.directCount,
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 Task Thread. read acknowledges one chronological batch; history does not change read state.',
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
- taskRef: { type: 'string', required: true, description: "Full branded Task ref exactly as returned by Team tools, including the 'task:' prefix." },
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 }, taskRef: { type: 'string', required: true }, threadRef: { type: 'string', required: true },
67
- revision: { type: 'number', required: true }, status: { type: 'string', required: true }, resolution: { type: 'string', required: true },
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
- const base = { workspaceId: current.workspaceId, taskRef: args.taskRef };
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, taskRef: snapshot.task.taskRef, threadRef: snapshot.thread.threadRef, revision: snapshot.thread.revision,
124
- status: snapshot.task.status, resolution: snapshot.task.resolution, following: attention !== undefined,
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: 'Create a top-level Task or reply to one existing Task Thread. 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.',
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
- taskRef: { type: 'string', description: "Full branded Task ref exactly as returned by Team tools, including the 'task:' prefix." },
139
- 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 Task. The revision is an internal concurrency token, not a citable fact." },
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(', ') ?? `Task ${value.taskRef ?? ''} revision ${value.revision ?? ''}`}` }],
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 taskRef and a positive baseRevision, and does not accept channelRef; use the current Thread 'revision' returned by team_inbox or team_thread for this Task");
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
- taskRef: args.taskRef, body: args.body, baseRevision,
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, taskRef: result.task.taskRef, threadRef: result.thread.threadRef,
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: result.taskRef, threadRef: result.threadRef,
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: result.taskRef, threadRef: result.threadRef, expectedRevision: result.expectedRevision,
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;AAUlD,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAC/C,eAAO,MAAM,MAAM,UAAY,CAAA;AA4R/B,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAMxC"}
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"}