dsh-interconnect 0.11.9 → 0.11.11

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.
@@ -1287,10 +1287,22 @@ var InterconnectService = class extends Service {
1287
1287
  }
1288
1288
  this.sendFrame(socket, { type: "query-result", reqId, result });
1289
1289
  }
1290
- /** Surface one remote notification to local listeners and the log. */
1290
+ /**
1291
+ * Surface one remote notification to local listeners and the log.
1292
+ *
1293
+ * `ctx.parallel` is used instead of `ctx.emit`: `emit` maps listeners without
1294
+ * awaiting them, so a listener that returns a rejected promise would surface
1295
+ * as an unhandled rejection, while `parallel` settles every listener and
1296
+ * aggregates their failures.
1297
+ */
1291
1298
  receiveEvent(eventPayload) {
1292
- this.ctx.logger.info(`interconnect: remote event ${eventPayload.notification.kind} from ${eventPayload.sender}`);
1293
- this.ctx.emit("interconnect/event", eventPayload.notification, eventPayload.sender);
1299
+ const { notification, sender } = eventPayload;
1300
+ this.ctx.logger.info(`interconnect: remote event ${notification.kind} from ${sender}`);
1301
+ void this.ctx.parallel("interconnect/event", notification, sender).catch((error) => {
1302
+ const reasons = error instanceof AggregateError ? error.errors : [error];
1303
+ const detail = reasons.map((reason) => reason instanceof Error ? reason.message : String(reason)).join("; ");
1304
+ this.ctx.logger.warn(`interconnect: listener for a ${notification.kind} event from ${sender} threw: ${detail}`);
1305
+ });
1294
1306
  }
1295
1307
  /**
1296
1308
  * Summarize the live local sessions so a sender can discover valid targets
@@ -1528,15 +1540,7 @@ var InterconnectService = class extends Service {
1528
1540
  return;
1529
1541
  }
1530
1542
  if (frame.type === "event") {
1531
- const sender = this.peerOf.get(socket) ?? "unknown-peer";
1532
- const kind = frame.notification.kind;
1533
- try {
1534
- this.receiveEvent({ sender, notification: frame.notification });
1535
- } catch (error) {
1536
- this.ctx.logger.warn(
1537
- `interconnect: listener for a ${kind} event from ${sender} threw: ` + (error instanceof Error ? error.message : String(error))
1538
- );
1539
- }
1543
+ this.receiveEvent({ sender: this.peerOf.get(socket) ?? "unknown-peer", notification: frame.notification });
1540
1544
  return;
1541
1545
  }
1542
1546
  if (frame.type === "msg-result") {
@@ -1775,7 +1779,7 @@ function apply(ctx) {
1775
1779
  const interconnect = ctx.interconnect;
1776
1780
  ctx.tools.register(defineTool({
1777
1781
  name: "interconnect_send",
1778
- description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session). Returns whether the peer instance received it and which instance answered. Only a session with a running agent receives directly; a persisted one can be woken by setting resume, and when delivery fails the result reports the reason (for example "session-not-live") and interconnect_list shows which sessions are live there. The sending instance and session ids are attached automatically, so the receiver can reply with interconnect_reply; do not pass a sender parameter.',
1782
+ description: 'Deliver one text message to a live session on another DSH instance (same machine, another machine, or another session). Returns whether the peer instance received it and which instance answered. Only a live session receives directly; a persisted one can be woken by setting resume, and when delivery fails the result reports the reason (for example "session-not-live") and interconnect_list shows which sessions are live there. The sending instance and session ids are attached automatically, so the receiver can reply with interconnect_reply; do not pass a sender parameter.',
1779
1783
  parameters: {
1780
1784
  instanceId: {
1781
1785
  type: "string",
@@ -1799,7 +1803,7 @@ function apply(ctx) {
1799
1803
  },
1800
1804
  resume: {
1801
1805
  type: "boolean",
1802
- description: `Wake the target session if it is persisted but has no running agent. Off by default because delivery to a woken session starts a real agent turn \u2014 a billed model call with that session's full toolset \u2014 in a conversation nobody is watching. Prefer interconnect_list and an already-live target; set this only when that specific session must be reached. The receiver may refuse, answering reason "resume-refused".`
1806
+ description: `Wake the target session if it is persisted but not live. Off by default because delivery to a woken session starts a real agent turn \u2014 a billed model call with that session's full toolset \u2014 in a conversation nobody is watching. Prefer interconnect_list and an already-live target; set this only when that specific session must be reached. The receiver may refuse, answering reason "resume-refused".`
1803
1807
  }
1804
1808
  },
1805
1809
  output: {
@@ -1814,7 +1818,7 @@ function apply(ctx) {
1814
1818
  const text = (() => {
1815
1819
  switch (value.reason) {
1816
1820
  case "unreachable":
1817
- return `not delivered: ${value.instance} did not answer (unreachable or unauthorized)`;
1821
+ return `not delivered: ${value.instance} did not answer (unreachable); retrying may succeed`;
1818
1822
  case "resume-refused":
1819
1823
  return `not delivered: ${value.instance} does not allow waking persisted sessions`;
1820
1824
  case "resume-failed":
@@ -1866,7 +1870,7 @@ function apply(ctx) {
1866
1870
  },
1867
1871
  render: (_args, value) => [{
1868
1872
  type: "text",
1869
- text: value.reachable ? `reachable: ${value.instance ?? "(unknown instance)"}` : "unreachable or unauthorized"
1873
+ text: value.reachable ? `reachable: ${value.instance ?? "(unknown instance)"}` : "unreachable"
1870
1874
  }]
1871
1875
  },
1872
1876
  async execute(args, exec) {
@@ -1877,7 +1881,7 @@ function apply(ctx) {
1877
1881
  }));
1878
1882
  ctx.tools.register(defineTool({
1879
1883
  name: "interconnect_list",
1880
- description: "List the live sessions on a peer DSH instance, so a message can be addressed without knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at the time of the call. Only sessions with a running agent appear, and a long listing stops at a size bound, so a live session missing from it may simply not fit; reaching a persisted session requires interconnect_send with resume set.",
1884
+ description: "List the live sessions on a peer DSH instance, so a message can be addressed without knowing a session id in advance. Every returned sessionId is a valid interconnect_send target at the time of the call. Only live sessions appear, and a long listing stops at a size bound, so a live session missing from it may simply not fit; reaching a persisted session requires interconnect_send with resume set.",
1881
1885
  parameters: {
1882
1886
  instanceId: {
1883
1887
  type: "string",
@@ -1907,7 +1911,7 @@ function apply(ctx) {
1907
1911
  }
1908
1912
  },
1909
1913
  render: (_args, value) => {
1910
- if (!value.reachable) return [{ type: "text", text: "unreachable or unauthorized" }];
1914
+ if (!value.reachable) return [{ type: "text", text: "unreachable" }];
1911
1915
  const sessions = value.sessions ?? [];
1912
1916
  if (sessions.length === 0) {
1913
1917
  return [{ type: "text", text: `no live sessions on ${value.instance ?? "(unknown instance)"}` }];
@@ -1955,7 +1959,7 @@ function apply(ctx) {
1955
1959
  },
1956
1960
  resume: {
1957
1961
  type: "boolean",
1958
- description: "Wake the target session if it is persisted but has no running agent, as in interconnect_send. Off by default; the receiver may refuse."
1962
+ description: "Wake the target session if it is persisted but not live, as in interconnect_send. Off by default; the receiver may refuse."
1959
1963
  }
1960
1964
  },
1961
1965
  output: {
@@ -1975,7 +1979,7 @@ function apply(ctx) {
1975
1979
  return "not delivered: the recorded sender's session belongs to a subagent and its parent agent owns delivery";
1976
1980
  }
1977
1981
  if (value.reason === "unreachable") {
1978
- return "not delivered: the recorded sender did not answer (unreachable or unauthorized)";
1982
+ return "not delivered: the recorded sender did not answer (unreachable); retrying may succeed";
1979
1983
  }
1980
1984
  if (value.reason === "resume-refused") {
1981
1985
  return "not delivered: the recorded sender does not allow waking persisted sessions";