@rk0429/agentic-relay 2.0.7 → 2.0.8
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/dist/relay.mjs +69 -21
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -1085,7 +1085,16 @@ function buildContextFromEnv() {
|
|
|
1085
1085
|
const depth = Number(process.env["RELAY_DEPTH"] ?? "0");
|
|
1086
1086
|
return { traceId, parentSessionId, depth };
|
|
1087
1087
|
}
|
|
1088
|
-
async function executeSpawnAgent(input, registry2, sessionManager2, guard, hooksEngine2, contextMonitor2, backendSelector, childHttpUrl, onProgress, agentEventStore, hookMemoryDir = "./memory", taskCompleter, taskLifecycleManager, relayContext) {
|
|
1088
|
+
async function executeSpawnAgent(input, registry2, sessionManager2, guard, hooksEngine2, contextMonitor2, backendSelector, childHttpUrl, onProgress, agentEventStore, hookMemoryDir = "./memory", taskCompleter, taskLifecycleManager, relayContext, signal) {
|
|
1089
|
+
if (signal?.aborted) {
|
|
1090
|
+
return {
|
|
1091
|
+
sessionId: "",
|
|
1092
|
+
exitCode: 1,
|
|
1093
|
+
stdout: "",
|
|
1094
|
+
stderr: "Spawn cancelled: parent session disconnected",
|
|
1095
|
+
failureReason: "unknown"
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1089
1098
|
onProgress?.({ stage: "initializing", percent: 0 });
|
|
1090
1099
|
let inlineTaskId;
|
|
1091
1100
|
if (input.title && taskLifecycleManager) {
|
|
@@ -1405,7 +1414,8 @@ ${input.prompt}`;
|
|
|
1405
1414
|
maxDepth: guard.getConfig().maxDepth,
|
|
1406
1415
|
traceId: envContext.traceId
|
|
1407
1416
|
},
|
|
1408
|
-
...mcpServers ? { mcpServers } : {}
|
|
1417
|
+
...mcpServers ? { mcpServers } : {},
|
|
1418
|
+
...signal ? { signal } : {}
|
|
1409
1419
|
});
|
|
1410
1420
|
}
|
|
1411
1421
|
})();
|
|
@@ -1853,7 +1863,7 @@ var init_conflict_detector = __esm({
|
|
|
1853
1863
|
});
|
|
1854
1864
|
|
|
1855
1865
|
// src/mcp-server/tools/spawn-agents-parallel.ts
|
|
1856
|
-
async function executeSpawnAgentsParallel(agents, registry2, sessionManager2, guard, hooksEngine2, contextMonitor2, backendSelector, childHttpUrl, onProgress, agentEventStore, hookMemoryDir = "./memory", taskCompleter, taskLifecycleManager, relayContext) {
|
|
1866
|
+
async function executeSpawnAgentsParallel(agents, registry2, sessionManager2, guard, hooksEngine2, contextMonitor2, backendSelector, childHttpUrl, onProgress, agentEventStore, hookMemoryDir = "./memory", taskCompleter, taskLifecycleManager, relayContext, signal) {
|
|
1857
1867
|
for (let index = 0; index < agents.length; index += 1) {
|
|
1858
1868
|
try {
|
|
1859
1869
|
resolveValidatedSessionMetadata(agents[index]);
|
|
@@ -1939,7 +1949,8 @@ async function executeSpawnAgentsParallel(agents, registry2, sessionManager2, gu
|
|
|
1939
1949
|
hookMemoryDir,
|
|
1940
1950
|
taskCompleter,
|
|
1941
1951
|
taskLifecycleManager,
|
|
1942
|
-
relayContext
|
|
1952
|
+
relayContext,
|
|
1953
|
+
signal
|
|
1943
1954
|
).then((result) => {
|
|
1944
1955
|
completedCount++;
|
|
1945
1956
|
onProgress?.({
|
|
@@ -8442,7 +8453,7 @@ var init_server = __esm({
|
|
|
8442
8453
|
this.agentEventStore
|
|
8443
8454
|
);
|
|
8444
8455
|
this.server = new McpServer(
|
|
8445
|
-
{ name: "agentic-relay", version: "2.0.
|
|
8456
|
+
{ name: "agentic-relay", version: "2.0.8" },
|
|
8446
8457
|
createMcpServerOptions()
|
|
8447
8458
|
);
|
|
8448
8459
|
this.registerTools(this.server);
|
|
@@ -8474,7 +8485,7 @@ var init_server = __esm({
|
|
|
8474
8485
|
* Run spawn_agent in the background and store the result in taskStore.
|
|
8475
8486
|
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
8476
8487
|
*/
|
|
8477
|
-
runSpawnAgentInBackground(taskId, params, extra, relayContext) {
|
|
8488
|
+
runSpawnAgentInBackground(taskId, params, extra, relayContext, signal) {
|
|
8478
8489
|
const run = async () => {
|
|
8479
8490
|
try {
|
|
8480
8491
|
const result = await executeSpawnAgent(
|
|
@@ -8491,7 +8502,8 @@ var init_server = __esm({
|
|
|
8491
8502
|
this.hookMemoryDir,
|
|
8492
8503
|
void 0,
|
|
8493
8504
|
this.taskLifecycleManager,
|
|
8494
|
-
relayContext
|
|
8505
|
+
relayContext,
|
|
8506
|
+
signal
|
|
8495
8507
|
);
|
|
8496
8508
|
const controlOptions = {
|
|
8497
8509
|
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
@@ -8532,7 +8544,7 @@ var init_server = __esm({
|
|
|
8532
8544
|
* Run spawn_agents_parallel in the background and store the result in taskStore.
|
|
8533
8545
|
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
8534
8546
|
*/
|
|
8535
|
-
runSpawnAgentsParallelInBackground(taskId, agents, extra, relayContext) {
|
|
8547
|
+
runSpawnAgentsParallelInBackground(taskId, agents, extra, relayContext, signal) {
|
|
8536
8548
|
const run = async () => {
|
|
8537
8549
|
try {
|
|
8538
8550
|
const result = await executeSpawnAgentsParallel(
|
|
@@ -8549,7 +8561,8 @@ var init_server = __esm({
|
|
|
8549
8561
|
this.hookMemoryDir,
|
|
8550
8562
|
void 0,
|
|
8551
8563
|
this.taskLifecycleManager,
|
|
8552
|
-
relayContext
|
|
8564
|
+
relayContext,
|
|
8565
|
+
signal
|
|
8553
8566
|
);
|
|
8554
8567
|
const controlOptions = {
|
|
8555
8568
|
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
@@ -8585,7 +8598,7 @@ var init_server = __esm({
|
|
|
8585
8598
|
};
|
|
8586
8599
|
void run();
|
|
8587
8600
|
}
|
|
8588
|
-
registerTools(server, relayContext) {
|
|
8601
|
+
registerTools(server, relayContext, signal) {
|
|
8589
8602
|
server.experimental.tasks.registerToolTask(
|
|
8590
8603
|
"spawn_agent",
|
|
8591
8604
|
{
|
|
@@ -8599,7 +8612,7 @@ var init_server = __esm({
|
|
|
8599
8612
|
ttl: DEFAULT_TASK_TTL,
|
|
8600
8613
|
pollInterval: DEFAULT_POLL_INTERVAL
|
|
8601
8614
|
});
|
|
8602
|
-
this.runSpawnAgentInBackground(task.taskId, params, extra, relayContext);
|
|
8615
|
+
this.runSpawnAgentInBackground(task.taskId, params, extra, relayContext, signal);
|
|
8603
8616
|
return { task };
|
|
8604
8617
|
},
|
|
8605
8618
|
getTask: async (_params, extra) => {
|
|
@@ -8625,7 +8638,7 @@ var init_server = __esm({
|
|
|
8625
8638
|
ttl: DEFAULT_TASK_TTL,
|
|
8626
8639
|
pollInterval: DEFAULT_POLL_INTERVAL
|
|
8627
8640
|
});
|
|
8628
|
-
this.runSpawnAgentsParallelInBackground(task.taskId, params.agents, extra, relayContext);
|
|
8641
|
+
this.runSpawnAgentsParallelInBackground(task.taskId, params.agents, extra, relayContext, signal);
|
|
8629
8642
|
return { task };
|
|
8630
8643
|
},
|
|
8631
8644
|
getTask: async (_params, extra) => {
|
|
@@ -8664,7 +8677,8 @@ var init_server = __esm({
|
|
|
8664
8677
|
this.hookMemoryDir,
|
|
8665
8678
|
void 0,
|
|
8666
8679
|
this.taskLifecycleManager,
|
|
8667
|
-
relayContext
|
|
8680
|
+
relayContext,
|
|
8681
|
+
signal
|
|
8668
8682
|
);
|
|
8669
8683
|
const controlOptions = {
|
|
8670
8684
|
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
@@ -8936,6 +8950,7 @@ var init_server = __esm({
|
|
|
8936
8950
|
*/
|
|
8937
8951
|
async startChildHttpServer() {
|
|
8938
8952
|
const sessions = /* @__PURE__ */ new Map();
|
|
8953
|
+
const sessionAbortControllers = /* @__PURE__ */ new Map();
|
|
8939
8954
|
const httpServer = createServer(async (req, res) => {
|
|
8940
8955
|
const url = req.url ?? "";
|
|
8941
8956
|
if (url !== "/mcp" && !url.startsWith("/mcp?")) {
|
|
@@ -8952,19 +8967,27 @@ var init_server = __esm({
|
|
|
8952
8967
|
}
|
|
8953
8968
|
}
|
|
8954
8969
|
const childRelayContext = extractRelayContextFromUrl(url);
|
|
8970
|
+
const abortController = new AbortController();
|
|
8955
8971
|
const transport = new StreamableHTTPServerTransport({
|
|
8956
8972
|
sessionIdGenerator: () => randomUUID()
|
|
8957
8973
|
});
|
|
8958
8974
|
const server = new McpServer(
|
|
8959
|
-
{ name: "agentic-relay", version: "2.0.
|
|
8975
|
+
{ name: "agentic-relay", version: "2.0.8" },
|
|
8960
8976
|
createMcpServerOptions()
|
|
8961
8977
|
);
|
|
8962
|
-
this.registerTools(server, childRelayContext);
|
|
8978
|
+
this.registerTools(server, childRelayContext, abortController.signal);
|
|
8963
8979
|
transport.onclose = () => {
|
|
8964
8980
|
const sid2 = transport.sessionId;
|
|
8965
8981
|
if (sid2) {
|
|
8966
8982
|
sessions.delete(sid2);
|
|
8967
|
-
|
|
8983
|
+
const ctrl = sessionAbortControllers.get(sid2);
|
|
8984
|
+
if (ctrl) {
|
|
8985
|
+
ctrl.abort();
|
|
8986
|
+
sessionAbortControllers.delete(sid2);
|
|
8987
|
+
logger.debug(`Child MCP session closed, background tasks aborted: ${sid2}`);
|
|
8988
|
+
} else {
|
|
8989
|
+
logger.debug(`Child MCP session closed: ${sid2}`);
|
|
8990
|
+
}
|
|
8968
8991
|
}
|
|
8969
8992
|
};
|
|
8970
8993
|
await server.connect(transport);
|
|
@@ -8972,12 +8995,18 @@ var init_server = __esm({
|
|
|
8972
8995
|
const sid = transport.sessionId;
|
|
8973
8996
|
if (sid) {
|
|
8974
8997
|
sessions.set(sid, { transport, server });
|
|
8998
|
+
sessionAbortControllers.set(sid, abortController);
|
|
8975
8999
|
logger.debug(`Child MCP session created: ${sid}`);
|
|
8976
9000
|
if (sessions.size > MAX_CHILD_HTTP_SESSIONS) {
|
|
8977
9001
|
const oldestEntry = sessions.entries().next().value;
|
|
8978
9002
|
if (oldestEntry) {
|
|
8979
9003
|
const [oldestSessionId, oldestSession] = oldestEntry;
|
|
8980
9004
|
sessions.delete(oldestSessionId);
|
|
9005
|
+
const evictedCtrl = sessionAbortControllers.get(oldestSessionId);
|
|
9006
|
+
if (evictedCtrl) {
|
|
9007
|
+
evictedCtrl.abort();
|
|
9008
|
+
sessionAbortControllers.delete(oldestSessionId);
|
|
9009
|
+
}
|
|
8981
9010
|
logger.warn(
|
|
8982
9011
|
`Child MCP session evicted due to limit (${MAX_CHILD_HTTP_SESSIONS}): ${oldestSessionId}`
|
|
8983
9012
|
);
|
|
@@ -10635,6 +10664,14 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
10635
10664
|
const timeoutMs = resolveClaudeSdkTimeoutMs();
|
|
10636
10665
|
const abortController = new AbortController();
|
|
10637
10666
|
const timer = timeoutMs !== void 0 ? setTimeout(() => abortController.abort(), timeoutMs) : void 0;
|
|
10667
|
+
const onExternalAbort = () => abortController.abort();
|
|
10668
|
+
if (flags.signal) {
|
|
10669
|
+
if (flags.signal.aborted) {
|
|
10670
|
+
abortController.abort();
|
|
10671
|
+
} else {
|
|
10672
|
+
flags.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
10673
|
+
}
|
|
10674
|
+
}
|
|
10638
10675
|
try {
|
|
10639
10676
|
const { query } = await loadClaudeSDK();
|
|
10640
10677
|
const options = {
|
|
@@ -10705,10 +10742,11 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
10705
10742
|
};
|
|
10706
10743
|
} catch (error) {
|
|
10707
10744
|
if (abortController.signal.aborted) {
|
|
10745
|
+
const reason = flags.signal?.aborted ? "Claude execution cancelled: parent session disconnected" : `Claude SDK query timed out after ${timeoutMs}ms`;
|
|
10708
10746
|
return {
|
|
10709
10747
|
exitCode: 1,
|
|
10710
10748
|
stdout: "",
|
|
10711
|
-
stderr:
|
|
10749
|
+
stderr: reason
|
|
10712
10750
|
};
|
|
10713
10751
|
}
|
|
10714
10752
|
return {
|
|
@@ -10718,6 +10756,7 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
10718
10756
|
};
|
|
10719
10757
|
} finally {
|
|
10720
10758
|
if (timer !== void 0) clearTimeout(timer);
|
|
10759
|
+
flags.signal?.removeEventListener("abort", onExternalAbort);
|
|
10721
10760
|
}
|
|
10722
10761
|
}
|
|
10723
10762
|
async *executeStreaming(flags) {
|
|
@@ -11307,7 +11346,9 @@ ${prompt}`;
|
|
|
11307
11346
|
workingDirectory: process.cwd(),
|
|
11308
11347
|
approvalPolicy: "never"
|
|
11309
11348
|
});
|
|
11310
|
-
const result = await thread.run(effectivePrompt
|
|
11349
|
+
const result = await thread.run(effectivePrompt, {
|
|
11350
|
+
...flags.signal ? { signal: flags.signal } : {}
|
|
11351
|
+
});
|
|
11311
11352
|
return {
|
|
11312
11353
|
exitCode: 0,
|
|
11313
11354
|
stdout: result.finalResponse,
|
|
@@ -11320,6 +11361,13 @@ ${prompt}`;
|
|
|
11320
11361
|
} : {}
|
|
11321
11362
|
};
|
|
11322
11363
|
} catch (error) {
|
|
11364
|
+
if (flags.signal?.aborted) {
|
|
11365
|
+
return {
|
|
11366
|
+
exitCode: 1,
|
|
11367
|
+
stdout: "",
|
|
11368
|
+
stderr: "Codex execution cancelled: parent session disconnected"
|
|
11369
|
+
};
|
|
11370
|
+
}
|
|
11323
11371
|
return {
|
|
11324
11372
|
exitCode: 1,
|
|
11325
11373
|
stdout: "",
|
|
@@ -13569,7 +13617,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
|
|
|
13569
13617
|
responseOutputDir,
|
|
13570
13618
|
relayConfig
|
|
13571
13619
|
);
|
|
13572
|
-
await server.start({ transport, port, currentVersion: "2.0.
|
|
13620
|
+
await server.start({ transport, port, currentVersion: "2.0.8" });
|
|
13573
13621
|
}
|
|
13574
13622
|
})
|
|
13575
13623
|
},
|
|
@@ -13729,7 +13777,7 @@ function createVersionCommand(registry2) {
|
|
|
13729
13777
|
description: "Show relay and backend versions"
|
|
13730
13778
|
},
|
|
13731
13779
|
async run() {
|
|
13732
|
-
const relayVersion = "2.0.
|
|
13780
|
+
const relayVersion = "2.0.8";
|
|
13733
13781
|
console.log(`agentic-relay v${relayVersion}`);
|
|
13734
13782
|
console.log("");
|
|
13735
13783
|
console.log("Backends:");
|
|
@@ -14126,7 +14174,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
|
|
|
14126
14174
|
var main = defineCommand11({
|
|
14127
14175
|
meta: {
|
|
14128
14176
|
name: "relay",
|
|
14129
|
-
version: "2.0.
|
|
14177
|
+
version: "2.0.8",
|
|
14130
14178
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
14131
14179
|
},
|
|
14132
14180
|
args: {
|
package/package.json
CHANGED