agentworkshop 0.5.5 → 0.5.7

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 (50) hide show
  1. package/.AgentWorkShop/prompts/compaction-hints.md +9 -0
  2. package/.AgentWorkShop/prompts/host-tools.json +695 -630
  3. package/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
  4. package/.AgentWorkShop/prompts/system-manual.md +6 -1
  5. package/.output/.AgentWorkShop/prompts/compaction-hints.md +9 -0
  6. package/.output/.AgentWorkShop/prompts/host-tools.json +695 -630
  7. package/.output/.AgentWorkShop/prompts/peer-reply-cross-channel.md +10 -0
  8. package/.output/.AgentWorkShop/prompts/system-manual.md +6 -1
  9. package/.output/nitro.json +1 -1
  10. package/.output/public/_nuxt/builds/latest.json +1 -1
  11. package/.output/public/_nuxt/builds/meta/02278199-eeea-4f96-882a-94c5408c6cb6.json +1 -0
  12. package/.output/server/chunks/_/nitro.mjs +2188 -1324
  13. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  14. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs +5 -2
  15. package/.output/server/chunks/routes/api/workshop/agent-tools/invoke.post.mjs.map +1 -1
  16. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs +25 -3
  17. package/.output/server/chunks/routes/api/workshop/channels/_id/index3.post.mjs.map +1 -1
  18. package/.output/server/package.json +1 -1
  19. package/package.json +1 -1
  20. package/scripts/_dbg-cross-channel-e2e.mjs +157 -0
  21. package/scripts/_dbg-cross-team-visibility-e2e.mjs +129 -0
  22. package/scripts/test-context-governor.ts +176 -0
  23. package/scripts/test-memory-brief-chronicle.ts +180 -0
  24. package/scripts/test-memory-dynamic.ts +3 -1
  25. package/scripts/test-memory-rrf-mmr.ts +114 -0
  26. package/server/api/workshop/agent-tools/invoke.post.ts +8 -1
  27. package/server/api/workshop/channels/[id]/messages/index.post.ts +26 -1
  28. package/server/api/workshop/ws.ts +1 -0
  29. package/server/data/daqs.json +35 -13
  30. package/server/data/dcw-lines.json +14 -0
  31. package/server/data/dcw-products.json +14 -0
  32. package/server/data/dcw-recipes.json +28 -0
  33. package/server/data/dcw-rollback.json +122 -1
  34. package/server/data/dcw-runs.json +54 -36
  35. package/server/data/dcw-writes.json +60 -0
  36. package/server/data/dcws.json +42 -0
  37. package/server/data/line-runs.json +32 -22
  38. package/server/services/workshop/agents/adapters/omp-rpc-client.ts +65 -0
  39. package/server/services/workshop/agents/agent-interface.ts +44 -1
  40. package/server/services/workshop/agents/mock-agent.ts +12 -0
  41. package/server/services/workshop/agents/omp-agent.ts +304 -8
  42. package/server/services/workshop/db/database.ts +16 -1
  43. package/server/services/workshop/db/memory.repo.ts +40 -2
  44. package/server/services/workshop/prompts/loader.ts +6 -5
  45. package/server/services/workshop/runtime/agent-runtime.ts +52 -6
  46. package/server/services/workshop/runtime/channel-runtime.ts +14 -6
  47. package/server/services/workshop/runtime/manager.ts +314 -3
  48. package/server/services/workshop/runtime/memory.ts +313 -78
  49. package/server/services/workshop/types/task.ts +14 -0
  50. package/.output/public/_nuxt/builds/meta/f2f649c5-fd3b-4507-a3a1-8b4a194de72d.json +0 -1
@@ -7,7 +7,7 @@
7
7
  "productId": "pd-3ad54846",
8
8
  "productName": "光学膜 BOPP",
9
9
  "startedAt": "2026-08-31T16:20:13.707Z",
10
- "taggedSamples": 34566
10
+ "taggedSamples": 34570
11
11
  },
12
12
  {
13
13
  "lineId": "ln-c377a6bf",
@@ -17,7 +17,7 @@
17
17
  "productId": "pd-7e69e0ee",
18
18
  "productName": "警告验证产品-k2xh",
19
19
  "startedAt": "2026-09-01T03:23:18.233Z",
20
- "taggedSamples": 14092
20
+ "taggedSamples": 14094
21
21
  },
22
22
  {
23
23
  "lineId": "ln-9224d3d7",
@@ -27,7 +27,7 @@
27
27
  "productId": "pd-910c0fa8",
28
28
  "productName": "新协议产品-9xhn",
29
29
  "startedAt": "2026-09-01T05:59:24.062Z",
30
- "taggedSamples": 17074
30
+ "taggedSamples": 17076
31
31
  },
32
32
  {
33
33
  "lineId": "ln-386c53ed",
@@ -37,7 +37,7 @@
37
37
  "productId": "pd-2d4f9357",
38
38
  "productName": "新协议产品-6ofk",
39
39
  "startedAt": "2026-09-01T06:05:53.063Z",
40
- "taggedSamples": 17363
40
+ "taggedSamples": 17365
41
41
  },
42
42
  {
43
43
  "lineId": "ln-5957f6db",
@@ -47,7 +47,7 @@
47
47
  "productId": "pd-a3ed5047",
48
48
  "productName": "新协议产品-x4hd",
49
49
  "startedAt": "2026-09-01T06:09:02.148Z",
50
- "taggedSamples": 16949
50
+ "taggedSamples": 16951
51
51
  },
52
52
  {
53
53
  "lineId": "ln-9ec42f08",
@@ -57,7 +57,7 @@
57
57
  "productId": "pd-5de729c0",
58
58
  "productName": "新协议产品-teti",
59
59
  "startedAt": "2026-09-01T06:13:44.315Z",
60
- "taggedSamples": 16928
60
+ "taggedSamples": 16930
61
61
  },
62
62
  {
63
63
  "lineId": "ln-69e37924",
@@ -67,7 +67,7 @@
67
67
  "productId": "pd-45eb8d43",
68
68
  "productName": "新协议产品-fg8t",
69
69
  "startedAt": "2026-09-01T06:16:47.469Z",
70
- "taggedSamples": 16961
70
+ "taggedSamples": 16963
71
71
  },
72
72
  {
73
73
  "lineId": "ln-c269e692",
@@ -77,7 +77,7 @@
77
77
  "productId": "pd-b3bd0191",
78
78
  "productName": "新协议产品-w2sp",
79
79
  "startedAt": "2026-09-01T06:56:05.893Z",
80
- "taggedSamples": 17012
80
+ "taggedSamples": 17014
81
81
  },
82
82
  {
83
83
  "lineId": "ln-229d1637",
@@ -87,7 +87,7 @@
87
87
  "productId": "pd-06b896f9",
88
88
  "productName": "新协议产品-lp4h",
89
89
  "startedAt": "2026-09-01T06:57:29.288Z",
90
- "taggedSamples": 16884
90
+ "taggedSamples": 16886
91
91
  },
92
92
  {
93
93
  "lineId": "ln-9546f91f",
@@ -97,7 +97,7 @@
97
97
  "productId": "pd-53e55078",
98
98
  "productName": "新协议产品-jri6",
99
99
  "startedAt": "2026-09-01T07:00:25.059Z",
100
- "taggedSamples": 16307
100
+ "taggedSamples": 16309
101
101
  },
102
102
  {
103
103
  "lineId": "ln-087aad5b",
@@ -107,7 +107,7 @@
107
107
  "productId": "pd-e7e969af",
108
108
  "productName": "新协议产品-4c2d",
109
109
  "startedAt": "2026-09-01T07:09:07.307Z",
110
- "taggedSamples": 15299
110
+ "taggedSamples": 15301
111
111
  },
112
112
  {
113
113
  "lineId": "ln-97d44f8a",
@@ -117,7 +117,7 @@
117
117
  "productId": "pd-28a3ab2c",
118
118
  "productName": "新协议产品-b2ni",
119
119
  "startedAt": "2026-09-01T07:13:44.912Z",
120
- "taggedSamples": 15148
120
+ "taggedSamples": 15150
121
121
  },
122
122
  {
123
123
  "lineId": "ln-a9551770",
@@ -127,7 +127,7 @@
127
127
  "productId": "pd-0c6a64c8",
128
128
  "productName": "新协议产品-uwkf",
129
129
  "startedAt": "2026-09-01T07:15:40.113Z",
130
- "taggedSamples": 14793
130
+ "taggedSamples": 14795
131
131
  },
132
132
  {
133
133
  "lineId": "ln-844ad82f",
@@ -137,7 +137,7 @@
137
137
  "productId": "pd-6932b24f",
138
138
  "productName": "新协议产品-kk6l",
139
139
  "startedAt": "2026-09-01T09:06:55.728Z",
140
- "taggedSamples": 12948
140
+ "taggedSamples": 12950
141
141
  },
142
142
  {
143
143
  "lineId": "ln-af002514",
@@ -147,7 +147,7 @@
147
147
  "productId": "pd-6348a595",
148
148
  "productName": "0.8mm 光学膜",
149
149
  "startedAt": "2026-09-01T14:06:28.766Z",
150
- "taggedSamples": 5772
150
+ "taggedSamples": 5780
151
151
  },
152
152
  {
153
153
  "lineId": "ln-0eccf6ba",
@@ -157,7 +157,7 @@
157
157
  "productId": "pd-4b71be77",
158
158
  "productName": "哨兵产品-mtjku36w",
159
159
  "startedAt": "2026-09-02T04:09:11.482Z",
160
- "taggedSamples": 1213
160
+ "taggedSamples": 1215
161
161
  },
162
162
  {
163
163
  "lineId": "ln-e984246e",
@@ -167,7 +167,7 @@
167
167
  "productId": "pd-bb1e0bed",
168
168
  "productName": "产品C-mtjkwyhu",
169
169
  "startedAt": "2026-09-02T04:11:26.583Z",
170
- "taggedSamples": 1212
170
+ "taggedSamples": 1214
171
171
  },
172
172
  {
173
173
  "lineId": "ln-1fe0b5bc",
@@ -177,7 +177,7 @@
177
177
  "productId": "pd-9f2d9507",
178
178
  "productName": "产品D-mtjkzcfr",
179
179
  "startedAt": "2026-09-02T04:13:17.902Z",
180
- "taggedSamples": 1211
180
+ "taggedSamples": 1213
181
181
  },
182
182
  {
183
183
  "lineId": "ln-d826473e",
@@ -187,7 +187,7 @@
187
187
  "productId": "pd-d230255e",
188
188
  "productName": "产品E-mtjl43pv",
189
189
  "startedAt": "2026-09-02T04:16:59.891Z",
190
- "taggedSamples": 1210
190
+ "taggedSamples": 1212
191
191
  },
192
192
  {
193
193
  "lineId": "ln-156abb71",
@@ -197,7 +197,7 @@
197
197
  "productId": "pd-6065b4ba",
198
198
  "productName": "产品F-mtjl60qf",
199
199
  "startedAt": "2026-09-02T04:18:29.340Z",
200
- "taggedSamples": 1209
200
+ "taggedSamples": 1211
201
201
  },
202
202
  {
203
203
  "lineId": "ln-bac43927",
@@ -207,7 +207,7 @@
207
207
  "productId": "pd-52f54e33",
208
208
  "productName": "产品G-mtjl98nl",
209
209
  "startedAt": "2026-09-02T04:20:59.682Z",
210
- "taggedSamples": 1208
210
+ "taggedSamples": 1210
211
211
  },
212
212
  {
213
213
  "lineId": "ln-f223008a",
@@ -217,6 +217,16 @@
217
217
  "productId": "pd-d919d4bf",
218
218
  "productName": "产品-mtjo000v",
219
219
  "startedAt": "2026-09-02T05:37:50.743Z",
220
- "taggedSamples": 1207
220
+ "taggedSamples": 1209
221
+ },
222
+ {
223
+ "lineId": "ln-c1ef6c0d",
224
+ "runId": "rr-4549422d",
225
+ "recipeId": "rc-ed3e066e",
226
+ "recipeName": "̽���䷽",
227
+ "productId": "pd-efb05c40",
228
+ "productName": "���̽��Ʒ",
229
+ "startedAt": "2026-09-02T11:55:28.775Z",
230
+ "taggedSamples": 0
221
231
  }
222
232
  ]
@@ -27,6 +27,27 @@ export type RpcCommand
27
27
  | { id?: string, type: 'set_model', provider: string, modelId: string }
28
28
  | { id?: string, type: 'get_state' }
29
29
  | { id?: string, type: 'new_session' }
30
+ // ===== 上下文治理(70% 压缩环;协议权威 omp://rpc.md)=====
31
+ | { id?: string, type: 'get_session_stats' }
32
+ | { id?: string, type: 'compact', customInstructions?: string }
33
+ | { id?: string, type: 'set_auto_compaction', enabled: boolean }
34
+
35
+ /** compaction 结果(compaction_end 事件 / compact 响应 data.result 共用形状) */
36
+ export interface CompactionResult {
37
+ summary?: string
38
+ tokensBefore?: number
39
+ tokensAfter?: number
40
+ estimatedTokensAfter?: number
41
+ }
42
+
43
+ /** provider 用量(被动上下文跟踪源;message_update 等帧携带的累计值) */
44
+ export interface RpcUsage {
45
+ /** input tokens ≈ 当前上下文长度(本回合 LLM 调用的 prompt 规模) */
46
+ input: number
47
+ output?: number
48
+ cacheRead?: number
49
+ at: number
50
+ }
30
51
  /** host 工具定义(omp 端可见的工具 schema) */
31
52
  export interface RpcHostToolDefinition {
32
53
  name: string
@@ -137,6 +158,11 @@ export class OmpRpcClient {
137
158
  private readonly pending = new Map<string, PendingRequest>()
138
159
  private seq = 0
139
160
 
161
+ /** 被动上下文跟踪:最近一次帧携带的累计 provider usage(get_session_stats 不可用时的兜底源) */
162
+ private lastUsage: RpcUsage | null = null
163
+ /** 上下文窗口大小(外部经 get_state 探测后注入;null = 未知,percent 不可算) */
164
+ private contextWindow: number | null = null
165
+
140
166
  private readonly eventListeners = new Set<(event: AgentSessionEvent) => void>()
141
167
  /** 原始帧 tap(chunk 重组后的每一帧,含 response/host_tool_call/extension_ui_request) */
142
168
  private readonly rawFrameListeners = new Set<(frame: Record<string, unknown>) => void>()
@@ -157,6 +183,41 @@ export class OmpRpcClient {
157
183
  return !!this.child && !this.exited
158
184
  }
159
185
 
186
+ /** 注入上下文窗口大小(get_state 探测 model.contextWindow 后调用;幂等) */
187
+ setContextWindow(tokens: number): void {
188
+ if (Number.isFinite(tokens) && tokens > 0) this.contextWindow = tokens
189
+ }
190
+
191
+ /** 被动上下文用量快照(无探测 RPC;数据来自最近一次携带 usage 的帧) */
192
+ getContextUsage(): { tokens: number, contextWindow: number | null, percent: number | null } | null {
193
+ if (!this.lastUsage) return null
194
+ const window = this.contextWindow
195
+ return {
196
+ tokens: this.lastUsage.input,
197
+ contextWindow: window,
198
+ percent: window && window > 0 ? Math.min(1, this.lastUsage.input / window) : null,
199
+ }
200
+ }
201
+
202
+ /**
203
+ * 从帧中防御性提取累计 usage(顶层 frame.usage 或 frame.message.usage;
204
+ * input 兼容 input/inputTokens/promptTokens 命名;无有效 input 返回 null)。
205
+ */
206
+ private extractUsage(frame: Record<string, unknown>): RpcUsage | null {
207
+ const raw = (frame.usage ?? (frame.message as Record<string, unknown> | undefined)?.usage) as Record<string, unknown> | undefined
208
+ if (!raw || typeof raw !== 'object') return null
209
+ const input = Number(raw.input ?? raw.inputTokens ?? raw.promptTokens)
210
+ if (!Number.isFinite(input) || input <= 0) return null
211
+ const output = Number(raw.output ?? raw.outputTokens)
212
+ const cacheRead = Number(raw.cacheRead)
213
+ return {
214
+ input,
215
+ output: Number.isFinite(output) ? output : undefined,
216
+ cacheRead: Number.isFinite(cacheRead) ? cacheRead : undefined,
217
+ at: Date.now(),
218
+ }
219
+ }
220
+
160
221
  /**
161
222
  * OS 级存活校准(系统休眠/强杀后 exit 事件可能不达,alive 会失真):
162
223
  * 按 PID 探 OS 实际存在性,进程已死则收敛为已退出(与 exit 事件同路径:
@@ -366,6 +427,10 @@ export class OmpRpcClient {
366
427
  private dispatchFrame(frame: Record<string, unknown>): void {
367
428
  const type = frame.type as string
368
429
 
430
+ // 被动上下文跟踪:任何帧携带累计 usage 都刷新最近值(零额外请求)
431
+ const usage = this.extractUsage(frame)
432
+ if (usage) this.lastUsage = usage
433
+
369
434
  // 原始帧镜像(终端 hub;listener 异常不影响协议处理)
370
435
  for (const fn of this.rawFrameListeners) {
371
436
  try {
@@ -5,7 +5,7 @@
5
5
  * 权威契约见 docs/superpowers/plans/2026-08-13-agent-workshop-multi-agent.md 核心契约块。
6
6
  */
7
7
  import type { A2AMessage, A2AArtifact, A2AError, ChannelMail, Part } from '../types/a2a'
8
- import type { WorkspaceTask, AgentTaskQueueView, AgentStatusView } from '../types/task'
8
+ import type { WorkspaceTask, AgentTaskQueueView, AgentStatusView, AgentContextStats } from '../types/task'
9
9
 
10
10
  /** Agent 元信息:Channel 内成员声明(hook harness 类型与配置) */
11
11
  export interface AgentInfo {
@@ -59,6 +59,34 @@ export interface AgentWorkspace {
59
59
  cancelTask(taskId: string): Promise<WorkspaceTask>
60
60
  /** 点对点发消息给同事 */
61
61
  sendMessage(input: { toAgentId: string, parts: Part[], metadata?: Record<string, unknown> }): Promise<A2AMessage>
62
+ /**
63
+ * (仅 lead)跨 Channel 点对点:直投目标 channel 的 lead mailbox(沿用 mailbox/route 机制)。
64
+ * 权限:发送方必须是本 channel 的 lead;目标 channel 与本 channel 须同主且启用、有 lead。
65
+ */
66
+ sendCrossChannelMessage(input: { toChannelId: string, parts: Part[], requireReply?: boolean, inReplyTo?: string }): Promise<{
67
+ messageId: string
68
+ toChannelId: string
69
+ toChannelName: string
70
+ toLeadAgentId: string
71
+ }>
72
+ /** (仅 lead)其他团队概览:同主其余 channel 的场景任务(进行中/近期完成)——跨团队协同的观察面 */
73
+ listOtherTeams(): Promise<Array<{
74
+ channelId: string
75
+ name: string
76
+ description: string
77
+ leadName: string | null
78
+ activeTasks: Array<{ id: string, title: string, state: string }>
79
+ recentCompleted: Array<{ title: string }>
80
+ }>>
81
+ /** (全员)跨团队共享记忆检索:其他 channel 的 __team__ 公共域,只读,带团队归属 */
82
+ searchOtherTeamsMemory(input: { query: string, limit?: number }): Promise<Array<{
83
+ channelId: string
84
+ channelName: string
85
+ title: string
86
+ content: string
87
+ importance: number
88
+ createdAt: string
89
+ }>>
62
90
  /**
63
91
  * 拒绝指派给自己的任务(能力/范畴不匹配):任务置 FAILED(调度器改派他人),
64
92
  * 并向派发方(任务创建者,缺省 channel lead)回执拒绝原因。
@@ -91,6 +119,11 @@ export interface AgentWorkspace {
91
119
  * scope='private' → 本人记忆库;scope='shared' → Channel 公共记忆域(全员可检索)。
92
120
  */
93
121
  saveMemory(input: { title: string, content: string, importance?: number, scope: 'private' | 'shared', dedupKey?: string }): Promise<{ scope: 'private' | 'shared', dedupKey: string }>
122
+ /**
123
+ * 会话压缩摘要入库(harvest 桥;omp compaction 产出的会话摘要 → 本成员持久记忆)。
124
+ * 平台 70% 主动压缩与 omp 原生 auto-compaction 双路统一经此落库(episodic-session)。
125
+ */
126
+ recordSessionMemory?(input: { summary: string, tokensBefore?: number, tokensAfter?: number, reason?: string }): Promise<void>
94
127
  /** 订阅同事产出 */
95
128
  subscribe(input: { agentIds?: string[] }): Promise<void>
96
129
  /** (lead)在本 channel 内新建团队成员(worker):按需建模板并克隆为独立实例 */
@@ -216,4 +249,14 @@ export interface AgentInterface {
216
249
  * 探到进程已死时收敛为已退出,让在途回合归位、下一回合自动重生子进程。
217
250
  */
218
251
  reconcileProcess?(): void
252
+ /**
253
+ * 可选:harness 上下文用量快照(omp;被动缓存值,无探测 RPC)。
254
+ * 进程内 harness(mock/claude)不实现 → getStatus 不透出 context 字段。
255
+ */
256
+ getContextStats?(): AgentContextStats | null
257
+ /**
258
+ * 可选:回合落定后的后台钩子(post-settle 上下文压缩检查)。
259
+ * 实现方自守卫(仅回合间隙发起、异常不抛出);调用方 AgentRuntime 在信箱无排队消息时调用。
260
+ */
261
+ onTurnSettled?(): Promise<void>
219
262
  }
@@ -352,6 +352,18 @@ export class MockAgentImpl implements AgentInterface {
352
352
  const text = request.message.parts
353
353
  .map(p => ('text' in p ? p.text : 'data' in p ? JSON.stringify(p.data) : ''))
354
354
  .join('\n')
355
+ // 跨 Channel 来信:发送方不是本 channel 成员,回复须走 lead 级跨 Channel 发送(回源 channel)
356
+ const crossChannel = request.message.metadata?.['x-aw-cross-channel'] === 'true'
357
+ const fromChannel = request.message.metadata?.['x-aw-from-channel']
358
+ if (crossChannel && typeof fromChannel === 'string') {
359
+ await ctx.workspace.sendCrossChannelMessage({
360
+ toChannelId: fromChannel,
361
+ parts: [{ text: `mock 跨Channel回复(${ctx.agentId}):已处理「${text.slice(0, 60)}」。执行结果:完成;你所需的内容已包含在本回复中。本回复不需要再响应。` }],
362
+ inReplyTo: request.message.messageId,
363
+ })
364
+ yield { kind: 'done' }
365
+ return
366
+ }
355
367
  await ctx.workspace.sendMessage({
356
368
  toAgentId: fromId,
357
369
  parts: [{ text: `mock 回复(${ctx.agentId}):已处理「${text.slice(0, 60)}」。执行结果:完成;你所需的内容已包含在本回复中。本回复不需要再响应。` }],