agentworkshop 0.7.14 → 0.7.16

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 (35) hide show
  1. package/.AgentWorkShop/prompts/host-tools.json +819 -755
  2. package/.output/.AgentWorkShop/prompts/host-tools.json +819 -755
  3. package/.output/nitro.json +1 -1
  4. package/.output/public/_nuxt/builds/latest.json +1 -1
  5. package/.output/public/_nuxt/builds/meta/cf0a8831-4514-493d-ad5a-4e371a089ef9.json +1 -0
  6. package/.output/server/chunks/_/nitro.mjs +885 -725
  7. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  8. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs +1 -1
  9. package/.output/server/chunks/routes/api/workshop/dcw/index.post.mjs.map +1 -1
  10. package/.output/server/chunks/routes/api/workshop/index3.post.mjs +1 -1
  11. package/.output/server/chunks/routes/api/workshop/index3.post.mjs.map +1 -1
  12. package/.output/server/package.json +1 -1
  13. package/package.json +1 -1
  14. package/scripts/_dbg-harness-ui-e2e.py +23 -13
  15. package/scripts/_dbg-opslog-agent-e2e.mjs +191 -0
  16. package/scripts/aw-expose.mjs +159 -0
  17. package/server/api/workshop/daq/index.post.ts +1 -1
  18. package/server/api/workshop/dcw/lines/index.post.ts +1 -1
  19. package/server/data/daqs.json +471 -61
  20. package/server/data/dcw-lines.json +49 -0
  21. package/server/data/dcw-products.json +49 -0
  22. package/server/data/dcw-recipes.json +64 -0
  23. package/server/data/dcw-rollback.json +239 -6
  24. package/server/data/dcw-runs.json +162 -142
  25. package/server/data/dcw-writes.json +156 -0
  26. package/server/data/dcws.json +363 -217
  27. package/server/data/line-runs.json +41 -11
  28. package/server/data/scene-layouts.json +11 -0
  29. package/server/plugins/workshop.ts +9 -0
  30. package/server/services/workshop/agents/agent-badge.ts +38 -0
  31. package/server/services/workshop/agents/host-tool-bridge.ts +622 -612
  32. package/server/services/workshop/agents/industrial-tools.ts +139 -4
  33. package/server/services/workshop/daq/drivers.ts +25 -5
  34. package/server/services/workshop/dcw/recipe-rollback-manager.ts +8 -6
  35. package/.output/public/_nuxt/builds/meta/23c30854-f9e1-4651-bc3a-b695ef5faca4.json +0 -1
@@ -1,755 +1,819 @@
1
- [
2
- {
3
- "name": "report_progress",
4
- "label": "Report Progress",
5
- "description": "Report your current task progress as a percentage (0-100). Call this whenever you make meaningful progress on your task.",
6
- "parameters": {
7
- "type": "object",
8
- "properties": {
9
- "progress": {
10
- "type": "number",
11
- "description": "Progress percentage 0-100"
12
- },
13
- "message": {
14
- "type": "string",
15
- "description": "Brief status message describing what you are doing"
16
- }
17
- },
18
- "required": [
19
- "progress"
20
- ]
21
- }
22
- },
23
- {
24
- "name": "complete_task",
25
- "label": "Complete Task",
26
- "description": "Mark a task as completed with final deliverables. Workers call this when their assigned task is done. Lead calls this for parent tasks when all children are done.",
27
- "parameters": {
28
- "type": "object",
29
- "properties": {
30
- "summary": {
31
- "type": "string",
32
- "description": "Summary of what was accomplished"
33
- },
34
- "deliverable": {
35
- "type": "string",
36
- "description": "Final deliverable: code, analysis result, document content, etc."
37
- },
38
- "task_id": {
39
- "type": "string",
40
- "description": "Task ID to complete. If omitted, completes your current assigned task."
41
- }
42
- },
43
- "required": [
44
- "summary"
45
- ]
46
- }
47
- },
48
- {
49
- "name": "dispatch_task",
50
- "label": "Dispatch Task",
51
- "description": "(Lead only) Create a subtask under a submitted parent task and assign it to a worker. Always provide parent_task_id so the parent task tracks completion. Always state route_reason: why THIS agent (specialty fit / shortest queue / past success evidence from the member capability table) — it is kept on the task as an auditable routing decision.",
52
- "parameters": {
53
- "type": "object",
54
- "properties": {
55
- "assignee_id": {
56
- "type": "string",
57
- "description": "ID of the worker agent to assign this task to"
58
- },
59
- "title": {
60
- "type": "string",
61
- "description": "Short task title"
62
- },
63
- "route_reason": {
64
- "type": "string",
65
- "description": "Why this agent was chosen (specialty fit / load / past success evidence) — one short line, kept as the auditable routing decision"
66
- },
67
- "description": {
68
- "type": "string",
69
- "description": "Detailed task description with requirements"
70
- },
71
- "parent_task_id": {
72
- "type": "string",
73
- "description": "The ID of the submitted parent task this subtask belongs to (from the task list)"
74
- }
75
- },
76
- "required": [
77
- "assignee_id",
78
- "title",
79
- "parent_task_id"
80
- ]
81
- }
82
- },
83
- {
84
- "name": "send_message_to_agent",
85
- "label": "Send Message",
86
- "description": "Send a message to another agent (lead or worker) in the same channel via the channel mailbox (routed to the recipient's own mailbox). Use priority \"immediate\" for urgent real-time messages that the recipient sees instantly during work; use \"task\" (default) for messages that queue until the recipient finishes their current task. Set require_reply=true to demand a response: the recipient must reply with their result via this same tool. When replying to a message, pass its message_id as in_reply_to — replies are auto-upgraded to real-time delivery and pushed straight into the recipient's running session, so the answer reaches a waiting sender instantly.",
87
- "parameters": {
88
- "type": "object",
89
- "properties": {
90
- "to_agent_id": {
91
- "type": "string",
92
- "description": "Recipient agent ID"
93
- },
94
- "message": {
95
- "type": "string",
96
- "description": "Message content (when replying: your execution result + the content they asked for)"
97
- },
98
- "priority": {
99
- "type": "string",
100
- "enum": [
101
- "immediate",
102
- "task"
103
- ],
104
- "description": "Message priority: \"immediate\" = inject into recipient's running session instantly; \"task\" = queue for later consumption (default)"
105
- },
106
- "require_reply": {
107
- "type": "boolean",
108
- "description": "Trigger: true = recipient MUST reply with result/content (default false)"
109
- },
110
- "in_reply_to": {
111
- "type": "string",
112
- "description": "Message ID this reply refers to (set when replying to a trigger message)"
113
- }
114
- },
115
- "required": [
116
- "to_agent_id",
117
- "message"
118
- ]
119
- }
120
- },
121
- {
122
- "name": "poll_messages",
123
- "label": "Poll Inbox",
124
- "description": "Check your own mailbox for unread messages from other agents. When waiting for a reply, pass wait_seconds (e.g. 90) to block until it arrives or the wait expires — one blocking call replaces repeated empty polling. Returned collaboration messages are acknowledged on read (removed from the queue); task assignments are left for execution. Replies to your trigger messages are also pushed into your running session in real time — if you already saw an injected \"[实时消息 from X]\", that IS the reply, no need to poll again.",
125
- "parameters": {
126
- "type": "object",
127
- "properties": {
128
- "limit": {
129
- "type": "number",
130
- "description": "Max messages to return (default 10)"
131
- },
132
- "wait_seconds": {
133
- "type": "number",
134
- "description": "Block up to N seconds (0-180) waiting for a message before returning empty (default 0 = immediate check)"
135
- }
136
- }
137
- }
138
- },
139
- {
140
- "name": "read_channel_mail",
141
- "label": "Read Channel Mail",
142
- "description": "(Lead only) Read the FULL channel mail log: every message routed through the channel mailbox (peer messages, real-time replies with in_reply_to chains, and task deliveries), newest first, with read/unread state. Pass agent_id to inspect a specific member's mailbox. Use this BEFORE dispatching a task whose result may already exist — if a worker already computed/delivered the value via mail, do NOT re-dispatch it; reference the concrete result from the mail instead.",
143
- "parameters": {
144
- "type": "object",
145
- "properties": {
146
- "limit": {
147
- "type": "number",
148
- "description": "Max mails to return (default 50, max 500)"
149
- },
150
- "agent_id": {
151
- "type": "string",
152
- "description": "Optional: only show mails involving this agent (as sender or recipient)"
153
- }
154
- }
155
- }
156
- },
157
- {
158
- "name": "broadcast_message",
159
- "label": "Broadcast",
160
- "description": "Broadcast a message to ALL agents in the channel (lead + all workers). Useful for announcements.",
161
- "parameters": {
162
- "type": "object",
163
- "properties": {
164
- "message": {
165
- "type": "string",
166
- "description": "Message content to broadcast"
167
- },
168
- "priority": {
169
- "type": "string",
170
- "enum": [
171
- "immediate",
172
- "task"
173
- ],
174
- "description": "Message priority (default \"task\")"
175
- }
176
- },
177
- "required": [
178
- "message"
179
- ]
180
- }
181
- },
182
- {
183
- "name": "list_channel_tasks",
184
- "label": "List Tasks",
185
- "description": "List all tasks in the current channel, including their status, progress, and assignee.",
186
- "parameters": {
187
- "type": "object",
188
- "properties": {}
189
- }
190
- },
191
- {
192
- "name": "list_team_agents",
193
- "label": "List Team",
194
- "description": "List all agents in the current channel (lead + workers) with their roles and names.",
195
- "parameters": {
196
- "type": "object",
197
- "properties": {}
198
- }
199
- },
200
- {
201
- "name": "get_task_details",
202
- "label": "Get Task",
203
- "description": "Get detailed information about a specific task, including artifacts and history.",
204
- "parameters": {
205
- "type": "object",
206
- "properties": {
207
- "task_id": {
208
- "type": "string",
209
- "description": "Task ID"
210
- }
211
- },
212
- "required": [
213
- "task_id"
214
- ]
215
- }
216
- },
217
- {
218
- "name": "get_my_task_queue",
219
- "label": "My Queue",
220
- "description": "View your own task queue: pending tasks (FIFO order), the task you are currently executing, and completed tasks. Use this to check if you have unfinished work.",
221
- "parameters": {
222
- "type": "object",
223
- "properties": {}
224
- }
225
- },
226
- {
227
- "name": "get_queue_overview",
228
- "label": "Queue Overview",
229
- "description": "(Lead only) Real-time overview of every team member: status (idle/busy), current task, pending queue length, completed count. Use this to make optimal scheduling and rebalancing decisions.",
230
- "parameters": {
231
- "type": "object",
232
- "properties": {}
233
- }
234
- },
235
- {
236
- "name": "reassign_task",
237
- "label": "Reassign Task",
238
- "description": "(Lead only) Move a pending (not yet started) or failed task from one worker to another. Use for load rebalancing or when a worker is stuck. The old worker's queued delivery is revoked automatically.",
239
- "parameters": {
240
- "type": "object",
241
- "properties": {
242
- "task_id": {
243
- "type": "string",
244
- "description": "Task ID to move"
245
- },
246
- "to_agent_id": {
247
- "type": "string",
248
- "description": "Worker agent ID to receive the task"
249
- }
250
- },
251
- "required": [
252
- "task_id",
253
- "to_agent_id"
254
- ]
255
- }
256
- },
257
- {
258
- "name": "update_task",
259
- "label": "Update Task",
260
- "description": "(Lead only) Modify the title/description of a pending (queued, not started) task. The assignee's queued delivery is refreshed with the new content automatically.",
261
- "parameters": {
262
- "type": "object",
263
- "properties": {
264
- "task_id": {
265
- "type": "string",
266
- "description": "Task ID to update"
267
- },
268
- "title": {
269
- "type": "string",
270
- "description": "New title (optional)"
271
- },
272
- "description": {
273
- "type": "string",
274
- "description": "New description (optional)"
275
- }
276
- },
277
- "required": [
278
- "task_id"
279
- ]
280
- }
281
- },
282
- {
283
- "name": "cancel_task",
284
- "label": "Cancel Task",
285
- "description": "Cancel a task and remove it from the assignee's queue (lead can cancel any; assignee can cancel own). Pending queued deliveries are revoked automatically.",
286
- "parameters": {
287
- "type": "object",
288
- "properties": {
289
- "task_id": {
290
- "type": "string",
291
- "description": "Task ID to cancel"
292
- }
293
- },
294
- "required": [
295
- "task_id"
296
- ]
297
- }
298
- },
299
- {
300
- "name": "search_memory",
301
- "label": "Search Memory",
302
- "description": "Search your persistent memory (hybrid keyword+semantic retrieval over your private memories and the channel's shared team memories). Results may include: your task history, the TEAM CHRONICLE (团队编年史 = rolling log of everything the team finished), past SESSION COMPACTION SUMMARIES (会话压缩摘要 = conclusions from earlier context windows), monthly reflections (作业反思), and shared conventions. Use this ANY TIME you need prior context: before starting a task, when you suspect relevant past work exists, or when the injected memory hints/brief mention something you need details on. Pass a focused query describing what you want to remember.",
303
- "parameters": {
304
- "type": "object",
305
- "properties": {
306
- "query": {
307
- "type": "string",
308
- "description": "What you want to recall, e.g. \"数据库连接池配置结论\" or \"previous deployment checklist\""
309
- },
310
- "scope": {
311
- "type": "string",
312
- "enum": [
313
- "auto",
314
- "private",
315
- "shared"
316
- ],
317
- "description": "Which memory domain to search: \"auto\" = your private + channel shared (default), \"private\" = only your own, \"shared\" = only channel-wide shared memories"
318
- },
319
- "limit": {
320
- "type": "number",
321
- "description": "Max results (default 5, max 20)"
322
- }
323
- },
324
- "required": [
325
- "query"
326
- ]
327
- }
328
- },
329
- {
330
- "name": "save_memory",
331
- "label": "Save Memory",
332
- "description": "Persist a distilled, reusable insight into memory for future tasks. scope=\"private\" saves to YOUR personal memory (only you recall it); scope=\"shared\" saves to the CHANNEL shared memory visible to ALL teammates (use for conclusions, conventions, or knowledge the whole team benefits from — not task-specific minutiae). Distill before saving: title = short topic, content = the reusable conclusion. Use a stable dedup_key to update an existing memory instead of duplicating. NOTE: the platform already auto-archives task outcomes, team results, the team chronicle, and session compaction summaries — never save whole task logs or raw session transcripts.",
333
- "parameters": {
334
- "type": "object",
335
- "properties": {
336
- "title": {
337
- "type": "string",
338
- "description": "Short topic title, e.g. \"API 网关限流方案结论\""
339
- },
340
- "content": {
341
- "type": "string",
342
- "description": "The distilled reusable knowledge/conclusion (plain text)"
343
- },
344
- "importance": {
345
- "type": "number",
346
- "description": "0-1 importance (default 0.7 private / 0.85 shared)"
347
- },
348
- "scope": {
349
- "type": "string",
350
- "enum": [
351
- "private",
352
- "shared"
353
- ],
354
- "description": "\"private\" = your memory only; \"shared\" = channel-wide shared memory for all teammates"
355
- },
356
- "dedup_key": {
357
- "type": "string",
358
- "description": "Stable key for idempotent update (same key overwrites instead of duplicating)"
359
- }
360
- },
361
- "required": [
362
- "title",
363
- "content",
364
- "scope"
365
- ]
366
- }
367
- },
368
- {
369
- "name": "create_team_agent",
370
- "label": "Create Team Agent",
371
- "description": "(Lead only) Create a NEW worker agent and add it to your channel's team, on the fly. Use ONLY when all workers stay busy with a persistent backlog, or when a task clearly needs a specialist that doesn't exist yet — not for routine tasks the current team can handle. The new member starts idle, appears in list_team_agents immediately, and can receive dispatch_task assignments right away. Give it a clear name and a system_prompt describing its specialty.",
372
- "parameters": {
373
- "type": "object",
374
- "properties": {
375
- "name": {
376
- "type": "string",
377
- "description": "Short, descriptive member name, e.g. \"db-migrator\" or \"test-writer\""
378
- },
379
- "harness": {
380
- "type": "string",
381
- "enum": [
382
- "omp",
383
- "mock",
384
- "claude"
385
- ],
386
- "description": "Agent harness: \"omp\" = full LLM agent with native work tools (default, use this for real work), \"mock\" = scripted test agent, \"claude\" = claude harness"
387
- },
388
- "system_prompt": {
389
- "type": "string",
390
- "description": "System prompt prefix defining this member's specialty, working style, and conventions (maps to its systemPromptPrefix config)"
391
- },
392
- "reason": {
393
- "type": "string",
394
- "description": "Why this member is being added (shown to the user in the team event timeline)"
395
- }
396
- },
397
- "required": [
398
- "name"
399
- ]
400
- }
401
- },
402
- {
403
- "name": "update_team_agent",
404
- "label": "Update Team Agent",
405
- "description": "(Lead only) Update an existing team member (worker): rename it, revise its system prompt (e.g. to specialize or correct its behavior), or enable/disable it. The member's runtime reloads with the new config on its next assignment. You cannot update yourself.",
406
- "parameters": {
407
- "type": "object",
408
- "properties": {
409
- "agent_id": {
410
- "type": "string",
411
- "description": "ID of the worker agent to update (from list_team_agents)"
412
- },
413
- "name": {
414
- "type": "string",
415
- "description": "New name (optional)"
416
- },
417
- "system_prompt": {
418
- "type": "string",
419
- "description": "New system prompt prefix defining its specialty/conventions (optional)"
420
- },
421
- "enabled": {
422
- "type": "boolean",
423
- "description": "true = activate member, false = disable member (disabled members receive no new tasks; default true)"
424
- },
425
- "reason": {
426
- "type": "string",
427
- "description": "Why this change is made (shown in the team event timeline)"
428
- }
429
- },
430
- "required": [
431
- "agent_id"
432
- ]
433
- }
434
- },
435
- {
436
- "name": "remove_team_agent",
437
- "label": "Remove Team Agent",
438
- "description": "(Lead only) Remove a worker from your channel's team. Its queued tasks are automatically re-dispatched to the remaining worker with the shortest queue (or failed for retry if it was mid-execution), so no work is lost — but the member's context is. Use ONLY for sustained idle surplus or persistent underperformance; never as an experiment, and avoid removing members with active work. You cannot remove yourself.",
439
- "parameters": {
440
- "type": "object",
441
- "properties": {
442
- "agent_id": {
443
- "type": "string",
444
- "description": "ID of the worker agent to remove"
445
- },
446
- "reason": {
447
- "type": "string",
448
- "description": "Why this member is removed (shown in the team event timeline)"
449
- }
450
- },
451
- "required": [
452
- "agent_id"
453
- ]
454
- }
455
- },
456
- {
457
- "name": "refuse_task",
458
- "label": "Refuse Task",
459
- "description": "Reject a task assigned to you because it is outside your capability or work scope (wrong recipient, unrelated domain, or missing prerequisites). The task is marked FAILED with your reason and a rejection notice is immediately sent back to the dispatcher (task creator, or the channel lead), who should reassign it to a fitting member. Use this INSTEAD of silently ignoring the task or doing unrelated work; do NOT use it for tasks you are able to do, and do NOT use cancel_task for refusals.",
460
- "parameters": {
461
- "type": "object",
462
- "properties": {
463
- "task_id": {
464
- "type": "string",
465
- "description": "ID of the task you are refusing (must be assigned to you)"
466
- },
467
- "reason": {
468
- "type": "string",
469
- "description": "Why the task is out of your scope: capability mismatch / wrong recipient / prerequisites missing. Be specific so the dispatcher can reassign properly."
470
- }
471
- },
472
- "required": [
473
- "task_id",
474
- "reason"
475
- ]
476
- }
477
- },
478
- {
479
- "name": "my_industrial_nodes",
480
- "label": "My Industrial Nodes",
481
- "description": "列出你绑定的全部数采/数控节点及其物理含义(参数含义/单位/安全量程/活动配方工艺窗口/控制模式)。在进行任何工业操作前必须先调用本工具理解节点语义与设定规则。",
482
- "parameters": {
483
- "type": "object",
484
- "properties": {}
485
- }
486
- },
487
- {
488
- "name": "dcw_control",
489
- "label": "DCW Control",
490
- "description": "对绑定的数控节点下发工艺设定值(真实物理量纲)。仅限你有权控制的节点;设定值会被安全量程与活动配方工艺窗口联锁校验,越窗直接拒绝。手动确认模式下需等待用户批准,用户备注会随结果返回。下发前先调用 my_industrial_nodes 理解节点物理含义。",
491
- "parameters": {
492
- "type": "object",
493
- "properties": {
494
- "node_id": {
495
- "type": "string",
496
- "description": "数控节点 id(见 my_industrial_nodes)"
497
- },
498
- "value": {
499
- "type": "number",
500
- "description": "目标设定值(真实物理量纲,如 ℃)"
501
- },
502
- "hypothesis": {
503
- "type": "string",
504
- "description": "本次调参假设(入优化记录档案):目标 + 预期效果 + 观察计划,如「提温 1℃ 预期张力上升 2%,5 分钟后复测」"
505
- },
506
- "task_id": {
507
- "type": "string",
508
- "description": "关联的优化任务 id(可选,入优化记录档案)"
509
- }
510
- },
511
- "required": [
512
- "node_id",
513
- "value"
514
- ]
515
- }
516
- },
517
- {
518
- "name": "dcw_read",
519
- "label": "DCW Read",
520
- "description": "读取绑定的数控节点的 PLC 当前值(读写集成的读半边)。返回 PLC 实时读数(经标定解码的物理量纲)与设定值对照;用于下发前取证、下发后复核设定是否生效。读取是被动观测,不影响控制状态,也不需要审批。",
521
- "parameters": {
522
- "type": "object",
523
- "properties": {
524
- "node_id": {
525
- "type": "string",
526
- "description": "数控节点 id(见 my_industrial_nodes)"
527
- }
528
- },
529
- "required": [
530
- "node_id"
531
- ]
532
- }
533
- },
534
- {
535
- "name": "daq_query",
536
- "label": "DAQ Query",
537
- "description": "从时序数据库检索你绑定的数采节点的历史/实时数据。支持按产线/产品/配方/时间窗/降采样多维过滤(产品/配方过滤基于逐样本打标,可精确取某批次数据);返回结果携带物理含义(参数语义/单位/量程/统计摘要/最近序列)。",
538
- "parameters": {
539
- "type": "object",
540
- "properties": {
541
- "node_id": {
542
- "type": "string",
543
- "description": "限定单个数采节点 id(缺省 = 全部绑定节点)"
544
- },
545
- "line_id": {
546
- "type": "string",
547
- "description": "按产线过滤(数据归属产线)"
548
- },
549
- "product_id": {
550
- "type": "string",
551
- "description": "按产品过滤(逐样本打标)"
552
- },
553
- "recipe_id": {
554
- "type": "string",
555
- "description": "按配方/批次过滤(逐样本打标)"
556
- },
557
- "last_minutes": {
558
- "type": "number",
559
- "description": "最近 N 分钟(缺省 30)"
560
- },
561
- "from_ms": {
562
- "type": "number",
563
- "description": "起始 epoch ms(与 to_ms 配合,优先于 last_minutes)"
564
- },
565
- "to_ms": {
566
- "type": "number",
567
- "description": "结束 epoch ms"
568
- },
569
- "bucket_ms": {
570
- "type": "number",
571
- "description": "时间间隔(降采样桶宽 ms):缺省 {queryDefaultBucketMs}(15s);可调,下限 {queryMinBucketMs}。不传即用缺省;系统配置变更后以新值为准"
572
- },
573
- "limit": {
574
- "type": "number",
575
- "description": "返回点数上限(缺省 500)"
576
- }
577
- }
578
- }
579
- },
580
- {
581
- "name": "dcw_judge",
582
- "label": "DCW Judge",
583
- "description": "对你发起的优化记录(调控 step)落判定。keep=已验证经验(配方可标 lastGood);rollback=判定应回退(判定入册后必须再调 dcw_rollback 执行,判定不自动改 PLC);uncertain=证据不足保持观察。判定必须引用数采证据(daq_query 窗口数据),禁止无证据判定。",
584
- "parameters": {
585
- "type": "object",
586
- "properties": {
587
- "record_id": {
588
- "type": "string",
589
- "description": "优化记录 id(dcw_control 下发成功后返回)"
590
- },
591
- "verdict": {
592
- "type": "string",
593
- "description": "判定结论:keep / rollback / uncertain",
594
- "enum": [
595
- "keep",
596
- "rollback",
597
- "uncertain"
598
- ]
599
- },
600
- "reason": {
601
- "type": "string",
602
- "description": "判定理由(必须引用具体数值/时间窗证据)"
603
- }
604
- },
605
- "required": [
606
- "record_id",
607
- "verdict",
608
- "reason"
609
- ]
610
- }
611
- },
612
- {
613
- "name": "dcw_rollback",
614
- "label": "DCW Rollback",
615
- "description": "执行参数回退(经与下发相同的安全门控,回退本身入册可审计)。record_id=回退你自己发起的优化记录到其设定前值;node_id=单步撤销到最近稳定锚。回退后必须 daq_query 复测确认恢复。冷却期内同向重写/重复回退会被拒绝。",
616
- "parameters": {
617
- "type": "object",
618
- "properties": {
619
- "record_id": {
620
- "type": "string",
621
- "description": "要回退的优化记录 id(与 node_id 二选一)"
622
- },
623
- "node_id": {
624
- "type": "string",
625
- "description": "节点单步回退(撤销栈栈顶;与 record_id 二选一)"
626
- },
627
- "to": {
628
- "type": "string",
629
- "description": "可选:指定目标锚 id(dcw_journal 可查)"
630
- }
631
- }
632
- }
633
- },
634
- {
635
- "name": "dcw_journal",
636
- "label": "DCW Journal",
637
- "description": "查询参数变更史与优化记录(在册审计):谁/何时/从多少到多少/判定结论/假设声明。优化前先读史可避免重复试错;回退定位也在此查。",
638
- "parameters": {
639
- "type": "object",
640
- "properties": {
641
- "node_id": {
642
- "type": "string",
643
- "description": "限定数控节点 id(仅限自己绑定的节点)"
644
- },
645
- "recipe_id": {
646
- "type": "string",
647
- "description": "按配方过滤优化记录"
648
- },
649
- "limit": {
650
- "type": "number",
651
- "description": "返回条数上限(缺省 20,最大 100)"
652
- }
653
- }
654
- }
655
- },
656
- {
657
- "name": "send_cross_channel_message",
658
- "label": "Cross-Channel Message",
659
- "description": "[Leader only] Send a message to the LEADER of another channel, so the two teams can collaborate without being siloed. The message lands directly in the target channel leader mailbox; that leader will read your request and act on it (dispatch tasks in their channel, gather info, etc.) and can reply to you via the mailbox. Params: to_channel_id accepts the target channel id OR its exact name; message is your request to the other leader (state your need, deadline and what you expect back); require_reply=true to demand a response. Only channel leaders may call this tool - workers will be rejected. When replying to a cross-channel request you received, use this same tool addressed to the requester channel.",
660
- "parameters": {
661
- "type": "object",
662
- "properties": {
663
- "to_channel_id": {
664
- "type": "string",
665
- "description": "Target channel id or exact name (must be another channel, not your own)"
666
- },
667
- "message": {
668
- "type": "string",
669
- "description": "Request text for the target channel leader: what you need, why, and what to return"
670
- },
671
- "require_reply": {
672
- "type": "boolean",
673
- "description": "true = demand the target leader reply with their result/answer"
674
- }
675
- },
676
- "required": [
677
- "to_channel_id",
678
- "message"
679
- ]
680
- }
681
- },
682
- {
683
- "name": "list_other_teams",
684
- "label": "List Other Teams",
685
- "description": "[Leader only] Overview of the OTHER teams (channels) in this workspace: each team name, description, lead, its in-progress scenario tasks, recently completed tasks, and how many shared memories it has (shared_memories > 0 means searchable knowledge exists - use search_other_teams_memory with that team). Decision flow: found knowledge -> reuse it directly; relevant work in progress but no knowledge yet -> message their leader via send_cross_channel_message; nothing -> consider whether your request justifies starting collaboration. Workers cannot call this tool.",
686
- "parameters": {
687
- "type": "object",
688
- "properties": {},
689
- "required": []
690
- }
691
- },
692
- {
693
- "name": "search_other_teams_memory",
694
- "label": "Search Other Teams Memory",
695
- "description": "[All members] Read-only search across the SHARED memory of other teams (channels) in this workspace - what other teams have learned/concluded/done. Use it to reuse existing knowledge instead of asking for it: if you find relevant results, apply them directly; if nothing relevant exists but the other team is working on it, ask your leader to message that team leader via send_cross_channel_message. Results are attributed to their team.",
696
- "parameters": {
697
- "type": "object",
698
- "properties": {
699
- "query": {
700
- "type": "string",
701
- "description": "What to look for (keywords of the knowledge/conclusion)"
702
- },
703
- "limit": {
704
- "type": "number",
705
- "description": "Max results (default 5)"
706
- }
707
- },
708
- "required": [
709
- "query"
710
- ]
711
- }
712
- },
713
- {
714
- "name": "daq_frames",
715
- "label": "DAQ Frames",
716
- "description": "Query multi-modal DAQ frames for your BOUND daq nodes: multi-point profiles (thickness scanners, profile scanners — returns point-count summary, a point preview and derived metrics) and camera image frames (CCD — returns resolution, object reference and derived metrics like brightness/contrast; pixels are NOT loaded into context, view them in the frontend gallery). Supports kind=vector|image filter and time windows. Use BEFORE judging surface quality or profile measurements.",
717
- "parameters": {
718
- "type": "object",
719
- "properties": {
720
- "node_id": {
721
- "type": "string",
722
- "description": "Limit to one bound daq node id (optional; default all your bound daq nodes)"
723
- },
724
- "line_id": {
725
- "type": "string",
726
- "description": "Filter by line id (can only narrow, never widen your access)"
727
- },
728
- "kind": {
729
- "type": "string",
730
- "enum": [
731
- "vector",
732
- "image"
733
- ],
734
- "description": "Frame kind filter (optional)"
735
- },
736
- "last_minutes": {
737
- "type": "number",
738
- "description": "Time window in minutes back from now (default 30)"
739
- },
740
- "from_ms": {
741
- "type": "number",
742
- "description": "Window start (epoch ms; overrides last_minutes)"
743
- },
744
- "to_ms": {
745
- "type": "number",
746
- "description": "Window end (epoch ms; default now)"
747
- },
748
- "limit": {
749
- "type": "number",
750
- "description": "Max frames per node (default 20, max 100)"
751
- }
752
- }
753
- }
754
- }
755
- ]
1
+ [
2
+ {
3
+ "name": "report_progress",
4
+ "label": "Report Progress",
5
+ "description": "Report your current task progress as a percentage (0-100). Call this whenever you make meaningful progress on your task.",
6
+ "parameters": {
7
+ "type": "object",
8
+ "properties": {
9
+ "progress": {
10
+ "type": "number",
11
+ "description": "Progress percentage 0-100"
12
+ },
13
+ "message": {
14
+ "type": "string",
15
+ "description": "Brief status message describing what you are doing"
16
+ }
17
+ },
18
+ "required": [
19
+ "progress"
20
+ ]
21
+ }
22
+ },
23
+ {
24
+ "name": "complete_task",
25
+ "label": "Complete Task",
26
+ "description": "Mark a task as completed with final deliverables. Workers call this when their assigned task is done. Lead calls this for parent tasks when all children are done.",
27
+ "parameters": {
28
+ "type": "object",
29
+ "properties": {
30
+ "summary": {
31
+ "type": "string",
32
+ "description": "Summary of what was accomplished"
33
+ },
34
+ "deliverable": {
35
+ "type": "string",
36
+ "description": "Final deliverable: code, analysis result, document content, etc."
37
+ },
38
+ "task_id": {
39
+ "type": "string",
40
+ "description": "Task ID to complete. If omitted, completes your current assigned task."
41
+ }
42
+ },
43
+ "required": [
44
+ "summary"
45
+ ]
46
+ }
47
+ },
48
+ {
49
+ "name": "dispatch_task",
50
+ "label": "Dispatch Task",
51
+ "description": "(Lead only) Create a subtask under a submitted parent task and assign it to a worker. Always provide parent_task_id so the parent task tracks completion. Always state route_reason: why THIS agent (specialty fit / shortest queue / past success evidence from the member capability table) — it is kept on the task as an auditable routing decision.",
52
+ "parameters": {
53
+ "type": "object",
54
+ "properties": {
55
+ "assignee_id": {
56
+ "type": "string",
57
+ "description": "ID of the worker agent to assign this task to"
58
+ },
59
+ "title": {
60
+ "type": "string",
61
+ "description": "Short task title"
62
+ },
63
+ "route_reason": {
64
+ "type": "string",
65
+ "description": "Why this agent was chosen (specialty fit / load / past success evidence) — one short line, kept as the auditable routing decision"
66
+ },
67
+ "description": {
68
+ "type": "string",
69
+ "description": "Detailed task description with requirements"
70
+ },
71
+ "parent_task_id": {
72
+ "type": "string",
73
+ "description": "The ID of the submitted parent task this subtask belongs to (from the task list)"
74
+ }
75
+ },
76
+ "required": [
77
+ "assignee_id",
78
+ "title",
79
+ "parent_task_id"
80
+ ]
81
+ }
82
+ },
83
+ {
84
+ "name": "send_message_to_agent",
85
+ "label": "Send Message",
86
+ "description": "Send a message to another agent (lead or worker) in the same channel via the channel mailbox (routed to the recipient's own mailbox). Use priority \"immediate\" for urgent real-time messages that the recipient sees instantly during work; use \"task\" (default) for messages that queue until the recipient finishes their current task. Set require_reply=true to demand a response: the recipient must reply with their result via this same tool. When replying to a message, pass its message_id as in_reply_to — replies are auto-upgraded to real-time delivery and pushed straight into the recipient's running session, so the answer reaches a waiting sender instantly.",
87
+ "parameters": {
88
+ "type": "object",
89
+ "properties": {
90
+ "to_agent_id": {
91
+ "type": "string",
92
+ "description": "Recipient agent ID"
93
+ },
94
+ "message": {
95
+ "type": "string",
96
+ "description": "Message content (when replying: your execution result + the content they asked for)"
97
+ },
98
+ "priority": {
99
+ "type": "string",
100
+ "enum": [
101
+ "immediate",
102
+ "task"
103
+ ],
104
+ "description": "Message priority: \"immediate\" = inject into recipient's running session instantly; \"task\" = queue for later consumption (default)"
105
+ },
106
+ "require_reply": {
107
+ "type": "boolean",
108
+ "description": "Trigger: true = recipient MUST reply with result/content (default false)"
109
+ },
110
+ "in_reply_to": {
111
+ "type": "string",
112
+ "description": "Message ID this reply refers to (set when replying to a trigger message)"
113
+ }
114
+ },
115
+ "required": [
116
+ "to_agent_id",
117
+ "message"
118
+ ]
119
+ }
120
+ },
121
+ {
122
+ "name": "poll_messages",
123
+ "label": "Poll Inbox",
124
+ "description": "Check your own mailbox for unread messages from other agents. When waiting for a reply, pass wait_seconds (e.g. 90) to block until it arrives or the wait expires — one blocking call replaces repeated empty polling. Returned collaboration messages are acknowledged on read (removed from the queue); task assignments are left for execution. Replies to your trigger messages are also pushed into your running session in real time — if you already saw an injected \"[实时消息 from X]\", that IS the reply, no need to poll again.",
125
+ "parameters": {
126
+ "type": "object",
127
+ "properties": {
128
+ "limit": {
129
+ "type": "number",
130
+ "description": "Max messages to return (default 10)"
131
+ },
132
+ "wait_seconds": {
133
+ "type": "number",
134
+ "description": "Block up to N seconds (0-180) waiting for a message before returning empty (default 0 = immediate check)"
135
+ }
136
+ }
137
+ }
138
+ },
139
+ {
140
+ "name": "read_channel_mail",
141
+ "label": "Read Channel Mail",
142
+ "description": "(Lead only) Read the FULL channel mail log: every message routed through the channel mailbox (peer messages, real-time replies with in_reply_to chains, and task deliveries), newest first, with read/unread state. Pass agent_id to inspect a specific member's mailbox. Use this BEFORE dispatching a task whose result may already exist — if a worker already computed/delivered the value via mail, do NOT re-dispatch it; reference the concrete result from the mail instead.",
143
+ "parameters": {
144
+ "type": "object",
145
+ "properties": {
146
+ "limit": {
147
+ "type": "number",
148
+ "description": "Max mails to return (default 50, max 500)"
149
+ },
150
+ "agent_id": {
151
+ "type": "string",
152
+ "description": "Optional: only show mails involving this agent (as sender or recipient)"
153
+ }
154
+ }
155
+ }
156
+ },
157
+ {
158
+ "name": "broadcast_message",
159
+ "label": "Broadcast",
160
+ "description": "Broadcast a message to ALL agents in the channel (lead + all workers). Useful for announcements.",
161
+ "parameters": {
162
+ "type": "object",
163
+ "properties": {
164
+ "message": {
165
+ "type": "string",
166
+ "description": "Message content to broadcast"
167
+ },
168
+ "priority": {
169
+ "type": "string",
170
+ "enum": [
171
+ "immediate",
172
+ "task"
173
+ ],
174
+ "description": "Message priority (default \"task\")"
175
+ }
176
+ },
177
+ "required": [
178
+ "message"
179
+ ]
180
+ }
181
+ },
182
+ {
183
+ "name": "list_channel_tasks",
184
+ "label": "List Tasks",
185
+ "description": "List all tasks in the current channel, including their status, progress, and assignee.",
186
+ "parameters": {
187
+ "type": "object",
188
+ "properties": {}
189
+ }
190
+ },
191
+ {
192
+ "name": "list_team_agents",
193
+ "label": "List Team",
194
+ "description": "List all agents in the current channel (lead + workers) with their roles and names.",
195
+ "parameters": {
196
+ "type": "object",
197
+ "properties": {}
198
+ }
199
+ },
200
+ {
201
+ "name": "get_task_details",
202
+ "label": "Get Task",
203
+ "description": "Get detailed information about a specific task, including artifacts and history.",
204
+ "parameters": {
205
+ "type": "object",
206
+ "properties": {
207
+ "task_id": {
208
+ "type": "string",
209
+ "description": "Task ID"
210
+ }
211
+ },
212
+ "required": [
213
+ "task_id"
214
+ ]
215
+ }
216
+ },
217
+ {
218
+ "name": "get_my_task_queue",
219
+ "label": "My Queue",
220
+ "description": "View your own task queue: pending tasks (FIFO order), the task you are currently executing, and completed tasks. Use this to check if you have unfinished work.",
221
+ "parameters": {
222
+ "type": "object",
223
+ "properties": {}
224
+ }
225
+ },
226
+ {
227
+ "name": "get_queue_overview",
228
+ "label": "Queue Overview",
229
+ "description": "(Lead only) Real-time overview of every team member: status (idle/busy), current task, pending queue length, completed count. Use this to make optimal scheduling and rebalancing decisions.",
230
+ "parameters": {
231
+ "type": "object",
232
+ "properties": {}
233
+ }
234
+ },
235
+ {
236
+ "name": "reassign_task",
237
+ "label": "Reassign Task",
238
+ "description": "(Lead only) Move a pending (not yet started) or failed task from one worker to another. Use for load rebalancing or when a worker is stuck. The old worker's queued delivery is revoked automatically.",
239
+ "parameters": {
240
+ "type": "object",
241
+ "properties": {
242
+ "task_id": {
243
+ "type": "string",
244
+ "description": "Task ID to move"
245
+ },
246
+ "to_agent_id": {
247
+ "type": "string",
248
+ "description": "Worker agent ID to receive the task"
249
+ }
250
+ },
251
+ "required": [
252
+ "task_id",
253
+ "to_agent_id"
254
+ ]
255
+ }
256
+ },
257
+ {
258
+ "name": "update_task",
259
+ "label": "Update Task",
260
+ "description": "(Lead only) Modify the title/description of a pending (queued, not started) task. The assignee's queued delivery is refreshed with the new content automatically.",
261
+ "parameters": {
262
+ "type": "object",
263
+ "properties": {
264
+ "task_id": {
265
+ "type": "string",
266
+ "description": "Task ID to update"
267
+ },
268
+ "title": {
269
+ "type": "string",
270
+ "description": "New title (optional)"
271
+ },
272
+ "description": {
273
+ "type": "string",
274
+ "description": "New description (optional)"
275
+ }
276
+ },
277
+ "required": [
278
+ "task_id"
279
+ ]
280
+ }
281
+ },
282
+ {
283
+ "name": "cancel_task",
284
+ "label": "Cancel Task",
285
+ "description": "Cancel a task and remove it from the assignee's queue (lead can cancel any; assignee can cancel own). Pending queued deliveries are revoked automatically.",
286
+ "parameters": {
287
+ "type": "object",
288
+ "properties": {
289
+ "task_id": {
290
+ "type": "string",
291
+ "description": "Task ID to cancel"
292
+ }
293
+ },
294
+ "required": [
295
+ "task_id"
296
+ ]
297
+ }
298
+ },
299
+ {
300
+ "name": "search_memory",
301
+ "label": "Search Memory",
302
+ "description": "Search your persistent memory (hybrid keyword+semantic retrieval over your private memories and the channel's shared team memories). Results may include: your task history, the TEAM CHRONICLE (团队编年史 = rolling log of everything the team finished), past SESSION COMPACTION SUMMARIES (会话压缩摘要 = conclusions from earlier context windows), monthly reflections (作业反思), and shared conventions. Use this ANY TIME you need prior context: before starting a task, when you suspect relevant past work exists, or when the injected memory hints/brief mention something you need details on. Pass a focused query describing what you want to remember.",
303
+ "parameters": {
304
+ "type": "object",
305
+ "properties": {
306
+ "query": {
307
+ "type": "string",
308
+ "description": "What you want to recall, e.g. \"数据库连接池配置结论\" or \"previous deployment checklist\""
309
+ },
310
+ "scope": {
311
+ "type": "string",
312
+ "enum": [
313
+ "auto",
314
+ "private",
315
+ "shared"
316
+ ],
317
+ "description": "Which memory domain to search: \"auto\" = your private + channel shared (default), \"private\" = only your own, \"shared\" = only channel-wide shared memories"
318
+ },
319
+ "limit": {
320
+ "type": "number",
321
+ "description": "Max results (default 5, max 20)"
322
+ }
323
+ },
324
+ "required": [
325
+ "query"
326
+ ]
327
+ }
328
+ },
329
+ {
330
+ "name": "save_memory",
331
+ "label": "Save Memory",
332
+ "description": "Persist a distilled, reusable insight into memory for future tasks. scope=\"private\" saves to YOUR personal memory (only you recall it); scope=\"shared\" saves to the CHANNEL shared memory visible to ALL teammates (use for conclusions, conventions, or knowledge the whole team benefits from — not task-specific minutiae). Distill before saving: title = short topic, content = the reusable conclusion. Use a stable dedup_key to update an existing memory instead of duplicating. NOTE: the platform already auto-archives task outcomes, team results, the team chronicle, and session compaction summaries — never save whole task logs or raw session transcripts.",
333
+ "parameters": {
334
+ "type": "object",
335
+ "properties": {
336
+ "title": {
337
+ "type": "string",
338
+ "description": "Short topic title, e.g. \"API 网关限流方案结论\""
339
+ },
340
+ "content": {
341
+ "type": "string",
342
+ "description": "The distilled reusable knowledge/conclusion (plain text)"
343
+ },
344
+ "importance": {
345
+ "type": "number",
346
+ "description": "0-1 importance (default 0.7 private / 0.85 shared)"
347
+ },
348
+ "scope": {
349
+ "type": "string",
350
+ "enum": [
351
+ "private",
352
+ "shared"
353
+ ],
354
+ "description": "\"private\" = your memory only; \"shared\" = channel-wide shared memory for all teammates"
355
+ },
356
+ "dedup_key": {
357
+ "type": "string",
358
+ "description": "Stable key for idempotent update (same key overwrites instead of duplicating)"
359
+ }
360
+ },
361
+ "required": [
362
+ "title",
363
+ "content",
364
+ "scope"
365
+ ]
366
+ }
367
+ },
368
+ {
369
+ "name": "create_team_agent",
370
+ "label": "Create Team Agent",
371
+ "description": "(Lead only) Create a NEW worker agent and add it to your channel's team, on the fly. Use ONLY when all workers stay busy with a persistent backlog, or when a task clearly needs a specialist that doesn't exist yet — not for routine tasks the current team can handle. The new member starts idle, appears in list_team_agents immediately, and can receive dispatch_task assignments right away. Give it a clear name and a system_prompt describing its specialty.",
372
+ "parameters": {
373
+ "type": "object",
374
+ "properties": {
375
+ "name": {
376
+ "type": "string",
377
+ "description": "Short, descriptive member name, e.g. \"db-migrator\" or \"test-writer\""
378
+ },
379
+ "harness": {
380
+ "type": "string",
381
+ "enum": [
382
+ "omp",
383
+ "mock",
384
+ "claude"
385
+ ],
386
+ "description": "Agent harness: \"omp\" = full LLM agent with native work tools (default, use this for real work), \"mock\" = scripted test agent, \"claude\" = claude harness"
387
+ },
388
+ "system_prompt": {
389
+ "type": "string",
390
+ "description": "System prompt prefix defining this member's specialty, working style, and conventions (maps to its systemPromptPrefix config)"
391
+ },
392
+ "reason": {
393
+ "type": "string",
394
+ "description": "Why this member is being added (shown to the user in the team event timeline)"
395
+ }
396
+ },
397
+ "required": [
398
+ "name"
399
+ ]
400
+ }
401
+ },
402
+ {
403
+ "name": "update_team_agent",
404
+ "label": "Update Team Agent",
405
+ "description": "(Lead only) Update an existing team member (worker): rename it, revise its system prompt (e.g. to specialize or correct its behavior), or enable/disable it. The member's runtime reloads with the new config on its next assignment. You cannot update yourself.",
406
+ "parameters": {
407
+ "type": "object",
408
+ "properties": {
409
+ "agent_id": {
410
+ "type": "string",
411
+ "description": "ID of the worker agent to update (from list_team_agents)"
412
+ },
413
+ "name": {
414
+ "type": "string",
415
+ "description": "New name (optional)"
416
+ },
417
+ "system_prompt": {
418
+ "type": "string",
419
+ "description": "New system prompt prefix defining its specialty/conventions (optional)"
420
+ },
421
+ "enabled": {
422
+ "type": "boolean",
423
+ "description": "true = activate member, false = disable member (disabled members receive no new tasks; default true)"
424
+ },
425
+ "reason": {
426
+ "type": "string",
427
+ "description": "Why this change is made (shown in the team event timeline)"
428
+ }
429
+ },
430
+ "required": [
431
+ "agent_id"
432
+ ]
433
+ }
434
+ },
435
+ {
436
+ "name": "remove_team_agent",
437
+ "label": "Remove Team Agent",
438
+ "description": "(Lead only) Remove a worker from your channel's team. Its queued tasks are automatically re-dispatched to the remaining worker with the shortest queue (or failed for retry if it was mid-execution), so no work is lost — but the member's context is. Use ONLY for sustained idle surplus or persistent underperformance; never as an experiment, and avoid removing members with active work. You cannot remove yourself.",
439
+ "parameters": {
440
+ "type": "object",
441
+ "properties": {
442
+ "agent_id": {
443
+ "type": "string",
444
+ "description": "ID of the worker agent to remove"
445
+ },
446
+ "reason": {
447
+ "type": "string",
448
+ "description": "Why this member is removed (shown in the team event timeline)"
449
+ }
450
+ },
451
+ "required": [
452
+ "agent_id"
453
+ ]
454
+ }
455
+ },
456
+ {
457
+ "name": "refuse_task",
458
+ "label": "Refuse Task",
459
+ "description": "Reject a task assigned to you because it is outside your capability or work scope (wrong recipient, unrelated domain, or missing prerequisites). The task is marked FAILED with your reason and a rejection notice is immediately sent back to the dispatcher (task creator, or the channel lead), who should reassign it to a fitting member. Use this INSTEAD of silently ignoring the task or doing unrelated work; do NOT use it for tasks you are able to do, and do NOT use cancel_task for refusals.",
460
+ "parameters": {
461
+ "type": "object",
462
+ "properties": {
463
+ "task_id": {
464
+ "type": "string",
465
+ "description": "ID of the task you are refusing (must be assigned to you)"
466
+ },
467
+ "reason": {
468
+ "type": "string",
469
+ "description": "Why the task is out of your scope: capability mismatch / wrong recipient / prerequisites missing. Be specific so the dispatcher can reassign properly."
470
+ }
471
+ },
472
+ "required": [
473
+ "task_id",
474
+ "reason"
475
+ ]
476
+ }
477
+ },
478
+ {
479
+ "name": "my_industrial_nodes",
480
+ "label": "My Industrial Nodes",
481
+ "description": "列出你绑定的全部数采/数控节点及其物理含义(参数含义/单位/安全量程/活动配方工艺窗口/控制模式)。在进行任何工业操作前必须先调用本工具理解节点语义与设定规则。",
482
+ "parameters": {
483
+ "type": "object",
484
+ "properties": {}
485
+ }
486
+ },
487
+ {
488
+ "name": "dcw_control",
489
+ "label": "DCW Control",
490
+ "description": "对绑定的数控节点下发工艺设定值(真实物理量纲)。仅限你有权控制的节点;设定值会被安全量程与活动配方工艺窗口联锁校验,越窗直接拒绝。手动确认模式下需等待用户批准,用户备注会随结果返回。下发前先调用 my_industrial_nodes 理解节点物理含义。",
491
+ "parameters": {
492
+ "type": "object",
493
+ "properties": {
494
+ "node_id": {
495
+ "type": "string",
496
+ "description": "数控节点 id(见 my_industrial_nodes)"
497
+ },
498
+ "value": {
499
+ "type": "number",
500
+ "description": "目标设定值(真实物理量纲,如 ℃)"
501
+ },
502
+ "hypothesis": {
503
+ "type": "string",
504
+ "description": "本次调参假设(入优化记录档案):目标 + 预期效果 + 观察计划,如「提温 1℃ 预期张力上升 2%,5 分钟后复测」"
505
+ },
506
+ "task_id": {
507
+ "type": "string",
508
+ "description": "关联的优化任务 id(可选,入优化记录档案)"
509
+ }
510
+ },
511
+ "required": [
512
+ "node_id",
513
+ "value"
514
+ ]
515
+ }
516
+ },
517
+ {
518
+ "name": "dcw_read",
519
+ "label": "DCW Read",
520
+ "description": "读取绑定的数控节点的 PLC 当前值(读写集成的读半边)。返回 PLC 实时读数(经标定解码的物理量纲)与设定值对照;用于下发前取证、下发后复核设定是否生效。读取是被动观测,不影响控制状态,也不需要审批。",
521
+ "parameters": {
522
+ "type": "object",
523
+ "properties": {
524
+ "node_id": {
525
+ "type": "string",
526
+ "description": "数控节点 id(见 my_industrial_nodes)"
527
+ }
528
+ },
529
+ "required": [
530
+ "node_id"
531
+ ]
532
+ }
533
+ },
534
+ {
535
+ "name": "daq_query",
536
+ "label": "DAQ Query",
537
+ "description": "从时序数据库检索你绑定的数采节点的历史/实时数据。支持按产线/产品/配方/时间窗/降采样多维过滤(产品/配方过滤基于逐样本打标,可精确取某批次数据);返回结果携带物理含义(参数语义/单位/量程/统计摘要/最近序列)。",
538
+ "parameters": {
539
+ "type": "object",
540
+ "properties": {
541
+ "node_id": {
542
+ "type": "string",
543
+ "description": "限定单个数采节点 id(缺省 = 全部绑定节点)"
544
+ },
545
+ "line_id": {
546
+ "type": "string",
547
+ "description": "按产线过滤(数据归属产线)"
548
+ },
549
+ "product_id": {
550
+ "type": "string",
551
+ "description": "按产品过滤(逐样本打标)"
552
+ },
553
+ "recipe_id": {
554
+ "type": "string",
555
+ "description": "按配方/批次过滤(逐样本打标)"
556
+ },
557
+ "last_minutes": {
558
+ "type": "number",
559
+ "description": "最近 N 分钟(缺省 30)"
560
+ },
561
+ "from_ms": {
562
+ "type": "number",
563
+ "description": "起始 epoch ms(与 to_ms 配合,优先于 last_minutes)"
564
+ },
565
+ "to_ms": {
566
+ "type": "number",
567
+ "description": "结束 epoch ms"
568
+ },
569
+ "bucket_ms": {
570
+ "type": "number",
571
+ "description": "时间间隔(降采样桶宽 ms):缺省 {queryDefaultBucketMs}(15s);可调,下限 {queryMinBucketMs}。不传即用缺省;系统配置变更后以新值为准"
572
+ },
573
+ "limit": {
574
+ "type": "number",
575
+ "description": "返回点数上限(缺省 500)"
576
+ }
577
+ }
578
+ }
579
+ },
580
+ {
581
+ "name": "dcw_judge",
582
+ "label": "DCW Judge",
583
+ "description": "对你发起的优化记录(调控 step)落判定。keep=已验证经验(配方可标 lastGood);rollback=判定应回退(判定入册后必须再调 dcw_rollback 执行,判定不自动改 PLC);uncertain=证据不足保持观察。判定必须引用数采证据(daq_query 窗口数据),禁止无证据判定。",
584
+ "parameters": {
585
+ "type": "object",
586
+ "properties": {
587
+ "record_id": {
588
+ "type": "string",
589
+ "description": "优化记录 id(dcw_control 下发成功后返回)"
590
+ },
591
+ "verdict": {
592
+ "type": "string",
593
+ "description": "判定结论:keep / rollback / uncertain",
594
+ "enum": [
595
+ "keep",
596
+ "rollback",
597
+ "uncertain"
598
+ ]
599
+ },
600
+ "reason": {
601
+ "type": "string",
602
+ "description": "判定理由(必须引用具体数值/时间窗证据)"
603
+ }
604
+ },
605
+ "required": [
606
+ "record_id",
607
+ "verdict",
608
+ "reason"
609
+ ]
610
+ }
611
+ },
612
+ {
613
+ "name": "dcw_rollback",
614
+ "label": "DCW Rollback",
615
+ "description": "执行参数回退(经与下发相同的安全门控,回退本身入册可审计)。record_id=回退你自己发起的优化记录到其设定前值;node_id=单步撤销到最近稳定锚。回退后必须 daq_query 复测确认恢复。冷却期内同向重写/重复回退会被拒绝。",
616
+ "parameters": {
617
+ "type": "object",
618
+ "properties": {
619
+ "record_id": {
620
+ "type": "string",
621
+ "description": "要回退的优化记录 id(与 node_id 二选一)"
622
+ },
623
+ "node_id": {
624
+ "type": "string",
625
+ "description": "节点单步回退(撤销栈栈顶;与 record_id 二选一)"
626
+ },
627
+ "to": {
628
+ "type": "string",
629
+ "description": "可选:指定目标锚 id(dcw_journal 可查)"
630
+ }
631
+ }
632
+ }
633
+ },
634
+ {
635
+ "name": "dcw_journal",
636
+ "label": "DCW Journal",
637
+ "description": "查询参数变更史与优化记录(在册审计):谁/何时/从多少到多少/判定结论/假设声明。优化前先读史可避免重复试错;回退定位也在此查。",
638
+ "parameters": {
639
+ "type": "object",
640
+ "properties": {
641
+ "node_id": {
642
+ "type": "string",
643
+ "description": "限定数控节点 id(仅限自己绑定的节点)"
644
+ },
645
+ "recipe_id": {
646
+ "type": "string",
647
+ "description": "按配方过滤优化记录"
648
+ },
649
+ "limit": {
650
+ "type": "number",
651
+ "description": "返回条数上限(缺省 20,最大 100)"
652
+ }
653
+ }
654
+ }
655
+ },
656
+ {
657
+ "name": "send_cross_channel_message",
658
+ "label": "Cross-Channel Message",
659
+ "description": "[Leader only] Send a message to the LEADER of another channel, so the two teams can collaborate without being siloed. The message lands directly in the target channel leader mailbox; that leader will read your request and act on it (dispatch tasks in their channel, gather info, etc.) and can reply to you via the mailbox. Params: to_channel_id accepts the target channel id OR its exact name; message is your request to the other leader (state your need, deadline and what you expect back); require_reply=true to demand a response. Only channel leaders may call this tool - workers will be rejected. When replying to a cross-channel request you received, use this same tool addressed to the requester channel.",
660
+ "parameters": {
661
+ "type": "object",
662
+ "properties": {
663
+ "to_channel_id": {
664
+ "type": "string",
665
+ "description": "Target channel id or exact name (must be another channel, not your own)"
666
+ },
667
+ "message": {
668
+ "type": "string",
669
+ "description": "Request text for the target channel leader: what you need, why, and what to return"
670
+ },
671
+ "require_reply": {
672
+ "type": "boolean",
673
+ "description": "true = demand the target leader reply with their result/answer"
674
+ }
675
+ },
676
+ "required": [
677
+ "to_channel_id",
678
+ "message"
679
+ ]
680
+ }
681
+ },
682
+ {
683
+ "name": "list_other_teams",
684
+ "label": "List Other Teams",
685
+ "description": "[Leader only] Overview of the OTHER teams (channels) in this workspace: each team name, description, lead, its in-progress scenario tasks, recently completed tasks, and how many shared memories it has (shared_memories > 0 means searchable knowledge exists - use search_other_teams_memory with that team). Decision flow: found knowledge -> reuse it directly; relevant work in progress but no knowledge yet -> message their leader via send_cross_channel_message; nothing -> consider whether your request justifies starting collaboration. Workers cannot call this tool.",
686
+ "parameters": {
687
+ "type": "object",
688
+ "properties": {},
689
+ "required": []
690
+ }
691
+ },
692
+ {
693
+ "name": "search_other_teams_memory",
694
+ "label": "Search Other Teams Memory",
695
+ "description": "[All members] Read-only search across the SHARED memory of other teams (channels) in this workspace - what other teams have learned/concluded/done. Use it to reuse existing knowledge instead of asking for it: if you find relevant results, apply them directly; if nothing relevant exists but the other team is working on it, ask your leader to message that team leader via send_cross_channel_message. Results are attributed to their team.",
696
+ "parameters": {
697
+ "type": "object",
698
+ "properties": {
699
+ "query": {
700
+ "type": "string",
701
+ "description": "What to look for (keywords of the knowledge/conclusion)"
702
+ },
703
+ "limit": {
704
+ "type": "number",
705
+ "description": "Max results (default 5)"
706
+ }
707
+ },
708
+ "required": [
709
+ "query"
710
+ ]
711
+ }
712
+ },
713
+ {
714
+ "name": "daq_frames",
715
+ "label": "DAQ Frames",
716
+ "description": "Query multi-modal DAQ frames for your BOUND daq nodes: multi-point profiles (thickness scanners, profile scanners — returns point-count summary, a point preview and derived metrics) and camera image frames (CCD — returns resolution, object reference and derived metrics like brightness/contrast; pixels are NOT loaded into context, view them in the frontend gallery). Supports kind=vector|image filter and time windows. Use BEFORE judging surface quality or profile measurements.",
717
+ "parameters": {
718
+ "type": "object",
719
+ "properties": {
720
+ "node_id": {
721
+ "type": "string",
722
+ "description": "Limit to one bound daq node id (optional; default all your bound daq nodes)"
723
+ },
724
+ "line_id": {
725
+ "type": "string",
726
+ "description": "Filter by line id (can only narrow, never widen your access)"
727
+ },
728
+ "kind": {
729
+ "type": "string",
730
+ "enum": [
731
+ "vector",
732
+ "image"
733
+ ],
734
+ "description": "Frame kind filter (optional)"
735
+ },
736
+ "last_minutes": {
737
+ "type": "number",
738
+ "description": "Time window in minutes back from now (default 30)"
739
+ },
740
+ "from_ms": {
741
+ "type": "number",
742
+ "description": "Window start (epoch ms; overrides last_minutes)"
743
+ },
744
+ "to_ms": {
745
+ "type": "number",
746
+ "description": "Window end (epoch ms; default now)"
747
+ },
748
+ "limit": {
749
+ "type": "number",
750
+ "description": "Max frames per node (default 20, max 100)"
751
+ }
752
+ }
753
+ }
754
+ },
755
+ {
756
+ "name": "ops_log",
757
+ "label": "Ops Log",
758
+ "description": "查询你负责产线的运维日志(数控下发/优化判定/回退/配方下发/产线事件,新→旧)。来源区分 Agent/用户/系统:Agent 的操作者格式为「Channel名/成员名」。用于作业前后自查:你对节点做过哪些操作、他人或系统做过哪些干预。",
759
+ "parameters": {
760
+ "type": "object",
761
+ "properties": {
762
+ "line_id": {
763
+ "type": "string",
764
+ "description": "限定产线 id(须为你绑定节点所属产线;缺省=全部负责产线)"
765
+ },
766
+ "node_id": {
767
+ "type": "string",
768
+ "description": "限定数控/数采节点 id(须为你绑定的节点)"
769
+ },
770
+ "kind": {
771
+ "type": "string",
772
+ "description": "按分类过滤:write(下发)/recipe(配方)/rollback(回退)/daq(采集)/line(产线)"
773
+ },
774
+ "actor_kind": {
775
+ "type": "string",
776
+ "description": "按来源过滤:agent/user/system"
777
+ },
778
+ "minutes": {
779
+ "type": "number",
780
+ "description": "回看窗口(分钟,缺省 1440=24 小时)"
781
+ },
782
+ "limit": {
783
+ "type": "number",
784
+ "description": "返回条数上限(缺省 20,最大 100)"
785
+ },
786
+ "mine": {
787
+ "type": "boolean",
788
+ "description": "true=只看你自己发起的操作"
789
+ }
790
+ }
791
+ }
792
+ },
793
+ {
794
+ "name": "recipe_log",
795
+ "label": "Recipe Change Log",
796
+ "description": "查询你负责产线的 Recipe 变更史:配方一键下发(recipe.apply)、优化开窗、判定、回退执行(新→旧)。你据此知道配方层面对当前节点做过哪些下发变更、由谁执行、是否已回退。节点级参数值逐笔历史用 dcw_journal。",
797
+ "parameters": {
798
+ "type": "object",
799
+ "properties": {
800
+ "line_id": {
801
+ "type": "string",
802
+ "description": "限定产线 id(须为你绑定节点所属产线;缺省=全部负责产线)"
803
+ },
804
+ "recipe_id": {
805
+ "type": "string",
806
+ "description": "按配方 id 过滤"
807
+ },
808
+ "minutes": {
809
+ "type": "number",
810
+ "description": "回看窗口(分钟,缺省 1440=24 小时)"
811
+ },
812
+ "limit": {
813
+ "type": "number",
814
+ "description": "返回条数上限(缺省 20,最大 100)"
815
+ }
816
+ }
817
+ }
818
+ }
819
+ ]