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
package/dist/index.cjs
CHANGED
|
@@ -28161,7 +28161,6 @@ var require_type_overrides = __commonJS({
|
|
|
28161
28161
|
var require_pg_connection_string = __commonJS({
|
|
28162
28162
|
"node_modules/pg-connection-string/index.js"(exports2, module2) {
|
|
28163
28163
|
"use strict";
|
|
28164
|
-
var { emitWarning } = require("process");
|
|
28165
28164
|
function parse4(str, options = {}) {
|
|
28166
28165
|
if (str.charAt(0) === "/") {
|
|
28167
28166
|
const config3 = str.split(" ");
|
|
@@ -28324,9 +28323,9 @@ var require_pg_connection_string = __commonJS({
|
|
|
28324
28323
|
return toClientConfig(parse4(str));
|
|
28325
28324
|
}
|
|
28326
28325
|
function deprecatedSslModeWarning(sslmode) {
|
|
28327
|
-
if (!deprecatedSslModeWarning.warned) {
|
|
28326
|
+
if (!deprecatedSslModeWarning.warned && typeof process !== "undefined" && process.emitWarning) {
|
|
28328
28327
|
deprecatedSslModeWarning.warned = true;
|
|
28329
|
-
emitWarning(`SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.
|
|
28328
|
+
process.emitWarning(`SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.
|
|
28330
28329
|
In the next major version (pg-connection-string v3.0.0 and pg v9.0.0), these modes will adopt standard libpq semantics, which have weaker security guarantees.
|
|
28331
28330
|
|
|
28332
28331
|
To prepare for this change:
|
|
@@ -30352,7 +30351,7 @@ var require_client = __commonJS({
|
|
|
30352
30351
|
if (error2) {
|
|
30353
30352
|
reject(error2);
|
|
30354
30353
|
} else {
|
|
30355
|
-
resolve5();
|
|
30354
|
+
resolve5(this);
|
|
30356
30355
|
}
|
|
30357
30356
|
});
|
|
30358
30357
|
});
|
|
@@ -30519,16 +30518,40 @@ var require_client = __commonJS({
|
|
|
30519
30518
|
activeQuery.handleError(msg, this.connection);
|
|
30520
30519
|
}
|
|
30521
30520
|
_handleRowDescription(msg) {
|
|
30522
|
-
this._getActiveQuery()
|
|
30521
|
+
const activeQuery = this._getActiveQuery();
|
|
30522
|
+
if (activeQuery == null) {
|
|
30523
|
+
const error2 = new Error("Received unexpected rowDescription message from backend.");
|
|
30524
|
+
this._handleErrorEvent(error2);
|
|
30525
|
+
return;
|
|
30526
|
+
}
|
|
30527
|
+
activeQuery.handleRowDescription(msg);
|
|
30523
30528
|
}
|
|
30524
30529
|
_handleDataRow(msg) {
|
|
30525
|
-
this._getActiveQuery()
|
|
30530
|
+
const activeQuery = this._getActiveQuery();
|
|
30531
|
+
if (activeQuery == null) {
|
|
30532
|
+
const error2 = new Error("Received unexpected dataRow message from backend.");
|
|
30533
|
+
this._handleErrorEvent(error2);
|
|
30534
|
+
return;
|
|
30535
|
+
}
|
|
30536
|
+
activeQuery.handleDataRow(msg);
|
|
30526
30537
|
}
|
|
30527
30538
|
_handlePortalSuspended(msg) {
|
|
30528
|
-
this._getActiveQuery()
|
|
30539
|
+
const activeQuery = this._getActiveQuery();
|
|
30540
|
+
if (activeQuery == null) {
|
|
30541
|
+
const error2 = new Error("Received unexpected portalSuspended message from backend.");
|
|
30542
|
+
this._handleErrorEvent(error2);
|
|
30543
|
+
return;
|
|
30544
|
+
}
|
|
30545
|
+
activeQuery.handlePortalSuspended(this.connection);
|
|
30529
30546
|
}
|
|
30530
30547
|
_handleEmptyQuery(msg) {
|
|
30531
|
-
this._getActiveQuery()
|
|
30548
|
+
const activeQuery = this._getActiveQuery();
|
|
30549
|
+
if (activeQuery == null) {
|
|
30550
|
+
const error2 = new Error("Received unexpected emptyQuery message from backend.");
|
|
30551
|
+
this._handleErrorEvent(error2);
|
|
30552
|
+
return;
|
|
30553
|
+
}
|
|
30554
|
+
activeQuery.handleEmptyQuery(this.connection);
|
|
30532
30555
|
}
|
|
30533
30556
|
_handleCommandComplete(msg) {
|
|
30534
30557
|
const activeQuery = this._getActiveQuery();
|
|
@@ -30551,10 +30574,22 @@ var require_client = __commonJS({
|
|
|
30551
30574
|
}
|
|
30552
30575
|
}
|
|
30553
30576
|
_handleCopyInResponse(msg) {
|
|
30554
|
-
this._getActiveQuery()
|
|
30577
|
+
const activeQuery = this._getActiveQuery();
|
|
30578
|
+
if (activeQuery == null) {
|
|
30579
|
+
const error2 = new Error("Received unexpected copyInResponse message from backend.");
|
|
30580
|
+
this._handleErrorEvent(error2);
|
|
30581
|
+
return;
|
|
30582
|
+
}
|
|
30583
|
+
activeQuery.handleCopyInResponse(this.connection);
|
|
30555
30584
|
}
|
|
30556
30585
|
_handleCopyData(msg) {
|
|
30557
|
-
this._getActiveQuery()
|
|
30586
|
+
const activeQuery = this._getActiveQuery();
|
|
30587
|
+
if (activeQuery == null) {
|
|
30588
|
+
const error2 = new Error("Received unexpected copyData message from backend.");
|
|
30589
|
+
this._handleErrorEvent(error2);
|
|
30590
|
+
return;
|
|
30591
|
+
}
|
|
30592
|
+
activeQuery.handleCopyData(msg, this.connection);
|
|
30558
30593
|
}
|
|
30559
30594
|
_handleNotification(msg) {
|
|
30560
30595
|
this.emit("notification", msg);
|
|
@@ -31368,7 +31403,7 @@ var require_client2 = __commonJS({
|
|
|
31368
31403
|
});
|
|
31369
31404
|
self2.emit("connect");
|
|
31370
31405
|
self2._pulseQueryQueue(true);
|
|
31371
|
-
cb();
|
|
31406
|
+
cb(null, this);
|
|
31372
31407
|
});
|
|
31373
31408
|
});
|
|
31374
31409
|
};
|
|
@@ -31382,7 +31417,7 @@ var require_client2 = __commonJS({
|
|
|
31382
31417
|
if (error2) {
|
|
31383
31418
|
reject(error2);
|
|
31384
31419
|
} else {
|
|
31385
|
-
resolve5();
|
|
31420
|
+
resolve5(this);
|
|
31386
31421
|
}
|
|
31387
31422
|
});
|
|
31388
31423
|
});
|
|
@@ -46309,6 +46344,54 @@ var __filename2 = (0, import_node_url2.fileURLToPath)(import_meta_url);
|
|
|
46309
46344
|
var __dirname2 = (0, import_node_path11.dirname)(__filename2);
|
|
46310
46345
|
var MAX_SOCKET_PATH_LENGTH = 107;
|
|
46311
46346
|
var MAX_OUTPUT_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
46347
|
+
var ACTIVITY_VERIFICATION = {
|
|
46348
|
+
/** Time to wait for activity patterns after injection (ms) */
|
|
46349
|
+
TIMEOUT_MS: 5e3,
|
|
46350
|
+
/** How often to check for activity patterns (ms) */
|
|
46351
|
+
POLL_INTERVAL_MS: 200,
|
|
46352
|
+
/** Maximum retries when no activity is detected */
|
|
46353
|
+
MAX_RETRIES: 3,
|
|
46354
|
+
/** Delay between retries (ms) */
|
|
46355
|
+
RETRY_DELAY_MS: 500,
|
|
46356
|
+
/**
|
|
46357
|
+
* Patterns indicating the task was received and displayed.
|
|
46358
|
+
* These are the primary verification patterns.
|
|
46359
|
+
*/
|
|
46360
|
+
TASK_RECEIVED_PATTERNS: [
|
|
46361
|
+
/\[Pasted text #\d+/,
|
|
46362
|
+
// Claude Code shows "[Pasted text #1 +95 lines]"
|
|
46363
|
+
/› Relay message from/,
|
|
46364
|
+
// Codex shows "› Relay message from"
|
|
46365
|
+
/Relay message from \w+ \[[\w-]+\]/
|
|
46366
|
+
// Droid/Gemini shows "Relay message from Agent [id]:"
|
|
46367
|
+
],
|
|
46368
|
+
/**
|
|
46369
|
+
* Patterns indicating the CLI is thinking/processing.
|
|
46370
|
+
* Secondary verification - proves the CLI is active.
|
|
46371
|
+
*/
|
|
46372
|
+
THINKING_PATTERNS: [
|
|
46373
|
+
/\(.*esc to (?:interrupt|stop)\)/i,
|
|
46374
|
+
// All CLIs: "(esc to interrupt)" or "(Press ESC to stop)"
|
|
46375
|
+
/[✻✶✳✢·✽⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]/,
|
|
46376
|
+
// Spinner characters (Claude + Droid)
|
|
46377
|
+
/Thinking\.\.\./,
|
|
46378
|
+
// Droid: "Thinking..."
|
|
46379
|
+
/Working/,
|
|
46380
|
+
// Codex: "Working"
|
|
46381
|
+
/Forming|Noodling|Manifesting/i
|
|
46382
|
+
// Claude Code thinking states
|
|
46383
|
+
],
|
|
46384
|
+
/**
|
|
46385
|
+
* Patterns indicating tool execution started.
|
|
46386
|
+
* Tertiary verification - proves the CLI is working.
|
|
46387
|
+
*/
|
|
46388
|
+
TOOL_EXECUTION_PATTERNS: [
|
|
46389
|
+
/⏺\s*(Bash|Read|Write|Edit|Glob|Grep|Task|WebFetch)/,
|
|
46390
|
+
// Claude Code tool markers
|
|
46391
|
+
/•\s*Running/
|
|
46392
|
+
// Codex: "• Running: command"
|
|
46393
|
+
]
|
|
46394
|
+
};
|
|
46312
46395
|
function hashWorkspaceId(workspaceId) {
|
|
46313
46396
|
return (0, import_node_crypto9.createHash)("sha256").update(workspaceId).digest("hex").slice(0, 12);
|
|
46314
46397
|
}
|
|
@@ -46331,6 +46414,7 @@ var RelayPtyOrchestrator = class extends BaseWrapper {
|
|
|
46331
46414
|
outputBuffer = "";
|
|
46332
46415
|
rawBuffer = "";
|
|
46333
46416
|
lastParsedLength = 0;
|
|
46417
|
+
bufferTrimCount = 0;
|
|
46334
46418
|
// Interactive mode (show output to terminal)
|
|
46335
46419
|
isInteractive = false;
|
|
46336
46420
|
// Injection state
|
|
@@ -46879,13 +46963,19 @@ Stderr: ${stderrBuffer.slice(0, 500)}` : "";
|
|
|
46879
46963
|
this.rawBuffer += data;
|
|
46880
46964
|
this.outputBuffer += data;
|
|
46881
46965
|
this.hasReceivedOutput = true;
|
|
46966
|
+
let buffersTrimmed = false;
|
|
46882
46967
|
if (this.rawBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
|
|
46883
46968
|
const trimAmount = this.rawBuffer.length - MAX_OUTPUT_BUFFER_SIZE;
|
|
46884
46969
|
this.rawBuffer = this.rawBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
|
|
46885
46970
|
this.lastParsedLength = Math.max(0, this.lastParsedLength - trimAmount);
|
|
46971
|
+
buffersTrimmed = true;
|
|
46886
46972
|
}
|
|
46887
46973
|
if (this.outputBuffer.length > MAX_OUTPUT_BUFFER_SIZE) {
|
|
46888
46974
|
this.outputBuffer = this.outputBuffer.slice(-MAX_OUTPUT_BUFFER_SIZE);
|
|
46975
|
+
buffersTrimmed = true;
|
|
46976
|
+
}
|
|
46977
|
+
if (buffersTrimmed) {
|
|
46978
|
+
this.bufferTrimCount += 1;
|
|
46889
46979
|
}
|
|
46890
46980
|
this.feedIdleDetectorOutput(data);
|
|
46891
46981
|
const indicator = this.formatUnreadIndicator();
|
|
@@ -48129,14 +48219,103 @@ Then output: \`->relay-file:spawn\`
|
|
|
48129
48219
|
this.relayPtyProcess.stdin.write(buffer);
|
|
48130
48220
|
}
|
|
48131
48221
|
/**
|
|
48132
|
-
*
|
|
48222
|
+
* Verify that the CLI shows activity after task injection.
|
|
48223
|
+
* Checks output for patterns indicating the task was received and processing started.
|
|
48224
|
+
*
|
|
48225
|
+
* This catches the race condition where PTY write succeeds but CLI wasn't ready
|
|
48226
|
+
* (the T-003 failure scenario where CLI showed bell characters instead of processing).
|
|
48227
|
+
*
|
|
48228
|
+
* @param outputBefore The output buffer content before injection
|
|
48229
|
+
* @returns Promise resolving to true if activity detected, false otherwise
|
|
48230
|
+
*/
|
|
48231
|
+
async verifyActivityAfterInjection(outputBefore) {
|
|
48232
|
+
const startTime = Date.now();
|
|
48233
|
+
const { TIMEOUT_MS, POLL_INTERVAL_MS, TASK_RECEIVED_PATTERNS, THINKING_PATTERNS, TOOL_EXECUTION_PATTERNS } = ACTIVITY_VERIFICATION;
|
|
48234
|
+
const trimCountBefore = this.bufferTrimCount;
|
|
48235
|
+
while (Date.now() - startTime < TIMEOUT_MS) {
|
|
48236
|
+
if (this.bufferTrimCount !== trimCountBefore) {
|
|
48237
|
+
this.log(` Activity verified: output buffer trimmed during verification (large output)`);
|
|
48238
|
+
return true;
|
|
48239
|
+
}
|
|
48240
|
+
const currentOutput = this.outputBuffer;
|
|
48241
|
+
const newOutput = currentOutput.slice(outputBefore.length);
|
|
48242
|
+
if (newOutput.length > 0) {
|
|
48243
|
+
const belCount = (newOutput.match(/\x07/g) || []).length;
|
|
48244
|
+
if (belCount > 10) {
|
|
48245
|
+
this.logError(` Input rejected: CLI produced ${belCount} BEL characters`);
|
|
48246
|
+
return false;
|
|
48247
|
+
}
|
|
48248
|
+
for (const pattern of TASK_RECEIVED_PATTERNS) {
|
|
48249
|
+
if (pattern.test(newOutput)) {
|
|
48250
|
+
this.log(` Activity verified: task received pattern matched`);
|
|
48251
|
+
return true;
|
|
48252
|
+
}
|
|
48253
|
+
}
|
|
48254
|
+
for (const pattern of THINKING_PATTERNS) {
|
|
48255
|
+
if (pattern.test(newOutput)) {
|
|
48256
|
+
this.log(` Activity verified: thinking pattern matched`);
|
|
48257
|
+
return true;
|
|
48258
|
+
}
|
|
48259
|
+
}
|
|
48260
|
+
for (const pattern of TOOL_EXECUTION_PATTERNS) {
|
|
48261
|
+
if (pattern.test(newOutput)) {
|
|
48262
|
+
this.log(` Activity verified: tool execution pattern matched`);
|
|
48263
|
+
return true;
|
|
48264
|
+
}
|
|
48265
|
+
}
|
|
48266
|
+
const meaningfulOutput = newOutput.replace(/[\x00-\x1f]/g, "");
|
|
48267
|
+
if (meaningfulOutput.length > 100) {
|
|
48268
|
+
this.log(` Activity verified: significant output growth (${meaningfulOutput.length} meaningful chars)`);
|
|
48269
|
+
return true;
|
|
48270
|
+
}
|
|
48271
|
+
}
|
|
48272
|
+
await sleep(POLL_INTERVAL_MS);
|
|
48273
|
+
}
|
|
48274
|
+
this.log(` No activity detected within ${TIMEOUT_MS}ms`);
|
|
48275
|
+
return false;
|
|
48276
|
+
}
|
|
48277
|
+
/**
|
|
48278
|
+
* Inject a task using the socket-based injection system with activity verification.
|
|
48133
48279
|
* This is the preferred method for spawned agent task delivery.
|
|
48134
48280
|
*
|
|
48281
|
+
* After socket confirms delivery, verifies the CLI shows activity (task received,
|
|
48282
|
+
* thinking indicators, or tool execution). Retries if no activity is detected.
|
|
48283
|
+
*
|
|
48135
48284
|
* @param task The task text to inject
|
|
48136
48285
|
* @param from The sender name (default: "spawner")
|
|
48137
|
-
* @returns Promise resolving to true if
|
|
48286
|
+
* @returns Promise resolving to true if task was delivered AND activity verified, false otherwise
|
|
48138
48287
|
*/
|
|
48139
48288
|
async injectTask(task, from = "spawner") {
|
|
48289
|
+
const { MAX_RETRIES, RETRY_DELAY_MS } = ACTIVITY_VERIFICATION;
|
|
48290
|
+
const STABILIZATION_DELAY_MS = 1500;
|
|
48291
|
+
this.log(` Waiting ${STABILIZATION_DELAY_MS}ms for CLI stabilization before task injection`);
|
|
48292
|
+
await sleep(STABILIZATION_DELAY_MS);
|
|
48293
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
48294
|
+
if (attempt > 0) {
|
|
48295
|
+
this.log(` Retry ${attempt}/${MAX_RETRIES} - waiting ${RETRY_DELAY_MS}ms before retry`);
|
|
48296
|
+
await sleep(RETRY_DELAY_MS);
|
|
48297
|
+
}
|
|
48298
|
+
const outputBefore = this.outputBuffer;
|
|
48299
|
+
const delivered = await this.performTaskInjection(task, from);
|
|
48300
|
+
if (!delivered) {
|
|
48301
|
+
this.logError(` Task delivery failed on attempt ${attempt + 1}`);
|
|
48302
|
+
continue;
|
|
48303
|
+
}
|
|
48304
|
+
const activityVerified = await this.verifyActivityAfterInjection(outputBefore);
|
|
48305
|
+
if (activityVerified) {
|
|
48306
|
+
this.log(` Task delivered and activity verified successfully`);
|
|
48307
|
+
return true;
|
|
48308
|
+
}
|
|
48309
|
+
this.logError(` Task delivered but no activity detected (attempt ${attempt + 1})`);
|
|
48310
|
+
}
|
|
48311
|
+
this.logError(` Task injection failed after ${MAX_RETRIES + 1} attempts - no CLI activity detected`);
|
|
48312
|
+
return false;
|
|
48313
|
+
}
|
|
48314
|
+
/**
|
|
48315
|
+
* Perform a single task injection attempt (without retry logic).
|
|
48316
|
+
* @returns true if the injection was sent successfully, false otherwise
|
|
48317
|
+
*/
|
|
48318
|
+
async performTaskInjection(task, from) {
|
|
48140
48319
|
if (!this.socket || !this.socketConnected) {
|
|
48141
48320
|
this.log(` Socket not connected for task injection, falling back to stdin write`);
|
|
48142
48321
|
try {
|
|
@@ -48389,6 +48568,12 @@ var openCodeApi = new OpenCodeApi();
|
|
|
48389
48568
|
|
|
48390
48569
|
// packages/wrapper/dist/opencode-wrapper.js
|
|
48391
48570
|
var import_node_child_process4 = require("node:child_process");
|
|
48571
|
+
var TASK_INJECTION = {
|
|
48572
|
+
/** Maximum retries when injection fails */
|
|
48573
|
+
MAX_RETRIES: 3,
|
|
48574
|
+
/** Delay between retries (ms) */
|
|
48575
|
+
RETRY_DELAY_MS: 500
|
|
48576
|
+
};
|
|
48392
48577
|
var OpenCodeWrapper = class extends BaseWrapper {
|
|
48393
48578
|
config;
|
|
48394
48579
|
// OpenCode API client
|
|
@@ -48644,19 +48829,32 @@ var OpenCodeWrapper = class extends BaseWrapper {
|
|
|
48644
48829
|
}
|
|
48645
48830
|
}
|
|
48646
48831
|
/**
|
|
48647
|
-
* Inject a task into the agent
|
|
48832
|
+
* Inject a task into the agent with retry logic.
|
|
48833
|
+
*
|
|
48834
|
+
* Retries on transient failures to match RelayPtyOrchestrator behavior.
|
|
48835
|
+
* This ensures consistent reliability across all wrapper types.
|
|
48836
|
+
*
|
|
48648
48837
|
* @param task - The task description to inject
|
|
48649
48838
|
* @param _from - The sender name (used for formatting)
|
|
48650
|
-
* @returns true if injection succeeded
|
|
48839
|
+
* @returns true if injection succeeded, false otherwise
|
|
48651
48840
|
*/
|
|
48652
48841
|
async injectTask(task, _from) {
|
|
48653
|
-
|
|
48654
|
-
|
|
48655
|
-
|
|
48656
|
-
|
|
48657
|
-
|
|
48658
|
-
|
|
48842
|
+
const { MAX_RETRIES, RETRY_DELAY_MS } = TASK_INJECTION;
|
|
48843
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
48844
|
+
if (attempt > 0) {
|
|
48845
|
+
console.log(`[OpenCodeWrapper] Retry ${attempt}/${MAX_RETRIES} - waiting ${RETRY_DELAY_MS}ms before retry`);
|
|
48846
|
+
await sleep(RETRY_DELAY_MS);
|
|
48847
|
+
}
|
|
48848
|
+
try {
|
|
48849
|
+
await this.performInjection(task);
|
|
48850
|
+
console.log(`[OpenCodeWrapper] Task delivered successfully${attempt > 0 ? ` (attempt ${attempt + 1})` : ""}`);
|
|
48851
|
+
return true;
|
|
48852
|
+
} catch (error2) {
|
|
48853
|
+
console.error(`[OpenCodeWrapper] Task delivery failed (attempt ${attempt + 1}/${MAX_RETRIES + 1}):`, error2);
|
|
48854
|
+
}
|
|
48659
48855
|
}
|
|
48856
|
+
console.error(`[OpenCodeWrapper] Task injection failed after ${MAX_RETRIES + 1} attempts`);
|
|
48857
|
+
return false;
|
|
48660
48858
|
}
|
|
48661
48859
|
/**
|
|
48662
48860
|
* Get output lines (for compatibility with spawner)
|
|
@@ -65364,8 +65562,9 @@ ${relayInstructions}`;
|
|
|
65364
65562
|
}
|
|
65365
65563
|
if (task && task.trim()) {
|
|
65366
65564
|
const ready = await openCodeWrapper.waitUntilReadyForMessages(2e4, 100);
|
|
65565
|
+
let taskSent = false;
|
|
65367
65566
|
if (ready) {
|
|
65368
|
-
|
|
65567
|
+
taskSent = await openCodeWrapper.injectTask(task, spawnerName || "spawner");
|
|
65369
65568
|
if (!taskSent) {
|
|
65370
65569
|
log3.warn(`Failed to inject task for ${name} via OpenCodeWrapper`);
|
|
65371
65570
|
} else if (debug) {
|
|
@@ -65374,6 +65573,25 @@ ${relayInstructions}`;
|
|
|
65374
65573
|
} else {
|
|
65375
65574
|
log3.warn(`OpenCodeWrapper ${name} not ready for task injection`);
|
|
65376
65575
|
}
|
|
65576
|
+
if (!taskSent) {
|
|
65577
|
+
const tracedError = createTraceableError("Task injection failed", {
|
|
65578
|
+
agentName: name,
|
|
65579
|
+
cli,
|
|
65580
|
+
taskLength: task.length,
|
|
65581
|
+
ready
|
|
65582
|
+
});
|
|
65583
|
+
log3.error(`CRITICAL: ${tracedError.logMessage}`);
|
|
65584
|
+
await openCodeWrapper.stop();
|
|
65585
|
+
if (this.onClearSpawning) {
|
|
65586
|
+
this.onClearSpawning(name);
|
|
65587
|
+
}
|
|
65588
|
+
return {
|
|
65589
|
+
success: false,
|
|
65590
|
+
name,
|
|
65591
|
+
error: tracedError.userMessage,
|
|
65592
|
+
errorId: tracedError.errorId
|
|
65593
|
+
};
|
|
65594
|
+
}
|
|
65377
65595
|
}
|
|
65378
65596
|
const workerInfo2 = {
|
|
65379
65597
|
name,
|
|
@@ -65514,7 +65732,7 @@ ${relayInstructions}`;
|
|
|
65514
65732
|
log3.debug(`Task injected to ${name} (attempt ${attempt})`);
|
|
65515
65733
|
break;
|
|
65516
65734
|
} else {
|
|
65517
|
-
throw new Error("Task injection returned false");
|
|
65735
|
+
throw new Error("Task injection returned false - delivery failed");
|
|
65518
65736
|
}
|
|
65519
65737
|
} catch (err) {
|
|
65520
65738
|
log3.debug(`Attempt ${attempt}/${maxRetries}: Error injecting task for ${name}: ${err.message}`);
|
|
@@ -65531,6 +65749,17 @@ ${relayInstructions}`;
|
|
|
65531
65749
|
taskLength: task.length
|
|
65532
65750
|
});
|
|
65533
65751
|
log3.error(`CRITICAL: ${tracedError.logMessage}`);
|
|
65752
|
+
await pty.stop();
|
|
65753
|
+
this.activeWorkers.delete(name);
|
|
65754
|
+
if (this.onClearSpawning) {
|
|
65755
|
+
this.onClearSpawning(name);
|
|
65756
|
+
}
|
|
65757
|
+
return {
|
|
65758
|
+
success: false,
|
|
65759
|
+
name,
|
|
65760
|
+
error: tracedError.userMessage,
|
|
65761
|
+
errorId: tracedError.errorId
|
|
65762
|
+
};
|
|
65534
65763
|
}
|
|
65535
65764
|
}
|
|
65536
65765
|
const workerInfo = {
|
|
@@ -73037,6 +73266,9 @@ var Daemon = class _Daemon {
|
|
|
73037
73266
|
}
|
|
73038
73267
|
this.notifyCloudSync();
|
|
73039
73268
|
this.writeConnectedAgentsFile();
|
|
73269
|
+
if (connection.agentName) {
|
|
73270
|
+
this.broadcastAgentReady(connection);
|
|
73271
|
+
}
|
|
73040
73272
|
};
|
|
73041
73273
|
connection.onClose = () => {
|
|
73042
73274
|
daemonLog.debug("Connection closed", { agent: connection.agentName ?? connection.id });
|
|
@@ -73610,6 +73842,31 @@ var Daemon = class _Daemon {
|
|
|
73610
73842
|
broadcastSystemMessage(message, data) {
|
|
73611
73843
|
this.router.broadcastSystemMessage(message, data);
|
|
73612
73844
|
}
|
|
73845
|
+
/**
|
|
73846
|
+
* Broadcast AGENT_READY event when an agent completes connection.
|
|
73847
|
+
* This allows spawning clients to know when their spawned agent is ready to receive messages.
|
|
73848
|
+
*/
|
|
73849
|
+
broadcastAgentReady(connection) {
|
|
73850
|
+
const payload = {
|
|
73851
|
+
name: connection.agentName,
|
|
73852
|
+
cli: connection.cli,
|
|
73853
|
+
task: connection.task,
|
|
73854
|
+
connectedAt: Date.now()
|
|
73855
|
+
};
|
|
73856
|
+
const envelope = {
|
|
73857
|
+
v: PROTOCOL_VERSION,
|
|
73858
|
+
type: "AGENT_READY",
|
|
73859
|
+
id: generateId2(),
|
|
73860
|
+
ts: Date.now(),
|
|
73861
|
+
payload
|
|
73862
|
+
};
|
|
73863
|
+
for (const conn of this.connections) {
|
|
73864
|
+
if (conn.id !== connection.id && conn.state === "ACTIVE") {
|
|
73865
|
+
conn.send(envelope);
|
|
73866
|
+
}
|
|
73867
|
+
}
|
|
73868
|
+
daemonLog.info("Broadcast AGENT_READY", { agent: connection.agentName });
|
|
73869
|
+
}
|
|
73613
73870
|
/**
|
|
73614
73871
|
* Get connection count.
|
|
73615
73872
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "Real-time agent-to-agent communication system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -130,25 +130,25 @@
|
|
|
130
130
|
},
|
|
131
131
|
"homepage": "https://github.com/AgentWorkforce/relay#readme",
|
|
132
132
|
"dependencies": {
|
|
133
|
-
"@agent-relay/bridge": "2.1.
|
|
134
|
-
"@agent-relay/config": "2.1.
|
|
135
|
-
"@agent-relay/continuity": "2.1.
|
|
136
|
-
"@agent-relay/daemon": "2.1.
|
|
137
|
-
"@agent-relay/hooks": "2.1.
|
|
138
|
-
"@agent-relay/mcp": "2.1.
|
|
139
|
-
"@agent-relay/protocol": "2.1.
|
|
140
|
-
"@agent-relay/resiliency": "2.1.
|
|
141
|
-
"@agent-relay/sdk": "2.1.
|
|
142
|
-
"@agent-relay/spawner": "2.1.
|
|
143
|
-
"@agent-relay/state": "2.1.
|
|
144
|
-
"@agent-relay/storage": "2.1.
|
|
145
|
-
"@agent-relay/telemetry": "2.1.
|
|
146
|
-
"@agent-relay/trajectory": "2.1.
|
|
147
|
-
"@agent-relay/user-directory": "2.1.
|
|
148
|
-
"@agent-relay/utils": "2.1.
|
|
149
|
-
"@agent-relay/wrapper": "2.1.
|
|
133
|
+
"@agent-relay/bridge": "2.1.6",
|
|
134
|
+
"@agent-relay/config": "2.1.6",
|
|
135
|
+
"@agent-relay/continuity": "2.1.6",
|
|
136
|
+
"@agent-relay/daemon": "2.1.6",
|
|
137
|
+
"@agent-relay/hooks": "2.1.6",
|
|
138
|
+
"@agent-relay/mcp": "2.1.6",
|
|
139
|
+
"@agent-relay/protocol": "2.1.6",
|
|
140
|
+
"@agent-relay/resiliency": "2.1.6",
|
|
141
|
+
"@agent-relay/sdk": "2.1.6",
|
|
142
|
+
"@agent-relay/spawner": "2.1.6",
|
|
143
|
+
"@agent-relay/state": "2.1.6",
|
|
144
|
+
"@agent-relay/storage": "2.1.6",
|
|
145
|
+
"@agent-relay/telemetry": "2.1.6",
|
|
146
|
+
"@agent-relay/trajectory": "2.1.6",
|
|
147
|
+
"@agent-relay/user-directory": "2.1.6",
|
|
148
|
+
"@agent-relay/utils": "2.1.6",
|
|
149
|
+
"@agent-relay/wrapper": "2.1.6",
|
|
150
150
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
151
|
-
"agent-trajectories": "^0.
|
|
151
|
+
"agent-trajectories": "^0.3.0",
|
|
152
152
|
"chokidar": "^5.0.0",
|
|
153
153
|
"commander": "^12.1.0",
|
|
154
154
|
"compare-versions": "^6.1.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-relay/benchmark",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "Performance benchmarking for agent swarms, sub-agents, and single agents using Harbor",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"directory": "packages/benchmark"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@agent-relay/sdk": "2.1.
|
|
58
|
-
"@agent-relay/protocol": "2.1.
|
|
59
|
-
"@agent-relay/spawner": "2.1.
|
|
57
|
+
"@agent-relay/sdk": "2.1.6",
|
|
58
|
+
"@agent-relay/protocol": "2.1.6",
|
|
59
|
+
"@agent-relay/spawner": "2.1.6",
|
|
60
60
|
"commander": "^12.1.0",
|
|
61
61
|
"yaml": "^2.3.4"
|
|
62
62
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../src/spawner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../src/spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -962,8 +962,9 @@ export class AgentSpawner {
|
|
|
962
962
|
// Send task to the newly spawned agent if provided
|
|
963
963
|
if (task && task.trim()) {
|
|
964
964
|
const ready = await openCodeWrapper.waitUntilReadyForMessages(20000, 100);
|
|
965
|
+
let taskSent = false;
|
|
965
966
|
if (ready) {
|
|
966
|
-
|
|
967
|
+
taskSent = await openCodeWrapper.injectTask(task, spawnerName || 'spawner');
|
|
967
968
|
if (!taskSent) {
|
|
968
969
|
log.warn(`Failed to inject task for ${name} via OpenCodeWrapper`);
|
|
969
970
|
}
|
|
@@ -974,6 +975,27 @@ export class AgentSpawner {
|
|
|
974
975
|
else {
|
|
975
976
|
log.warn(`OpenCodeWrapper ${name} not ready for task injection`);
|
|
976
977
|
}
|
|
978
|
+
// If task injection failed, kill the agent and return error
|
|
979
|
+
// An agent without its task is useless and will just sit idle
|
|
980
|
+
if (!taskSent) {
|
|
981
|
+
const tracedError = createTraceableError('Task injection failed', {
|
|
982
|
+
agentName: name,
|
|
983
|
+
cli,
|
|
984
|
+
taskLength: task.length,
|
|
985
|
+
ready,
|
|
986
|
+
});
|
|
987
|
+
log.error(`CRITICAL: ${tracedError.logMessage}`);
|
|
988
|
+
await openCodeWrapper.stop();
|
|
989
|
+
if (this.onClearSpawning) {
|
|
990
|
+
this.onClearSpawning(name);
|
|
991
|
+
}
|
|
992
|
+
return {
|
|
993
|
+
success: false,
|
|
994
|
+
name,
|
|
995
|
+
error: tracedError.userMessage,
|
|
996
|
+
errorId: tracedError.errorId,
|
|
997
|
+
};
|
|
998
|
+
}
|
|
977
999
|
}
|
|
978
1000
|
// Track the worker (cast to AgentWrapper for type compatibility)
|
|
979
1001
|
const workerInfo = {
|
|
@@ -1133,7 +1155,7 @@ export class AgentSpawner {
|
|
|
1133
1155
|
// Fallback for older wrapper types
|
|
1134
1156
|
await pty.waitUntilCliReady(15000, 100);
|
|
1135
1157
|
}
|
|
1136
|
-
// Inject task via socket (
|
|
1158
|
+
// Inject task via socket (relay-pty confirms write)
|
|
1137
1159
|
const success = await pty.injectTask(task, spawnerName || 'spawner');
|
|
1138
1160
|
if (success) {
|
|
1139
1161
|
taskSent = true;
|
|
@@ -1142,7 +1164,8 @@ export class AgentSpawner {
|
|
|
1142
1164
|
break;
|
|
1143
1165
|
}
|
|
1144
1166
|
else {
|
|
1145
|
-
|
|
1167
|
+
// Delivery failed - safe to retry
|
|
1168
|
+
throw new Error('Task injection returned false - delivery failed');
|
|
1146
1169
|
}
|
|
1147
1170
|
}
|
|
1148
1171
|
catch (err) {
|
|
@@ -1162,8 +1185,19 @@ export class AgentSpawner {
|
|
|
1162
1185
|
taskLength: task.length,
|
|
1163
1186
|
});
|
|
1164
1187
|
log.error(`CRITICAL: ${tracedError.logMessage}`);
|
|
1165
|
-
//
|
|
1166
|
-
//
|
|
1188
|
+
// Kill the agent since it's useless without its task - it will just sit idle
|
|
1189
|
+
// Return an error so the caller knows the spawn effectively failed
|
|
1190
|
+
await pty.stop();
|
|
1191
|
+
this.activeWorkers.delete(name);
|
|
1192
|
+
if (this.onClearSpawning) {
|
|
1193
|
+
this.onClearSpawning(name);
|
|
1194
|
+
}
|
|
1195
|
+
return {
|
|
1196
|
+
success: false,
|
|
1197
|
+
name,
|
|
1198
|
+
error: tracedError.userMessage,
|
|
1199
|
+
errorId: tracedError.errorId,
|
|
1200
|
+
};
|
|
1167
1201
|
}
|
|
1168
1202
|
}
|
|
1169
1203
|
// Track the worker
|