agent-relay 3.1.16 → 3.1.17

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 (39) hide show
  1. package/bin/agent-relay-broker-linux-arm64 +0 -0
  2. package/dist/index.cjs +565 -32
  3. package/package.json +8 -8
  4. package/packages/acp-bridge/package.json +2 -2
  5. package/packages/config/package.json +1 -1
  6. package/packages/hooks/package.json +4 -4
  7. package/packages/memory/package.json +2 -2
  8. package/packages/openclaw/package.json +2 -2
  9. package/packages/policy/package.json +2 -2
  10. package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts +16 -0
  11. package/packages/sdk/dist/__tests__/e2e-owner-review.test.d.ts.map +1 -0
  12. package/packages/sdk/dist/__tests__/e2e-owner-review.test.js +640 -0
  13. package/packages/sdk/dist/__tests__/e2e-owner-review.test.js.map +1 -0
  14. package/packages/sdk/dist/workflows/cli.js +10 -0
  15. package/packages/sdk/dist/workflows/cli.js.map +1 -1
  16. package/packages/sdk/dist/workflows/runner.d.ts +31 -0
  17. package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
  18. package/packages/sdk/dist/workflows/runner.js +534 -31
  19. package/packages/sdk/dist/workflows/runner.js.map +1 -1
  20. package/packages/sdk/dist/workflows/trajectory.d.ts +22 -1
  21. package/packages/sdk/dist/workflows/trajectory.d.ts.map +1 -1
  22. package/packages/sdk/dist/workflows/trajectory.js +55 -8
  23. package/packages/sdk/dist/workflows/trajectory.js.map +1 -1
  24. package/packages/sdk/dist/workflows/validator.d.ts.map +1 -1
  25. package/packages/sdk/dist/workflows/validator.js +29 -0
  26. package/packages/sdk/dist/workflows/validator.js.map +1 -1
  27. package/packages/sdk/package.json +2 -2
  28. package/packages/sdk/src/__tests__/e2e-owner-review.test.ts +778 -0
  29. package/packages/sdk/src/__tests__/workflow-runner.test.ts +484 -9
  30. package/packages/sdk/src/workflows/README.md +11 -0
  31. package/packages/sdk/src/workflows/cli.ts +10 -0
  32. package/packages/sdk/src/workflows/runner.ts +706 -33
  33. package/packages/sdk/src/workflows/trajectory.ts +89 -8
  34. package/packages/sdk/src/workflows/validator.ts +29 -0
  35. package/packages/sdk-py/pyproject.toml +1 -1
  36. package/packages/telemetry/package.json +1 -1
  37. package/packages/trajectory/package.json +2 -2
  38. package/packages/user-directory/package.json +2 -2
  39. package/packages/utils/package.json +2 -2
@@ -43,6 +43,13 @@ interface TrajectoryAgent {
43
43
  joinedAt: string;
44
44
  }
45
45
 
46
+ interface StepParticipants {
47
+ role?: string;
48
+ owner?: string;
49
+ specialist?: string;
50
+ reviewer?: string;
51
+ }
52
+
46
53
  interface TrajectoryFile {
47
54
  id: string;
48
55
  version: number;
@@ -230,16 +237,18 @@ export class WorkflowTrajectory {
230
237
  // ── Step events ────────────────────────────────────────────────────────────
231
238
 
232
239
  /** Record step started — captures intent, not just assignment. */
233
- async stepStarted(step: WorkflowStep, agent: string): Promise<void> {
240
+ async stepStarted(step: WorkflowStep, agent: string, participants?: StepParticipants): Promise<void> {
234
241
  if (!this.enabled || !this.trajectory) return;
235
242
 
236
- // Register agent if not seen
237
- if (!this.trajectory.agents.some((a) => a.name === agent)) {
238
- this.trajectory.agents.push({
239
- name: agent,
240
- role: step.agent ?? 'deterministic',
241
- joinedAt: new Date().toISOString(),
242
- });
243
+ await this.registerAgent(agent, participants?.role ?? step.agent ?? 'deterministic');
244
+ if (participants?.owner && participants.owner !== agent) {
245
+ await this.registerAgent(participants.owner, 'owner');
246
+ }
247
+ if (participants?.specialist) {
248
+ await this.registerAgent(participants.specialist, 'specialist');
249
+ }
250
+ if (participants?.reviewer) {
251
+ await this.registerAgent(participants.reviewer, 'reviewer');
243
252
  }
244
253
 
245
254
  // Capture the step's purpose: first non-empty sentence of the task
@@ -255,6 +264,78 @@ export class WorkflowTrajectory {
255
264
  await this.flush();
256
265
  }
257
266
 
267
+ async registerAgent(name: string, role: string): Promise<void> {
268
+ if (!this.enabled || !this.trajectory) return;
269
+ if (!this.trajectory.agents.some((a) => a.name === name)) {
270
+ this.trajectory.agents.push({
271
+ name,
272
+ role,
273
+ joinedAt: new Date().toISOString(),
274
+ });
275
+ await this.flush();
276
+ }
277
+ }
278
+
279
+ async stepSupervisionAssigned(
280
+ step: WorkflowStep,
281
+ supervised: { owner: { name: string }; specialist: { name: string }; reviewer?: { name: string } }
282
+ ): Promise<void> {
283
+ if (!this.enabled || !this.trajectory) return;
284
+
285
+ await this.registerAgent(supervised.owner.name, 'owner');
286
+ await this.registerAgent(supervised.specialist.name, 'specialist');
287
+ if (supervised.reviewer?.name) {
288
+ await this.registerAgent(supervised.reviewer.name, 'reviewer');
289
+ }
290
+
291
+ const reviewerNote = supervised.reviewer?.name ? `, reviewer=${supervised.reviewer.name}` : '';
292
+ this.addEvent(
293
+ 'decision',
294
+ `"${step.name}" supervision assigned → owner=${supervised.owner.name}, specialist=${supervised.specialist.name}${reviewerNote}`,
295
+ 'medium',
296
+ {
297
+ owner: supervised.owner.name,
298
+ specialist: supervised.specialist.name,
299
+ reviewer: supervised.reviewer?.name,
300
+ }
301
+ );
302
+ await this.flush();
303
+ }
304
+
305
+ async ownerMonitoringEvent(
306
+ stepName: string,
307
+ owner: string,
308
+ detail: string,
309
+ raw?: Record<string, unknown>
310
+ ): Promise<void> {
311
+ if (!this.enabled || !this.trajectory) return;
312
+
313
+ this.addEvent(
314
+ 'note',
315
+ `"${stepName}" owner ${owner}: ${detail}`,
316
+ 'medium',
317
+ raw ? { owner, ...raw } : { owner }
318
+ );
319
+ await this.flush();
320
+ }
321
+
322
+ async reviewCompleted(
323
+ stepName: string,
324
+ reviewerName: string,
325
+ decision: 'approved' | 'rejected',
326
+ reason?: string
327
+ ): Promise<void> {
328
+ if (!this.enabled || !this.trajectory) return;
329
+
330
+ this.addEvent('review-completed', `"${stepName}" review ${decision} by ${reviewerName}`, 'medium', {
331
+ stepName,
332
+ reviewer: reviewerName,
333
+ decision,
334
+ reason,
335
+ });
336
+ await this.flush();
337
+ }
338
+
258
339
  /** Record step completed — captures what was accomplished. */
259
340
  async stepCompleted(step: WorkflowStep, output: string, attempt: number): Promise<void> {
260
341
  if (!this.enabled || !this.trajectory) return;
@@ -11,8 +11,37 @@ export interface ValidationIssue {
11
11
  export function validateWorkflow(config: RelayYamlConfig): ValidationIssue[] {
12
12
  const issues: ValidationIssue[] = [];
13
13
  const agentMap = new Map(config.agents.map((a) => [a.name, a]));
14
+ const hasReviewerAgent = config.agents.some((a) => {
15
+ const role = a.role?.toLowerCase() ?? '';
16
+ const name = a.name.toLowerCase();
17
+ return (
18
+ a.preset === 'reviewer' ||
19
+ role.includes('review') ||
20
+ role.includes('critic') ||
21
+ role.includes('verifier') ||
22
+ role.includes('qa') ||
23
+ name.includes('review')
24
+ );
25
+ });
14
26
 
15
27
  for (const workflow of config.workflows ?? []) {
28
+ const hasInteractiveAgentSteps = workflow.steps.some((step) => {
29
+ if (step.type === 'deterministic' || step.type === 'worktree') return false;
30
+ if (!step.agent) return false;
31
+ const raw = agentMap.get(step.agent);
32
+ if (!raw) return false;
33
+ return resolveForValidation(raw).interactive !== false;
34
+ });
35
+ if (hasInteractiveAgentSteps && !hasReviewerAgent) {
36
+ issues.push({
37
+ severity: 'warning',
38
+ code: 'NO_REVIEW_AGENT',
39
+ message: `Workflow "${workflow.name}" has interactive agent steps but no obvious reviewer agent. The runner can auto-fallback, but dedicated reviewers improve step hardening.`,
40
+ fix: `Add an agent with role/preset like \`reviewer\`, \`critic\`, or \`verifier\`.`,
41
+ location: `workflow:${workflow.name}`,
42
+ });
43
+ }
44
+
16
45
  for (const step of workflow.steps ?? []) {
17
46
  if (step.type === 'deterministic' || step.type === 'worktree') continue;
18
47
  if (!step.agent) continue;
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agent-relay-sdk"
7
- version = "3.1.16"
7
+ version = "3.1.17"
8
8
  description = "Python SDK for Agent Relay workflows"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/telemetry",
3
- "version": "3.1.16",
3
+ "version": "3.1.17",
4
4
  "description": "Anonymous telemetry for Agent Relay usage analytics",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/trajectory",
3
- "version": "3.1.16",
3
+ "version": "3.1.17",
4
4
  "description": "Trajectory integration utilities (trail/PDERO) for Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/config": "3.1.16"
25
+ "@agent-relay/config": "3.1.17"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/user-directory",
3
- "version": "3.1.16",
3
+ "version": "3.1.17",
4
4
  "description": "User directory service for agent-relay (per-user credential storage)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "test:watch": "vitest"
23
23
  },
24
24
  "dependencies": {
25
- "@agent-relay/utils": "3.1.16"
25
+ "@agent-relay/utils": "3.1.17"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.19.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/utils",
3
- "version": "3.1.16",
3
+ "version": "3.1.17",
4
4
  "description": "Shared utilities for agent-relay: logging, name generation, command resolution, update checking",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",
@@ -112,7 +112,7 @@
112
112
  "vitest": "^3.2.4"
113
113
  },
114
114
  "dependencies": {
115
- "@agent-relay/config": "3.1.16",
115
+ "@agent-relay/config": "3.1.17",
116
116
  "compare-versions": "^6.1.1"
117
117
  },
118
118
  "publishConfig": {