agent-relay 3.2.0 → 3.2.1
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/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/dist/index.cjs +1307 -204
- package/dist/src/cli/relaycast-mcp.d.ts +4 -0
- package/dist/src/cli/relaycast-mcp.d.ts.map +1 -1
- package/dist/src/cli/relaycast-mcp.js +4 -4
- package/dist/src/cli/relaycast-mcp.js.map +1 -1
- package/package.json +8 -8
- package/packages/acp-bridge/package.json +2 -2
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/openclaw/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts +14 -0
- package/packages/sdk/dist/__tests__/completion-pipeline.test.d.ts.map +1 -0
- package/packages/sdk/dist/__tests__/completion-pipeline.test.js +1476 -0
- package/packages/sdk/dist/__tests__/completion-pipeline.test.js.map +1 -0
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.js +2 -2
- package/packages/sdk/dist/__tests__/e2e-owner-review.test.js.map +1 -1
- package/packages/sdk/dist/workflows/runner.d.ts +53 -2
- package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/runner.js +1269 -86
- package/packages/sdk/dist/workflows/runner.js.map +1 -1
- package/packages/sdk/dist/workflows/trajectory.d.ts +6 -2
- package/packages/sdk/dist/workflows/trajectory.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/trajectory.js +37 -2
- package/packages/sdk/dist/workflows/trajectory.js.map +1 -1
- package/packages/sdk/dist/workflows/types.d.ts +88 -0
- package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/types.js.map +1 -1
- package/packages/sdk/package.json +2 -2
- package/packages/sdk/src/__tests__/completion-pipeline.test.ts +1820 -0
- package/packages/sdk/src/__tests__/e2e-owner-review.test.ts +2 -2
- package/packages/sdk/src/__tests__/idle-nudge.test.ts +68 -0
- package/packages/sdk/src/__tests__/workflow-runner.test.ts +113 -4
- package/packages/sdk/src/workflows/README.md +43 -11
- package/packages/sdk/src/workflows/runner.ts +1751 -94
- package/packages/sdk/src/workflows/schema.json +6 -0
- package/packages/sdk/src/workflows/trajectory.ts +52 -3
- package/packages/sdk/src/workflows/types.ts +149 -0
- package/packages/sdk-py/pyproject.toml +1 -1
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +2 -2
|
@@ -126,6 +126,12 @@ Added workdir to WorktreeWorkflowStep
|
|
|
126
126
|
},
|
|
127
127
|
"idleNudge": {
|
|
128
128
|
"$ref": "#/definitions/IdleNudgeConfig"
|
|
129
|
+
},
|
|
130
|
+
"completionGracePeriodMs": {
|
|
131
|
+
"type": "integer",
|
|
132
|
+
"minimum": 0,
|
|
133
|
+
"default": 5000,
|
|
134
|
+
"description": "Grace period (ms) after an agent exits with code 0 but without posting the expected coordination signal. During this window the runner checks verification gates and evidence before failing. Set to 0 to disable."
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
},
|
|
@@ -16,7 +16,7 @@ import { existsSync } from 'node:fs';
|
|
|
16
16
|
import { mkdir, writeFile, rename } from 'node:fs/promises';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
|
|
19
|
-
import type { TrajectoryConfig, WorkflowStep } from './types.js';
|
|
19
|
+
import type { StepCompletionDecision, TrajectoryConfig, WorkflowStep } from './types.js';
|
|
20
20
|
|
|
21
21
|
// ── Trajectory file format (compatible with trail CLI) ───────────────────────
|
|
22
22
|
|
|
@@ -84,6 +84,8 @@ export interface StepOutcome {
|
|
|
84
84
|
nonInteractive?: boolean;
|
|
85
85
|
/** Duration in ms. */
|
|
86
86
|
durationMs?: number;
|
|
87
|
+
/** How the step completion was determined. */
|
|
88
|
+
completionMode?: StepCompletionDecision['mode'];
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
// ── Failure root-cause categories ───────────────────────────────────────────
|
|
@@ -339,8 +341,35 @@ export class WorkflowTrajectory {
|
|
|
339
341
|
await this.flush();
|
|
340
342
|
}
|
|
341
343
|
|
|
344
|
+
async stepCompletionDecision(stepName: string, decision: StepCompletionDecision): Promise<void> {
|
|
345
|
+
if (!this.enabled || !this.trajectory) return;
|
|
346
|
+
|
|
347
|
+
const modeLabel = decision.mode === 'marker' ? 'marker-based' : `${decision.mode}-based`;
|
|
348
|
+
const reason = decision.reason ? ` — ${decision.reason}` : '';
|
|
349
|
+
const evidence = this.formatCompletionEvidenceSummary(decision.evidence);
|
|
350
|
+
const evidenceSuffix = evidence ? ` (${evidence})` : '';
|
|
351
|
+
|
|
352
|
+
this.addEvent(
|
|
353
|
+
decision.mode === 'marker' ? 'completion-marker' : 'completion-evidence',
|
|
354
|
+
`"${stepName}" ${modeLabel} completion${reason}${evidenceSuffix}`,
|
|
355
|
+
'medium',
|
|
356
|
+
{
|
|
357
|
+
stepName,
|
|
358
|
+
completionMode: decision.mode,
|
|
359
|
+
reason: decision.reason,
|
|
360
|
+
evidence: decision.evidence,
|
|
361
|
+
}
|
|
362
|
+
);
|
|
363
|
+
await this.flush();
|
|
364
|
+
}
|
|
365
|
+
|
|
342
366
|
/** Record step completed — captures what was accomplished. */
|
|
343
|
-
async stepCompleted(
|
|
367
|
+
async stepCompleted(
|
|
368
|
+
step: WorkflowStep,
|
|
369
|
+
output: string,
|
|
370
|
+
attempt: number,
|
|
371
|
+
decision?: StepCompletionDecision
|
|
372
|
+
): Promise<void> {
|
|
344
373
|
if (!this.enabled || !this.trajectory) return;
|
|
345
374
|
|
|
346
375
|
const suffix = attempt > 1 ? ` (after ${attempt} attempts)` : '';
|
|
@@ -357,7 +386,12 @@ export class WorkflowTrajectory {
|
|
|
357
386
|
? lastMeaningful
|
|
358
387
|
: output.trim().slice(0, 120) || '(no output)';
|
|
359
388
|
|
|
360
|
-
|
|
389
|
+
if (decision) {
|
|
390
|
+
await this.stepCompletionDecision(step.name, decision);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const modeSuffix = decision ? ` [${decision.mode}]` : '';
|
|
394
|
+
this.addEvent('finding', `"${step.name}" completed${suffix}${modeSuffix} → ${completion}`, 'medium');
|
|
361
395
|
await this.flush();
|
|
362
396
|
}
|
|
363
397
|
|
|
@@ -697,6 +731,21 @@ export class WorkflowTrajectory {
|
|
|
697
731
|
chapter.events.push(event);
|
|
698
732
|
}
|
|
699
733
|
|
|
734
|
+
private formatCompletionEvidenceSummary(
|
|
735
|
+
evidence: StepCompletionDecision['evidence'] | undefined
|
|
736
|
+
): string | undefined {
|
|
737
|
+
if (!evidence) return undefined;
|
|
738
|
+
|
|
739
|
+
const parts: string[] = [];
|
|
740
|
+
if (evidence.summary) parts.push(evidence.summary);
|
|
741
|
+
if (evidence.signals?.length) parts.push(`signals=${evidence.signals.join(', ')}`);
|
|
742
|
+
if (evidence.channelPosts?.length) parts.push(`channel=${evidence.channelPosts.join(' | ')}`);
|
|
743
|
+
if (evidence.files?.length) parts.push(`files=${evidence.files.join(', ')}`);
|
|
744
|
+
if (evidence.exitCode !== undefined) parts.push(`exit=${evidence.exitCode}`);
|
|
745
|
+
|
|
746
|
+
return parts.length > 0 ? parts.join('; ') : undefined;
|
|
747
|
+
}
|
|
748
|
+
|
|
700
749
|
private async flush(): Promise<void> {
|
|
701
750
|
if (!this.trajectory) return;
|
|
702
751
|
|
|
@@ -76,6 +76,13 @@ export interface SwarmConfig {
|
|
|
76
76
|
channel?: string;
|
|
77
77
|
/** Idle agent detection and nudging configuration for interactive agents. */
|
|
78
78
|
idleNudge?: IdleNudgeConfig;
|
|
79
|
+
/**
|
|
80
|
+
* Grace period (ms) after an agent exits with code 0 but without posting
|
|
81
|
+
* the expected coordination signal. During this window the runner checks
|
|
82
|
+
* verification gates and evidence before failing the step.
|
|
83
|
+
* Default: 5000 (5 seconds). Set to 0 to disable.
|
|
84
|
+
*/
|
|
85
|
+
completionGracePeriodMs?: number;
|
|
79
86
|
}
|
|
80
87
|
|
|
81
88
|
export type SwarmPattern =
|
|
@@ -310,6 +317,128 @@ export interface VerificationCheck {
|
|
|
310
317
|
description?: string;
|
|
311
318
|
}
|
|
312
319
|
|
|
320
|
+
// ── Completion evidence ─────────────────────────────────────────────────────
|
|
321
|
+
|
|
322
|
+
export type CompletionEvidenceSignalSource =
|
|
323
|
+
| 'channel'
|
|
324
|
+
| 'stdout'
|
|
325
|
+
| 'stderr'
|
|
326
|
+
| 'process'
|
|
327
|
+
| 'filesystem'
|
|
328
|
+
| 'tool'
|
|
329
|
+
| 'verification';
|
|
330
|
+
|
|
331
|
+
export type CompletionEvidenceSignalKind =
|
|
332
|
+
| 'worker_done'
|
|
333
|
+
| 'lead_done'
|
|
334
|
+
| 'step_complete'
|
|
335
|
+
| 'owner_decision'
|
|
336
|
+
| 'review_decision'
|
|
337
|
+
| 'task_summary'
|
|
338
|
+
| 'verification_passed'
|
|
339
|
+
| 'verification_failed'
|
|
340
|
+
| 'process_exit'
|
|
341
|
+
| 'custom';
|
|
342
|
+
|
|
343
|
+
export interface CompletionEvidenceSignal {
|
|
344
|
+
kind: CompletionEvidenceSignalKind;
|
|
345
|
+
source: CompletionEvidenceSignalSource;
|
|
346
|
+
text: string;
|
|
347
|
+
observedAt: string;
|
|
348
|
+
sender?: string;
|
|
349
|
+
actor?: string;
|
|
350
|
+
role?: string;
|
|
351
|
+
value?: string;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export type CompletionEvidenceChannelOrigin = 'runner_post' | 'forwarded_chunk' | 'relay_message';
|
|
355
|
+
|
|
356
|
+
export interface CompletionEvidenceChannelPost {
|
|
357
|
+
stepName: string;
|
|
358
|
+
text: string;
|
|
359
|
+
postedAt: string;
|
|
360
|
+
origin: CompletionEvidenceChannelOrigin;
|
|
361
|
+
completionRelevant: boolean;
|
|
362
|
+
sender?: string;
|
|
363
|
+
actor?: string;
|
|
364
|
+
role?: string;
|
|
365
|
+
target?: string;
|
|
366
|
+
signals: CompletionEvidenceSignal[];
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export type CompletionEvidenceFileChangeKind = 'created' | 'modified' | 'deleted';
|
|
370
|
+
|
|
371
|
+
export interface CompletionEvidenceFileChange {
|
|
372
|
+
path: string;
|
|
373
|
+
kind: CompletionEvidenceFileChangeKind;
|
|
374
|
+
observedAt: string;
|
|
375
|
+
root?: string;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export type CompletionEvidenceToolSideEffectType =
|
|
379
|
+
| 'persist_step_output'
|
|
380
|
+
| 'post_channel_message'
|
|
381
|
+
| 'verification_observed'
|
|
382
|
+
| 'worktree_created'
|
|
383
|
+
| 'owner_monitoring'
|
|
384
|
+
| 'review_started'
|
|
385
|
+
| 'review_completed'
|
|
386
|
+
| 'worker_exit'
|
|
387
|
+
| 'worker_error'
|
|
388
|
+
| 'retry'
|
|
389
|
+
| 'custom';
|
|
390
|
+
|
|
391
|
+
export interface CompletionEvidenceToolSideEffect {
|
|
392
|
+
type: CompletionEvidenceToolSideEffectType;
|
|
393
|
+
detail: string;
|
|
394
|
+
observedAt: string;
|
|
395
|
+
raw?: Record<string, unknown>;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export interface StepCompletionEvidence {
|
|
399
|
+
stepName: string;
|
|
400
|
+
status?: WorkflowStepStatus;
|
|
401
|
+
startedAt?: string;
|
|
402
|
+
completedAt?: string;
|
|
403
|
+
lastUpdatedAt: string;
|
|
404
|
+
roots: string[];
|
|
405
|
+
output: {
|
|
406
|
+
stdout: string;
|
|
407
|
+
stderr: string;
|
|
408
|
+
combined: string;
|
|
409
|
+
};
|
|
410
|
+
channelPosts: CompletionEvidenceChannelPost[];
|
|
411
|
+
files: CompletionEvidenceFileChange[];
|
|
412
|
+
process: {
|
|
413
|
+
exitCode?: number;
|
|
414
|
+
exitSignal?: string;
|
|
415
|
+
};
|
|
416
|
+
toolSideEffects: CompletionEvidenceToolSideEffect[];
|
|
417
|
+
coordinationSignals: CompletionEvidenceSignal[];
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export type StepCompletionMode =
|
|
421
|
+
| 'marker'
|
|
422
|
+
| 'evidence'
|
|
423
|
+
| 'verification'
|
|
424
|
+
| 'owner_decision'
|
|
425
|
+
| 'review'
|
|
426
|
+
| 'heuristic';
|
|
427
|
+
|
|
428
|
+
export interface StepCompletionDecisionEvidence {
|
|
429
|
+
summary?: string;
|
|
430
|
+
signals?: string[];
|
|
431
|
+
channelPosts?: string[];
|
|
432
|
+
files?: string[];
|
|
433
|
+
exitCode?: number;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export interface StepCompletionDecision {
|
|
437
|
+
mode: StepCompletionMode;
|
|
438
|
+
reason?: string;
|
|
439
|
+
evidence?: StepCompletionDecisionEvidence;
|
|
440
|
+
}
|
|
441
|
+
|
|
313
442
|
// ── Coordination ────────────────────────────────────────────────────────────
|
|
314
443
|
|
|
315
444
|
/** Coordination settings for multi-agent synchronization. */
|
|
@@ -394,6 +523,25 @@ export interface WorkflowRunRow {
|
|
|
394
523
|
}
|
|
395
524
|
|
|
396
525
|
export type WorkflowStepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
|
526
|
+
export type WorkflowOwnerDecision =
|
|
527
|
+
| 'COMPLETE'
|
|
528
|
+
| 'INCOMPLETE_RETRY'
|
|
529
|
+
| 'INCOMPLETE_FAIL'
|
|
530
|
+
| 'NEEDS_CLARIFICATION';
|
|
531
|
+
/**
|
|
532
|
+
* Completion reasons are recorded for both successful and failed steps.
|
|
533
|
+
* `retry_requested_by_owner` is a retry-control signal, not a success state:
|
|
534
|
+
* the runner retries while budget remains and fails the step once retries are exhausted.
|
|
535
|
+
*/
|
|
536
|
+
export type WorkflowStepCompletionReason =
|
|
537
|
+
| 'completed_verified'
|
|
538
|
+
| 'completed_by_owner_decision'
|
|
539
|
+
| 'completed_by_evidence'
|
|
540
|
+
| 'completed_by_process_exit'
|
|
541
|
+
| 'retry_requested_by_owner'
|
|
542
|
+
| 'failed_verification'
|
|
543
|
+
| 'failed_owner_decision'
|
|
544
|
+
| 'failed_no_evidence';
|
|
397
545
|
|
|
398
546
|
/** Database row representing a single workflow step execution. */
|
|
399
547
|
export interface WorkflowStepRow {
|
|
@@ -410,6 +558,7 @@ export interface WorkflowStepRow {
|
|
|
410
558
|
dependsOn: string[];
|
|
411
559
|
output?: string;
|
|
412
560
|
error?: string;
|
|
561
|
+
completionReason?: WorkflowStepCompletionReason;
|
|
413
562
|
startedAt?: string;
|
|
414
563
|
completedAt?: string;
|
|
415
564
|
retryCount: number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/trajectory",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1",
|
|
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.2.
|
|
25
|
+
"@agent-relay/config": "3.2.1"
|
|
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.2.
|
|
3
|
+
"version": "3.2.1",
|
|
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.2.
|
|
25
|
+
"@agent-relay/utils": "3.2.1"
|
|
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.2.
|
|
3
|
+
"version": "3.2.1",
|
|
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.2.
|
|
115
|
+
"@agent-relay/config": "3.2.1",
|
|
116
116
|
"compare-versions": "^6.1.1"
|
|
117
117
|
},
|
|
118
118
|
"publishConfig": {
|