agent-relay 2.1.4 → 2.1.6
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/README.md +85 -236
- package/dist/index.cjs +281 -24
- package/package.json +19 -19
- package/packages/api-types/package.json +1 -1
- package/packages/benchmark/package.json +4 -4
- package/packages/bridge/dist/spawner.d.ts.map +1 -1
- package/packages/bridge/dist/spawner.js +39 -5
- package/packages/bridge/dist/spawner.js.map +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/bridge/src/spawner.ts +40 -5
- package/packages/cli-tester/package.json +1 -1
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +2 -2
- package/packages/daemon/dist/server.d.ts +5 -0
- package/packages/daemon/dist/server.d.ts.map +1 -1
- package/packages/daemon/dist/server.js +31 -0
- package/packages/daemon/dist/server.js.map +1 -1
- package/packages/daemon/package.json +12 -12
- package/packages/daemon/src/server.ts +37 -0
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/cloud.d.ts +7 -114
- package/packages/mcp/dist/cloud.d.ts.map +1 -1
- package/packages/mcp/dist/cloud.js +21 -431
- package/packages/mcp/dist/cloud.js.map +1 -1
- package/packages/mcp/dist/errors.d.ts +4 -22
- package/packages/mcp/dist/errors.d.ts.map +1 -1
- package/packages/mcp/dist/errors.js +4 -43
- package/packages/mcp/dist/errors.js.map +1 -1
- package/packages/mcp/dist/hybrid-client.d.ts.map +1 -1
- package/packages/mcp/dist/hybrid-client.js +7 -1
- package/packages/mcp/dist/hybrid-client.js.map +1 -1
- package/packages/mcp/package.json +4 -3
- package/packages/mcp/src/cloud.ts +29 -511
- package/packages/mcp/src/errors.ts +12 -49
- package/packages/mcp/src/hybrid-client.ts +8 -1
- package/packages/mcp/tests/discover.test.ts +72 -11
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +17 -1
- package/packages/protocol/dist/types.d.ts.map +1 -1
- package/packages/protocol/package.json +1 -1
- package/packages/protocol/src/types.ts +23 -0
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/browser-client.d.ts +212 -0
- package/packages/sdk/dist/browser-client.d.ts.map +1 -0
- package/packages/sdk/dist/browser-client.js +750 -0
- package/packages/sdk/dist/browser-client.js.map +1 -0
- package/packages/sdk/dist/browser-framing.d.ts +46 -0
- package/packages/sdk/dist/browser-framing.d.ts.map +1 -0
- package/packages/sdk/dist/browser-framing.js +122 -0
- package/packages/sdk/dist/browser-framing.js.map +1 -0
- package/packages/sdk/dist/client.d.ts +129 -2
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +312 -2
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/discovery.d.ts +10 -0
- package/packages/sdk/dist/discovery.d.ts.map +1 -0
- package/packages/sdk/dist/discovery.js +22 -0
- package/packages/sdk/dist/discovery.js.map +1 -0
- package/packages/sdk/dist/errors.d.ts +9 -0
- package/packages/sdk/dist/errors.d.ts.map +1 -0
- package/packages/sdk/dist/errors.js +9 -0
- package/packages/sdk/dist/errors.js.map +1 -0
- package/packages/sdk/dist/index.d.ts +18 -2
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +27 -1
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/transports/index.d.ts +92 -0
- package/packages/sdk/dist/transports/index.d.ts.map +1 -0
- package/packages/sdk/dist/transports/index.js +129 -0
- package/packages/sdk/dist/transports/index.js.map +1 -0
- package/packages/sdk/dist/transports/socket-transport.d.ts +30 -0
- package/packages/sdk/dist/transports/socket-transport.d.ts.map +1 -0
- package/packages/sdk/dist/transports/socket-transport.js +94 -0
- package/packages/sdk/dist/transports/socket-transport.js.map +1 -0
- package/packages/sdk/dist/transports/types.d.ts +69 -0
- package/packages/sdk/dist/transports/types.d.ts.map +1 -0
- package/packages/sdk/dist/transports/types.js +10 -0
- package/packages/sdk/dist/transports/types.js.map +1 -0
- package/packages/sdk/dist/transports/websocket-transport.d.ts +55 -0
- package/packages/sdk/dist/transports/websocket-transport.d.ts.map +1 -0
- package/packages/sdk/dist/transports/websocket-transport.js +180 -0
- package/packages/sdk/dist/transports/websocket-transport.js.map +1 -0
- package/packages/sdk/package.json +28 -4
- package/packages/sdk/src/browser-client.ts +985 -0
- package/packages/sdk/src/browser-framing.test.ts +115 -0
- package/packages/sdk/src/browser-framing.ts +150 -0
- package/packages/sdk/src/client.test.ts +425 -0
- package/packages/sdk/src/client.ts +397 -3
- package/packages/sdk/src/discovery.ts +38 -0
- package/packages/sdk/src/errors.ts +17 -0
- package/packages/sdk/src/index.ts +82 -1
- package/packages/sdk/src/transports/index.ts +197 -0
- package/packages/sdk/src/transports/socket-transport.ts +115 -0
- package/packages/sdk/src/transports/types.ts +77 -0
- package/packages/sdk/src/transports/websocket-transport.ts +245 -0
- package/packages/sdk/tsconfig.json +1 -1
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/package.json +2 -2
- package/packages/storage/src/jsonl-adapter.test.ts +8 -3
- 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/dist/cjs/discovery.js +328 -0
- package/packages/utils/dist/cjs/errors.js +81 -0
- package/packages/utils/dist/discovery.d.ts +123 -0
- package/packages/utils/dist/discovery.d.ts.map +1 -0
- package/packages/utils/dist/discovery.js +439 -0
- package/packages/utils/dist/discovery.js.map +1 -0
- package/packages/utils/dist/errors.d.ts +29 -0
- package/packages/utils/dist/errors.d.ts.map +1 -0
- package/packages/utils/dist/errors.js +50 -0
- package/packages/utils/dist/errors.js.map +1 -0
- package/packages/utils/package.json +15 -2
- package/packages/utils/src/consolidation.test.ts +125 -0
- package/packages/utils/src/discovery.test.ts +196 -0
- package/packages/utils/src/discovery.ts +524 -0
- package/packages/utils/src/errors.test.ts +83 -0
- package/packages/utils/src/errors.ts +56 -0
- package/packages/wrapper/dist/opencode-wrapper.d.ts +6 -2
- package/packages/wrapper/dist/opencode-wrapper.d.ts.map +1 -1
- package/packages/wrapper/dist/opencode-wrapper.js +34 -10
- package/packages/wrapper/dist/opencode-wrapper.js.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts +22 -2
- package/packages/wrapper/dist/relay-pty-orchestrator.d.ts.map +1 -1
- package/packages/wrapper/dist/relay-pty-orchestrator.js +174 -4
- package/packages/wrapper/dist/relay-pty-orchestrator.js.map +1 -1
- package/packages/wrapper/package.json +6 -6
- package/packages/wrapper/src/opencode-wrapper.ts +37 -9
- package/packages/wrapper/src/relay-pty-orchestrator.ts +197 -4
- package/relay-snippets/agent-relay-snippet.md +17 -5
|
@@ -64,6 +64,61 @@ const MAX_SOCKET_PATH_LENGTH = 107;
|
|
|
64
64
|
*/
|
|
65
65
|
const MAX_OUTPUT_BUFFER_SIZE = 10 * 1024 * 1024; // 10MB
|
|
66
66
|
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Activity Verification Constants
|
|
69
|
+
// ============================================================================
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Activity patterns used to verify that a CLI has received and started processing
|
|
73
|
+
* an injected task. These patterns work across Claude Code, Codex, and Droid/Gemini.
|
|
74
|
+
*
|
|
75
|
+
* The problem we're solving: Rust confirms "delivered to PTY" but that doesn't mean
|
|
76
|
+
* the CLI processed it. The T-003 failure showed the CLI wasn't ready when input arrived.
|
|
77
|
+
*
|
|
78
|
+
* @see https://github.com/your-org/relay/issues/XXX for the original investigation
|
|
79
|
+
*/
|
|
80
|
+
const ACTIVITY_VERIFICATION = {
|
|
81
|
+
/** Time to wait for activity patterns after injection (ms) */
|
|
82
|
+
TIMEOUT_MS: 5000,
|
|
83
|
+
/** How often to check for activity patterns (ms) */
|
|
84
|
+
POLL_INTERVAL_MS: 200,
|
|
85
|
+
/** Maximum retries when no activity is detected */
|
|
86
|
+
MAX_RETRIES: 3,
|
|
87
|
+
/** Delay between retries (ms) */
|
|
88
|
+
RETRY_DELAY_MS: 500,
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Patterns indicating the task was received and displayed.
|
|
92
|
+
* These are the primary verification patterns.
|
|
93
|
+
*/
|
|
94
|
+
TASK_RECEIVED_PATTERNS: [
|
|
95
|
+
/\[Pasted text #\d+/, // Claude Code shows "[Pasted text #1 +95 lines]"
|
|
96
|
+
/› Relay message from/, // Codex shows "› Relay message from"
|
|
97
|
+
/Relay message from \w+ \[[\w-]+\]/, // Droid/Gemini shows "Relay message from Agent [id]:"
|
|
98
|
+
],
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Patterns indicating the CLI is thinking/processing.
|
|
102
|
+
* Secondary verification - proves the CLI is active.
|
|
103
|
+
*/
|
|
104
|
+
THINKING_PATTERNS: [
|
|
105
|
+
/\(.*esc to (?:interrupt|stop)\)/i, // All CLIs: "(esc to interrupt)" or "(Press ESC to stop)"
|
|
106
|
+
/[✻✶✳✢·✽⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/, // Spinner characters (Claude + Droid)
|
|
107
|
+
/Thinking\.\.\./, // Droid: "Thinking..."
|
|
108
|
+
/Working/, // Codex: "Working"
|
|
109
|
+
/Forming|Noodling|Manifesting/i, // Claude Code thinking states
|
|
110
|
+
],
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Patterns indicating tool execution started.
|
|
114
|
+
* Tertiary verification - proves the CLI is working.
|
|
115
|
+
*/
|
|
116
|
+
TOOL_EXECUTION_PATTERNS: [
|
|
117
|
+
/⏺\s*(Bash|Read|Write|Edit|Glob|Grep|Task|WebFetch)/, // Claude Code tool markers
|
|
118
|
+
/•\s*Running/, // Codex: "• Running: command"
|
|
119
|
+
],
|
|
120
|
+
} as const;
|
|
121
|
+
|
|
67
122
|
function hashWorkspaceId(workspaceId: string): string {
|
|
68
123
|
return createHash('sha256').update(workspaceId).digest('hex').slice(0, 12);
|
|
69
124
|
}
|
|
@@ -213,6 +268,7 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
213
268
|
private outputBuffer = '';
|
|
214
269
|
private rawBuffer = '';
|
|
215
270
|
private lastParsedLength = 0;
|
|
271
|
+
private bufferTrimCount = 0;
|
|
216
272
|
|
|
217
273
|
// Interactive mode (show output to terminal)
|
|
218
274
|
private isInteractive = false;
|
|
@@ -965,15 +1021,21 @@ export class RelayPtyOrchestrator extends BaseWrapper {
|
|
|
965
1021
|
|
|
966
1022
|
// Trim buffers if they exceed max size to prevent RangeError: Invalid string length
|
|
967
1023
|
// Keep the most recent output (tail) as it's more relevant for pattern matching
|
|
1024
|
+
let buffersTrimmed = false;
|
|
968
1025
|
if (this.rawBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
|
|
969
1026
|
const trimAmount = this.rawBuffer.length - MAX_OUTPUT_BUFFER_SIZE;
|
|
970
1027
|
this.rawBuffer = this.rawBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
|
|
971
1028
|
// Adjust lastParsedLength to stay in sync with the trimmed buffer
|
|
972
1029
|
// This ensures parseRelayCommands() doesn't skip content or re-parse old content
|
|
973
1030
|
this.lastParsedLength = Math.max(0, this.lastParsedLength - trimAmount);
|
|
1031
|
+
buffersTrimmed = true;
|
|
974
1032
|
}
|
|
975
1033
|
if (this.outputBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
|
|
976
1034
|
this.outputBuffer = this.outputBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
|
|
1035
|
+
buffersTrimmed = true;
|
|
1036
|
+
}
|
|
1037
|
+
if (buffersTrimmed) {
|
|
1038
|
+
this.bufferTrimCount += 1;
|
|
977
1039
|
}
|
|
978
1040
|
|
|
979
1041
|
// Feed to idle detector
|
|
@@ -2572,17 +2634,148 @@ Then output: \`->relay-file:spawn\`
|
|
|
2572
2634
|
}
|
|
2573
2635
|
|
|
2574
2636
|
/**
|
|
2575
|
-
*
|
|
2637
|
+
* Verify that the CLI shows activity after task injection.
|
|
2638
|
+
* Checks output for patterns indicating the task was received and processing started.
|
|
2639
|
+
*
|
|
2640
|
+
* This catches the race condition where PTY write succeeds but CLI wasn't ready
|
|
2641
|
+
* (the T-003 failure scenario where CLI showed bell characters instead of processing).
|
|
2642
|
+
*
|
|
2643
|
+
* @param outputBefore The output buffer content before injection
|
|
2644
|
+
* @returns Promise resolving to true if activity detected, false otherwise
|
|
2645
|
+
*/
|
|
2646
|
+
private async verifyActivityAfterInjection(outputBefore: string): Promise<boolean> {
|
|
2647
|
+
const startTime = Date.now();
|
|
2648
|
+
const { TIMEOUT_MS, POLL_INTERVAL_MS, TASK_RECEIVED_PATTERNS, THINKING_PATTERNS, TOOL_EXECUTION_PATTERNS } = ACTIVITY_VERIFICATION;
|
|
2649
|
+
const trimCountBefore = this.bufferTrimCount;
|
|
2650
|
+
|
|
2651
|
+
while (Date.now() - startTime < TIMEOUT_MS) {
|
|
2652
|
+
// If buffers were trimmed during verification, treat it as activity.
|
|
2653
|
+
// Large output growth triggers trimming, which would otherwise make slice() return
|
|
2654
|
+
// an empty string and falsely signal no activity.
|
|
2655
|
+
if (this.bufferTrimCount !== trimCountBefore) {
|
|
2656
|
+
this.log(` Activity verified: output buffer trimmed during verification (large output)`);
|
|
2657
|
+
return true;
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
// Get new output since injection
|
|
2661
|
+
const currentOutput = this.outputBuffer;
|
|
2662
|
+
const newOutput = currentOutput.slice(outputBefore.length);
|
|
2663
|
+
|
|
2664
|
+
if (newOutput.length > 0) {
|
|
2665
|
+
// REJECTION CHECK: Multiple BEL characters (0x07) indicate CLI rejected input
|
|
2666
|
+
// The T-003 failure showed CLI producing 1000+ BELs when input was injected
|
|
2667
|
+
// while the CLI wasn't ready (still initializing or in wrong mode)
|
|
2668
|
+
const belCount = (newOutput.match(/\x07/g) || []).length;
|
|
2669
|
+
if (belCount > 10) {
|
|
2670
|
+
this.logError(` Input rejected: CLI produced ${belCount} BEL characters`);
|
|
2671
|
+
return false; // Don't wait - immediately fail so retry can attempt
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
// Check for task received patterns (primary verification)
|
|
2675
|
+
for (const pattern of TASK_RECEIVED_PATTERNS) {
|
|
2676
|
+
if (pattern.test(newOutput)) {
|
|
2677
|
+
this.log(` Activity verified: task received pattern matched`);
|
|
2678
|
+
return true;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
// Check for thinking/processing patterns (secondary verification)
|
|
2683
|
+
for (const pattern of THINKING_PATTERNS) {
|
|
2684
|
+
if (pattern.test(newOutput)) {
|
|
2685
|
+
this.log(` Activity verified: thinking pattern matched`);
|
|
2686
|
+
return true;
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
// Check for tool execution patterns (tertiary verification)
|
|
2691
|
+
for (const pattern of TOOL_EXECUTION_PATTERNS) {
|
|
2692
|
+
if (pattern.test(newOutput)) {
|
|
2693
|
+
this.log(` Activity verified: tool execution pattern matched`);
|
|
2694
|
+
return true;
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
// Fallback: If output grew significantly (>100 meaningful chars), assume activity
|
|
2699
|
+
// This catches CLIs with unusual output patterns
|
|
2700
|
+
// IMPORTANT: Strip out BEL (0x07) and other control characters - these are rejection
|
|
2701
|
+
// signals not activity. The T-003 failure showed CLI producing 1000+ BELs when input
|
|
2702
|
+
// was injected before it was ready.
|
|
2703
|
+
const meaningfulOutput = newOutput.replace(/[\x00-\x1f]/g, ''); // Strip control chars
|
|
2704
|
+
if (meaningfulOutput.length > 100) {
|
|
2705
|
+
this.log(` Activity verified: significant output growth (${meaningfulOutput.length} meaningful chars)`);
|
|
2706
|
+
return true;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
await sleep(POLL_INTERVAL_MS);
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
// No activity detected within timeout
|
|
2714
|
+
this.log(` No activity detected within ${TIMEOUT_MS}ms`);
|
|
2715
|
+
return false;
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
/**
|
|
2719
|
+
* Inject a task using the socket-based injection system with activity verification.
|
|
2576
2720
|
* This is the preferred method for spawned agent task delivery.
|
|
2577
2721
|
*
|
|
2722
|
+
* After socket confirms delivery, verifies the CLI shows activity (task received,
|
|
2723
|
+
* thinking indicators, or tool execution). Retries if no activity is detected.
|
|
2724
|
+
*
|
|
2578
2725
|
* @param task The task text to inject
|
|
2579
2726
|
* @param from The sender name (default: "spawner")
|
|
2580
|
-
* @returns Promise resolving to true if
|
|
2727
|
+
* @returns Promise resolving to true if task was delivered AND activity verified, false otherwise
|
|
2581
2728
|
*/
|
|
2582
2729
|
async injectTask(task: string, from = 'spawner'): Promise<boolean> {
|
|
2730
|
+
const { MAX_RETRIES, RETRY_DELAY_MS } = ACTIVITY_VERIFICATION;
|
|
2731
|
+
|
|
2732
|
+
// Claude Code's TUI needs a stabilization delay after displaying the welcome screen
|
|
2733
|
+
// before it's ready to accept stdin input. Without this, input may be silently dropped
|
|
2734
|
+
// even though the CLI appears "idle" and doesn't reject with BELs.
|
|
2735
|
+
// 1500ms is based on observed behavior - Claude Code typically needs 1-1.5s after
|
|
2736
|
+
// its TUI renders before input handlers are fully initialized.
|
|
2737
|
+
const STABILIZATION_DELAY_MS = 1500;
|
|
2738
|
+
this.log(` Waiting ${STABILIZATION_DELAY_MS}ms for CLI stabilization before task injection`);
|
|
2739
|
+
await sleep(STABILIZATION_DELAY_MS);
|
|
2740
|
+
|
|
2741
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
2742
|
+
if (attempt > 0) {
|
|
2743
|
+
this.log(` Retry ${attempt}/${MAX_RETRIES} - waiting ${RETRY_DELAY_MS}ms before retry`);
|
|
2744
|
+
await sleep(RETRY_DELAY_MS);
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
// Capture output buffer state before injection
|
|
2748
|
+
const outputBefore = this.outputBuffer;
|
|
2749
|
+
|
|
2750
|
+
// Attempt delivery via socket
|
|
2751
|
+
const delivered = await this.performTaskInjection(task, from);
|
|
2752
|
+
if (!delivered) {
|
|
2753
|
+
this.logError(` Task delivery failed on attempt ${attempt + 1}`);
|
|
2754
|
+
continue; // Retry
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
// Verify CLI shows activity (task received, thinking, or tool execution)
|
|
2758
|
+
const activityVerified = await this.verifyActivityAfterInjection(outputBefore);
|
|
2759
|
+
if (activityVerified) {
|
|
2760
|
+
this.log(` Task delivered and activity verified successfully`);
|
|
2761
|
+
return true;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// Delivery succeeded but no activity - CLI might not have been ready
|
|
2765
|
+
this.logError(` Task delivered but no activity detected (attempt ${attempt + 1})`);
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
this.logError(` Task injection failed after ${MAX_RETRIES + 1} attempts - no CLI activity detected`);
|
|
2769
|
+
return false;
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
/**
|
|
2773
|
+
* Perform a single task injection attempt (without retry logic).
|
|
2774
|
+
* @returns true if the injection was sent successfully, false otherwise
|
|
2775
|
+
*/
|
|
2776
|
+
private async performTaskInjection(task: string, from: string): Promise<boolean> {
|
|
2583
2777
|
if (!this.socket || !this.socketConnected) {
|
|
2584
2778
|
this.log(` Socket not connected for task injection, falling back to stdin write`);
|
|
2585
|
-
// Fallback to direct write if socket not available
|
|
2586
2779
|
try {
|
|
2587
2780
|
await this.write(task + '\n');
|
|
2588
2781
|
return true;
|
|
@@ -2606,7 +2799,7 @@ Then output: \`->relay-file:spawn\`
|
|
|
2606
2799
|
priority: 0, // High priority for initial task
|
|
2607
2800
|
};
|
|
2608
2801
|
|
|
2609
|
-
// Send with timeout and
|
|
2802
|
+
// Send with timeout and get socket confirmation
|
|
2610
2803
|
return new Promise<boolean>((resolve) => {
|
|
2611
2804
|
const timeout = setTimeout(() => {
|
|
2612
2805
|
this.logError(` Task inject timeout for ${shortId} after 30s`);
|
|
@@ -24,7 +24,9 @@ Real-time agent-to-agent messaging via file-based protocol.
|
|
|
24
24
|
|
|
25
25
|
## Sending Messages
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
**TWO STEPS REQUIRED:**
|
|
28
|
+
|
|
29
|
+
**Step 1:** EXECUTE this bash command (you MUST run it via your Bash/shell tool, not just display it):
|
|
28
30
|
|
|
29
31
|
```bash
|
|
30
32
|
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
@@ -34,7 +36,12 @@ Your message here.
|
|
|
34
36
|
EOF
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
**Step 2:** Output the trigger `->relay-file:msg` directly in your response text (after the bash command succeeds).
|
|
40
|
+
|
|
41
|
+
⚠️ **CRITICAL**: You must EXECUTE the bash command above - do NOT just display it as a code block. The file must actually be created on disk. Then output the trigger as plain text.
|
|
42
|
+
|
|
43
|
+
✅ CORRECT: Run Bash tool → then output `->relay-file:msg`
|
|
44
|
+
❌ WRONG: Display the bash code without executing it
|
|
38
45
|
|
|
39
46
|
> **Note**: `$AGENT_RELAY_OUTBOX` is automatically set by agent-relay when spawning agents. Data is stored in `.agent-relay/` within your project directory.
|
|
40
47
|
|
|
@@ -105,6 +112,7 @@ EOF
|
|
|
105
112
|
|
|
106
113
|
**IMPORTANT**: The filename is always `spawn` (not `spawn-agentname`) and the trigger is always `->relay-file:spawn`. Spawn agents one at a time sequentially.
|
|
107
114
|
|
|
115
|
+
**Step 1:** EXECUTE this bash command (run it, don't just display it):
|
|
108
116
|
```bash
|
|
109
117
|
# Spawn
|
|
110
118
|
cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF'
|
|
@@ -115,8 +123,9 @@ CLI: claude
|
|
|
115
123
|
Task description here.
|
|
116
124
|
EOF
|
|
117
125
|
```
|
|
118
|
-
|
|
126
|
+
**Step 2:** Output: `->relay-file:spawn`
|
|
119
127
|
|
|
128
|
+
**Step 1:** EXECUTE this bash command (run it, don't just display it):
|
|
120
129
|
```bash
|
|
121
130
|
# Release
|
|
122
131
|
cat > $AGENT_RELAY_OUTBOX/release << 'EOF'
|
|
@@ -124,7 +133,7 @@ KIND: release
|
|
|
124
133
|
NAME: WorkerName
|
|
125
134
|
EOF
|
|
126
135
|
```
|
|
127
|
-
|
|
136
|
+
**Step 2:** Output: `->relay-file:release`
|
|
128
137
|
|
|
129
138
|
## When You Are Spawned
|
|
130
139
|
|
|
@@ -137,7 +146,10 @@ If you were spawned by another agent:
|
|
|
137
146
|
```bash
|
|
138
147
|
# Check your spawner
|
|
139
148
|
echo "I was spawned by: $AGENT_RELAY_SPAWNER"
|
|
149
|
+
```
|
|
140
150
|
|
|
151
|
+
**Step 1:** EXECUTE this bash command:
|
|
152
|
+
```bash
|
|
141
153
|
# Reply to your spawner
|
|
142
154
|
cat > $AGENT_RELAY_OUTBOX/msg << 'EOF'
|
|
143
155
|
TO: $AGENT_RELAY_SPAWNER
|
|
@@ -145,7 +157,7 @@ TO: $AGENT_RELAY_SPAWNER
|
|
|
145
157
|
ACK: Starting on the task.
|
|
146
158
|
EOF
|
|
147
159
|
```
|
|
148
|
-
|
|
160
|
+
**Step 2:** Output: `->relay-file:msg`
|
|
149
161
|
|
|
150
162
|
## Receiving Messages
|
|
151
163
|
|