@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.
Files changed (2) hide show
  1. package/dist/relay.mjs +69 -21
  2. 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.7" },
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.7" },
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
- logger.debug(`Child MCP session closed: ${sid2}`);
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: `Claude SDK query timed out after ${timeoutMs}ms`
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.7" });
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.7";
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.7",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "description": "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI with MCP-based multi-layer sub-agent orchestration",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",