cs-bots 0.9.0 → 0.9.3

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/src/tools.js CHANGED
@@ -94,6 +94,18 @@ const DEFS = [
94
94
  priority: { type: 'number', description: '优先级(数值越大越先)' },
95
95
  dueAt: { type: 'number', description: '截止时间(epoch ms)' },
96
96
  sourceSeq: { type: 'string', description: '幂等键:同键重复创建只产生一条' },
97
+ source: {
98
+ type: 'string',
99
+ enum: ['human', 'ai'],
100
+ description: '谁下的令:human=人(Boss)/ ai=智能体。不传则按调用者身份自动推断。',
101
+ },
102
+ channel: {
103
+ type: 'string',
104
+ enum: ['user', 'session', 'external'],
105
+ description:
106
+ '从哪个入口下的令(t-40 需求①):user=用户在页面手工建 / session=会话里产出 / '
107
+ + 'external=外部渠道接入(预留)。不传则按 source 推断(人→user,智能体→session)。',
108
+ },
97
109
  expectedComplexity: {
98
110
  type: 'string',
99
111
  enum: ['T0', 'T1', 'T2', 'T3'],
@@ -144,7 +156,9 @@ const DEFS = [
144
156
  },
145
157
  {
146
158
  name: 'bot_task_list',
147
- description: '列出 cs-bots 任务板上的任务。默认不含已删除(tombstone);传 status 可只看某状态。',
159
+ description:
160
+ '列出 cs-bots 任务板上的任务。默认不含已删除(tombstone);传 status 可只看某状态;'
161
+ + '传 source / channel 可按「谁下的令 / 从哪个入口下的令」筛选(t-40 需求①)。',
148
162
  parameters: {
149
163
  type: 'object',
150
164
  properties: {
@@ -153,12 +167,46 @@ const DEFS = [
153
167
  enum: ['pending', 'in_progress', 'completed', 'blocked', 'deleted'],
154
168
  description: '只看该状态',
155
169
  },
170
+ source: { type: 'string', enum: ['human', 'ai'], description: '只看该来源(人 / 智能体)' },
171
+ channel: {
172
+ type: 'string',
173
+ enum: ['user', 'session', 'external'],
174
+ description: '只看该渠道(用户手工 / 会话产出 / 外部接入)',
175
+ },
156
176
  },
157
177
  additionalProperties: false,
158
178
  },
159
179
  run: (s, a) => {
160
180
  if (!s.board) return failure('board-unavailable')
161
- return success({ tasks: s.board.list(a?.status ? { status: a.status } : {}) })
181
+ // 只把**给了的**过滤条件传下去:给 undefined 会命中 `!== null` 分支造成误筛
182
+ const opts = {}
183
+ if (a?.status) opts.status = a.status
184
+ if (a?.source) opts.source = a.source
185
+ if (a?.channel) opts.channel = a.channel
186
+ return success({ tasks: s.board.list(opts) })
187
+ },
188
+ },
189
+ {
190
+ name: 'bot_task_room',
191
+ description:
192
+ '给任务开一个议事厅(群聊房间)。**长任务在建任务时就自动有了**,本工具用于:' +
193
+ '① 短任务按需开(Boss:「短任务默认不建房间,防止房间爆炸,需要时再建」);' +
194
+ '② 长任务的议事厅丢了/想补一个。幂等:已有就复用,不会重复建。' +
195
+ '需要任务有负责人(没负责人就没有团队可挂)。',
196
+ parameters: {
197
+ type: 'object',
198
+ properties: { id: { type: 'string', description: '任务 id' } },
199
+ required: ['id'],
200
+ additionalProperties: false,
201
+ },
202
+ run: async (s, a, exec) => {
203
+ if (typeof s.openTaskRoom !== 'function') return failure('task-room-unavailable', { hint: '后端未注入 openTaskRoom' })
204
+ try {
205
+ const r = await s.openTaskRoom(String(a.id ?? ''), callerOf(exec))
206
+ return r.ok ? success(r) : failure('task-room-failed', { message: r.reason })
207
+ } catch (error) {
208
+ return failure(error?.code ?? 'task-room-failed', { message: String(error?.message ?? error) })
209
+ }
162
210
  },
163
211
  },
164
212
  {
@@ -428,6 +476,31 @@ const DEFS = [
428
476
  return success({ bots: [...live, ...retired] })
429
477
  },
430
478
  },
479
+ {
480
+ name: 'bot_roster_purge',
481
+ description:
482
+ '把**已退役**的 Bot 从注册表里真正清掉(retire 只是标记,记录会一直留着)。' +
483
+ '**只能清已退役的**:在役 Bot 一律拒绝。**不删工作目录、不杀会话** —— ' +
484
+ '只移除注册表记录,cwd 里的产物原样保留。清理动作在审计流里留档,可追溯。' +
485
+ 'allRetired:true 一次清干净;或用 ids 指定。(**官方 roster 没有这个能力**)',
486
+ parameters: {
487
+ type: 'object',
488
+ properties: {
489
+ allRetired: { type: 'boolean', description: '清全部已退役的 Bot(与 ids 二选一)' },
490
+ ids: { type: 'array', items: { type: 'string' }, description: '指定要清的 Bot id 列表' },
491
+ reason: { type: 'string', description: '清理原因(写进审计流)' },
492
+ },
493
+ additionalProperties: false,
494
+ },
495
+ run: (s, a, exec) => {
496
+ if (!s.roster) return failure('roster-unavailable')
497
+ try {
498
+ return success(s.roster.purge({ ids: a.ids, allRetired: a.allRetired, reason: a.reason, byId: callerOf(exec) }))
499
+ } catch (error) {
500
+ return failure(error?.code ?? 'ROSTER_PURGE_FAILED', { message: String(error?.message ?? error) })
501
+ }
502
+ },
503
+ },
431
504
  {
432
505
  name: 'bot_roster_manage',
433
506
  description: