@bastani/atomic 0.9.43 → 0.9.44-alpha.2

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 (137) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +22 -0
  3. package/dist/builtin/intercom/broker/broker.ts +31 -7
  4. package/dist/builtin/intercom/broker/client-message-validation.ts +6 -0
  5. package/dist/builtin/intercom/broker/client.ts +69 -0
  6. package/dist/builtin/intercom/broker/send-signature.ts +4 -1
  7. package/dist/builtin/intercom/index.bundle.mjs +309 -109
  8. package/dist/builtin/intercom/live-route-refusal.ts +20 -0
  9. package/dist/builtin/intercom/package.json +1 -1
  10. package/dist/builtin/intercom/skills/intercom/SKILL.md +11 -6
  11. package/dist/builtin/intercom/types.ts +28 -1
  12. package/dist/builtin/mcp/CHANGELOG.md +7 -0
  13. package/dist/builtin/mcp/package.json +1 -1
  14. package/dist/builtin/subagents/CHANGELOG.md +9 -0
  15. package/dist/builtin/subagents/README.md +8 -8
  16. package/dist/builtin/subagents/agents/worker.md +1 -1
  17. package/dist/builtin/subagents/package.json +1 -1
  18. package/dist/builtin/subagents/skills/agent-browser/SKILL.md +1 -1
  19. package/dist/builtin/subagents/skills/cua-driver/EMBEDDING.md +21 -2
  20. package/dist/builtin/subagents/skills/cua-driver/LINUX.md +2 -2
  21. package/dist/builtin/subagents/skills/cua-driver/MACOS.md +342 -10
  22. package/dist/builtin/subagents/skills/cua-driver/README.md +4 -3
  23. package/dist/builtin/subagents/skills/cua-driver/RUNTIME.md +3 -1
  24. package/dist/builtin/subagents/skills/cua-driver/SKILL.md +7 -4
  25. package/dist/builtin/subagents/skills/cua-driver/WINDOWS.md +6 -5
  26. package/dist/builtin/subagents/skills/cua-driver/WORKFLOW.md +15 -0
  27. package/dist/builtin/subagents/skills/herdr/SKILL.md +22 -10
  28. package/dist/builtin/subagents/skills/subagent/SKILL.md +8 -5
  29. package/dist/builtin/subagents/src/extension/index.bundle.mjs +6 -6
  30. package/dist/builtin/web-access/package.json +1 -1
  31. package/dist/builtin/workflows/CHANGELOG.md +20 -0
  32. package/dist/builtin/workflows/README.md +1 -1
  33. package/dist/builtin/workflows/builtin/{chunk-frqxd4d1.js → chunk-k8d7ehjx.js} +22 -0
  34. package/dist/builtin/workflows/builtin/{chunk-3s95f7ry.js → chunk-qxpymnaf.js} +1 -1
  35. package/dist/builtin/workflows/builtin/{chunk-edhf30ef.js → chunk-zjecnjxx.js} +1 -1
  36. package/dist/builtin/workflows/builtin/goal.js +2 -2
  37. package/dist/builtin/workflows/builtin/index.js +3 -3
  38. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  39. package/dist/builtin/workflows/package.json +1 -1
  40. package/dist/builtin/workflows/src/extension/index.bundle.mjs +1844 -603
  41. package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +1880 -605
  42. package/dist/builtin/workflows/src/index.js +1896 -655
  43. package/dist/builtin/workflows/src/local-worker-entry.mjs +1880 -605
  44. package/dist/cli/args.js +1 -1
  45. package/dist/cli/args.js.map +1 -1
  46. package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
  47. package/dist/core/agent-session-custom-message-commit.js +59 -0
  48. package/dist/core/agent-session-custom-message-commit.js.map +1 -1
  49. package/dist/core/agent-session-methods.d.ts +1 -0
  50. package/dist/core/agent-session-methods.d.ts.map +1 -1
  51. package/dist/core/agent-session-methods.js.map +1 -1
  52. package/dist/core/agent-session-prompt.d.ts +4 -0
  53. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  54. package/dist/core/agent-session-prompt.js +10 -2
  55. package/dist/core/agent-session-prompt.js.map +1 -1
  56. package/dist/core/agent-session.d.ts +2 -0
  57. package/dist/core/agent-session.d.ts.map +1 -1
  58. package/dist/core/agent-session.js +9 -0
  59. package/dist/core/agent-session.js.map +1 -1
  60. package/dist/core/builtin-packages.d.ts.map +1 -1
  61. package/dist/core/builtin-packages.js +13 -13
  62. package/dist/core/builtin-packages.js.map +1 -1
  63. package/dist/core/exec.d.ts.map +1 -1
  64. package/dist/core/exec.js +11 -2
  65. package/dist/core/exec.js.map +1 -1
  66. package/dist/core/package-manager-resolver.d.ts.map +1 -1
  67. package/dist/core/package-manager-resolver.js +25 -14
  68. package/dist/core/package-manager-resolver.js.map +1 -1
  69. package/dist/core/package-manager-types.d.ts +8 -0
  70. package/dist/core/package-manager-types.d.ts.map +1 -1
  71. package/dist/core/package-manager-types.js.map +1 -1
  72. package/dist/core/package-manager.d.ts +1 -1
  73. package/dist/core/package-manager.d.ts.map +1 -1
  74. package/dist/core/package-manager.js.map +1 -1
  75. package/dist/core/resource-loader-extension-warnings.d.ts +4 -1
  76. package/dist/core/resource-loader-extension-warnings.d.ts.map +1 -1
  77. package/dist/core/resource-loader-extension-warnings.js +15 -0
  78. package/dist/core/resource-loader-extension-warnings.js.map +1 -1
  79. package/dist/core/resource-loader-package-resources.d.ts.map +1 -1
  80. package/dist/core/resource-loader-package-resources.js +1 -0
  81. package/dist/core/resource-loader-package-resources.js.map +1 -1
  82. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  83. package/dist/core/resource-loader-reload.js +5 -3
  84. package/dist/core/resource-loader-reload.js.map +1 -1
  85. package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
  86. package/dist/extensions/mcp/client/oauth/flow.js +4 -1
  87. package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
  88. package/dist/extensions/mcp/client/oauth/types.d.ts +1 -0
  89. package/dist/extensions/mcp/client/oauth/types.d.ts.map +1 -1
  90. package/dist/extensions/mcp/client/oauth/types.js +8 -4
  91. package/dist/extensions/mcp/client/oauth/types.js.map +1 -1
  92. package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -1
  93. package/dist/extensions/mcp/client/transports/streamable-http.js +2 -1
  94. package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -1
  95. package/dist/index.d.ts +1 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js.map +1 -1
  98. package/dist/main.d.ts.map +1 -1
  99. package/dist/main.js +20 -10
  100. package/dist/main.js.map +1 -1
  101. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  102. package/dist/modes/interactive/components/model-selector.js +4 -2
  103. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  104. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  105. package/dist/modes/interactive/components/scoped-models-selector.js +4 -2
  106. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  107. package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  108. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  109. package/dist/modes/interactive/components/tool-execution.js +11 -1
  110. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  111. package/dist/modes/interactive/model-search.d.ts +10 -0
  112. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  113. package/dist/modes/interactive/model-search.js +21 -0
  114. package/dist/modes/interactive/model-search.js.map +1 -1
  115. package/dist/package-manager-cli.d.ts.map +1 -1
  116. package/dist/package-manager-cli.js +5 -0
  117. package/dist/package-manager-cli.js.map +1 -1
  118. package/dist/utils/tools-manager.d.ts.map +1 -1
  119. package/dist/utils/tools-manager.js +30 -35
  120. package/dist/utils/tools-manager.js.map +1 -1
  121. package/docs/computer-use.md +5 -5
  122. package/docs/custom-provider/streaming.md +9 -14
  123. package/docs/environment-variables.md +1 -0
  124. package/docs/intercom/operations.md +1 -1
  125. package/docs/intercom.md +16 -2
  126. package/docs/packages.md +2 -0
  127. package/docs/settings.md +2 -2
  128. package/docs/skills.md +2 -2
  129. package/docs/subagents.md +47 -10
  130. package/docs/workflows/api-reference.md +1 -1
  131. package/docs/workflows/authoring.md +1 -1
  132. package/docs/workflows/operations.md +8 -6
  133. package/docs/workflows/reliable-design.md +23 -5
  134. package/examples/extensions/custom-provider-anthropic/index.ts +31 -31
  135. package/examples/extensions/todo.ts +7 -0
  136. package/npm-shrinkwrap.json +32 -32
  137. package/package.json +3 -3
@@ -99,7 +99,13 @@ function isLiveWorkflowStageRouteRefusalCode(value) {
99
99
  function isTransientLiveWorkflowStageRouteRefusal(code) {
100
100
  return TRANSIENT_REFUSAL_CODES.has(code);
101
101
  }
102
- var LIVE_WORKFLOW_STAGE_ROUTE_REFUSAL_CODES, LIVE_WORKFLOW_STAGE_ROUTE_REFUSAL_REASONS, TRANSIENT_REFUSAL_CODES, IntercomLiveRouteRefusedError;
102
+ function liveRouteOwnerRetryDelayMs(attempt) {
103
+ return Math.min(LIVE_ROUTE_OWNER_RETRY_FIRST_MS * 2 ** attempt, LIVE_ROUTE_OWNER_RETRY_MAX_MS);
104
+ }
105
+ function isOwnerMissingRefusal(error) {
106
+ return error instanceof IntercomLiveRouteRefusedError && error.code === "owner_missing";
107
+ }
108
+ var LIVE_WORKFLOW_STAGE_ROUTE_REFUSAL_CODES, LIVE_WORKFLOW_STAGE_ROUTE_REFUSAL_REASONS, TRANSIENT_REFUSAL_CODES, IntercomLiveRouteRefusedError, LIVE_ROUTE_OWNER_WAIT_MS = 120000, LIVE_ROUTE_OWNER_RETRY_FIRST_MS = 250, LIVE_ROUTE_OWNER_RETRY_MAX_MS = 2000;
103
109
  var init_live_route_refusal = __esm(() => {
104
110
  LIVE_WORKFLOW_STAGE_ROUTE_REFUSAL_CODES = [
105
111
  "owner_missing",
@@ -358,6 +364,8 @@ function isMessage(value) {
358
364
  return false;
359
365
  if (message.expectsReply !== undefined && typeof message.expectsReply !== "boolean")
360
366
  return false;
367
+ if (message.delivery !== undefined && message.delivery !== "steer" && message.delivery !== "followUp" && message.delivery !== "interrupt")
368
+ return false;
361
369
  if (message.replyError !== undefined && typeof message.replyError !== "string")
362
370
  return false;
363
371
  if (message.source !== undefined && !isMessageSource(message.source))
@@ -683,7 +691,8 @@ function buildSendSignature(to, options) {
683
691
  attachments: canonicalizeAttachmentsForSendSignature(options.attachments) ?? [],
684
692
  replyTo: options.replyTo ?? null,
685
693
  expectsReply: options.expectsReply ?? false,
686
- replyError: options.replyError ?? null
694
+ replyError: options.replyError ?? null,
695
+ ...options.delivery === undefined || options.delivery === "steer" ? {} : { delivery: options.delivery }
687
696
  });
688
697
  }
689
698
 
@@ -908,7 +917,7 @@ function isWorkflowFutureStageRosterEntries(value) {
908
917
  function isWorkflowStageRosterEntries(value) {
909
918
  return Array.isArray(value) && value.every((entry) => typeof entry === "object" && entry !== null && entry.kind === "workflow-stage" && typeof entry.runId === "string" && typeof entry.stageId === "string" && typeof entry.stageName === "string" && typeof entry.target === "string" && (entry.lifecycle === "pending" || entry.lifecycle === "running") && typeof entry.group === "string" && (entry.sessionId === undefined || typeof entry.sessionId === "string"));
910
919
  }
911
- var BROKER_SOCKET, BROKER_CONNECT_TIMEOUT_MS = 1e4, PENDING_STAGE_ROUTE_ACK_TIMEOUT_MS = 1e4, GROUP_REQUEST_TIMEOUT_MS = 5000, PRESENCE_ACK_TIMEOUT_MS = 5000, RESTORING_RECIPIENT_REQUEST_TIMEOUT_MS = 5000, HELD_SEND_GRACE_MS = 5000, IntercomClient;
920
+ var BROKER_SOCKET, BROKER_CONNECT_TIMEOUT_MS = 1e4, PENDING_STAGE_ROUTE_ACK_TIMEOUT_MS = 1e4, GROUP_REQUEST_TIMEOUT_MS = 5000, PRESENCE_ACK_TIMEOUT_MS = 5000, RESTORING_RECIPIENT_REQUEST_TIMEOUT_MS = 5000, HELD_SEND_GRACE_MS = 5000, IntercomPendingStageRouteRefusedError, PENDING_STAGE_ROUTE_REFUSAL_CODES, IntercomClient;
912
921
  var init_client = __esm(() => {
913
922
  init_paths();
914
923
  init_pending_send_registry();
@@ -917,6 +926,21 @@ var init_client = __esm(() => {
917
926
  init_live_route_refusal();
918
927
  init_retry_policy();
919
928
  BROKER_SOCKET = getBrokerSocketPath();
929
+ IntercomPendingStageRouteRefusedError = class IntercomPendingStageRouteRefusedError extends Error {
930
+ connectionKept;
931
+ code;
932
+ constructor(reason, refusal = { connectionKept: false }) {
933
+ super(reason);
934
+ this.name = "IntercomPendingStageRouteRefusedError";
935
+ this.connectionKept = refusal.connectionKept;
936
+ this.code = refusal.code;
937
+ }
938
+ };
939
+ PENDING_STAGE_ROUTE_REFUSAL_CODES = new Set([
940
+ "not_authorized",
941
+ "invalid_stage_roster",
942
+ "invalid_possible_stage_roster"
943
+ ]);
920
944
  IntercomClient = class IntercomClient extends EventEmitter {
921
945
  returnAddress;
922
946
  preferredSessionId;
@@ -924,6 +948,8 @@ var init_client = __esm(() => {
924
948
  connectTimeoutMs;
925
949
  brokerAcknowledgesReceipt = false;
926
950
  brokerAcknowledgesPendingStageRoutes = false;
951
+ multiplexesPendingStageRoutes;
952
+ brokerRefusesPendingStageRoutesInPlace = false;
927
953
  brokerAnswersStatus = false;
928
954
  socket = null;
929
955
  _sessionId = null;
@@ -989,6 +1015,7 @@ var init_client = __esm(() => {
989
1015
  this.preferredSessionId = options.preferredSessionId;
990
1016
  this.acknowledgesReceipt = options.acknowledgesReceipt === true;
991
1017
  this.connectTimeoutMs = options.connectTimeoutMs ?? BROKER_CONNECT_TIMEOUT_MS;
1018
+ this.multiplexesPendingStageRoutes = options.multiplexesPendingStageRoutes === true;
992
1019
  }
993
1020
  failPending(error) {
994
1021
  this.pendingSends.rejectAll(error);
@@ -1101,6 +1128,7 @@ var init_client = __esm(() => {
1101
1128
  this._supervisorSessionId = null;
1102
1129
  this.brokerAcknowledgesReceipt = false;
1103
1130
  this.brokerAcknowledgesPendingStageRoutes = false;
1131
+ this.brokerRefusesPendingStageRoutesInPlace = false;
1104
1132
  this.brokerAnswersStatus = false;
1105
1133
  this._messageSource = undefined;
1106
1134
  this.disconnectError = null;
@@ -1179,7 +1207,7 @@ var init_client = __esm(() => {
1179
1207
  }
1180
1208
  switch (brokerMessage.type) {
1181
1209
  case "registered": {
1182
- if (typeof brokerMessage.sessionId !== "string" || brokerMessage.supervisorSessionId !== undefined && typeof brokerMessage.supervisorSessionId !== "string" || brokerMessage.acknowledgesReceipt !== undefined && brokerMessage.acknowledgesReceipt !== true || brokerMessage.acknowledgesPendingStageRoutes !== undefined && brokerMessage.acknowledgesPendingStageRoutes !== true || brokerMessage.brokerStatus !== undefined && brokerMessage.brokerStatus !== true) {
1210
+ if (typeof brokerMessage.sessionId !== "string" || brokerMessage.supervisorSessionId !== undefined && typeof brokerMessage.supervisorSessionId !== "string" || brokerMessage.acknowledgesReceipt !== undefined && brokerMessage.acknowledgesReceipt !== true || brokerMessage.acknowledgesPendingStageRoutes !== undefined && brokerMessage.acknowledgesPendingStageRoutes !== true || brokerMessage.refusesPendingStageRoutesInPlace !== undefined && brokerMessage.refusesPendingStageRoutesInPlace !== true || brokerMessage.brokerStatus !== undefined && brokerMessage.brokerStatus !== true) {
1183
1211
  throw new Error("Invalid registered message");
1184
1212
  }
1185
1213
  if (this._sessionId !== null) {
@@ -1189,6 +1217,7 @@ var init_client = __esm(() => {
1189
1217
  this._supervisorSessionId = typeof brokerMessage.supervisorSessionId === "string" ? brokerMessage.supervisorSessionId : null;
1190
1218
  this.brokerAcknowledgesReceipt = this.acknowledgesReceipt && brokerMessage.acknowledgesReceipt === true;
1191
1219
  this.brokerAcknowledgesPendingStageRoutes = brokerMessage.acknowledgesPendingStageRoutes === true;
1220
+ this.brokerRefusesPendingStageRoutesInPlace = brokerMessage.refusesPendingStageRoutesInPlace === true;
1192
1221
  this.brokerAnswersStatus = brokerMessage.brokerStatus === true;
1193
1222
  this.emit("_registered", { type: "registered", sessionId: brokerMessage.sessionId });
1194
1223
  break;
@@ -1201,6 +1230,12 @@ var init_client = __esm(() => {
1201
1230
  this.emit("_registration_failed", refusal);
1202
1231
  break;
1203
1232
  }
1233
+ const refusedRouteId = typeof brokerMessage.requestId === "string" ? brokerMessage.requestId : "";
1234
+ const refusedRoute = this.pendingStageRouteRegistrations.get(refusedRouteId);
1235
+ if (refusedRoute !== undefined) {
1236
+ this.pendingStageRouteRegistrations.delete(refusedRouteId);
1237
+ refusedRoute.reject(new IntercomPendingStageRouteRefusedError(brokerMessage.reason));
1238
+ }
1204
1239
  this.disconnectError ??= refusal;
1205
1240
  this.failPending(this.disconnectError);
1206
1241
  this.socket?.destroy();
@@ -1326,6 +1361,21 @@ var init_client = __esm(() => {
1326
1361
  this.emit("pending_stage_route_revoked", { runId });
1327
1362
  break;
1328
1363
  }
1364
+ case "pending_stage_route_refused": {
1365
+ const { requestId, runId, code, reason } = brokerMessage;
1366
+ if (typeof requestId !== "string" || typeof runId !== "string" || typeof reason !== "string" || typeof code !== "string") {
1367
+ throw new Error("Invalid pending-stage route refusal");
1368
+ }
1369
+ const pending = this.pendingStageRouteRegistrations.get(requestId);
1370
+ if (!pending)
1371
+ return;
1372
+ this.pendingStageRouteRegistrations.delete(requestId);
1373
+ pending.reject(new IntercomPendingStageRouteRefusedError(reason, {
1374
+ connectionKept: true,
1375
+ ...PENDING_STAGE_ROUTE_REFUSAL_CODES.has(code) ? { code } : {}
1376
+ }));
1377
+ break;
1378
+ }
1329
1379
  case "pending_stage_route_registered": {
1330
1380
  const { requestId } = brokerMessage;
1331
1381
  if (typeof requestId !== "string")
@@ -1829,7 +1879,8 @@ var init_client = __esm(() => {
1829
1879
  stages,
1830
1880
  possibleStages,
1831
1881
  ...parent === undefined ? {} : { parent },
1832
- ...dormant === true ? { dormant: true } : {}
1882
+ ...dormant === true ? { dormant: true } : {},
1883
+ ...this.multiplexesPendingStageRoutes && this.brokerRefusesPendingStageRoutesInPlace ? { refusalKeepsConnection: true } : {}
1833
1884
  });
1834
1885
  } catch (error) {
1835
1886
  clearTimeout(timeout);
@@ -1942,6 +1993,7 @@ var init_client = __esm(() => {
1942
1993
  timestamp: Date.now(),
1943
1994
  replyTo: options.replyTo,
1944
1995
  expectsReply: options.expectsReply,
1996
+ ...options.delivery === undefined || options.delivery === "steer" ? {} : { delivery: options.delivery },
1945
1997
  replyError: options.replyError,
1946
1998
  source: this._messageSource,
1947
1999
  content: { text: options.text, attachments: options.attachments }
@@ -2742,6 +2794,7 @@ class ReplyTracker {
2742
2794
  pendingAsks = new Map;
2743
2795
  pendingTurnContexts = [];
2744
2796
  currentTurnContext = null;
2797
+ turnContextAdmitted = false;
2745
2798
  constructor(askTimeoutMs = ASK_REPLY_TIMEOUT_MS) {
2746
2799
  this.askTimeoutMs = askTimeoutMs;
2747
2800
  }
@@ -2767,15 +2820,27 @@ class ReplyTracker {
2767
2820
  }
2768
2821
  beginTurn(now = Date.now()) {
2769
2822
  this.pruneExpired(now);
2770
- this.currentTurnContext = this.pendingTurnContexts.shift() ?? null;
2823
+ this.turnContextAdmitted = false;
2824
+ }
2825
+ admitTurnMessage(messageId) {
2826
+ if (this.currentTurnContext?.message.id === messageId) {
2827
+ this.turnContextAdmitted = true;
2828
+ return;
2829
+ }
2830
+ const index = this.pendingTurnContexts.findIndex((context) => context.message.id === messageId);
2831
+ if (index < 0)
2832
+ return;
2833
+ const [admitted] = this.pendingTurnContexts.splice(index, 1);
2834
+ if (this.turnContextAdmitted)
2835
+ return;
2836
+ this.currentTurnContext = admitted;
2837
+ this.turnContextAdmitted = true;
2771
2838
  }
2772
2839
  endTurn() {
2773
2840
  this.currentTurnContext = null;
2774
2841
  }
2775
2842
  restoreTurnContext() {
2776
- if (this.currentTurnContext)
2777
- this.pendingTurnContexts.unshift(this.currentTurnContext);
2778
- this.currentTurnContext = null;
2843
+ this.turnContextAdmitted = false;
2779
2844
  }
2780
2845
  reset() {
2781
2846
  this.pendingAsks.clear();
@@ -2824,10 +2889,11 @@ class ReplyTracker {
2824
2889
  }
2825
2890
  throw new Error(`No pending ask from "${options.to}"`);
2826
2891
  }
2827
- if (pending.length === 1) {
2828
- return pending[0];
2892
+ const visible = pending.filter((context) => !this.pendingTurnContexts.some((queued) => queued.message.id === context.message.id));
2893
+ if (visible.length === 1) {
2894
+ return visible[0];
2829
2895
  }
2830
- if (pending.length === 0) {
2896
+ if (visible.length === 0) {
2831
2897
  throw new Error("No active intercom context to reply to");
2832
2898
  }
2833
2899
  throw new Error("Multiple pending asks — specify `to`");
@@ -4030,6 +4096,10 @@ A valid target outside the known set queues speculatively with a \`notInKnownSet
4030
4096
  undeliverable at terminal only if never delivered. Use \`ask\` only for a live, reply-capable target.
4031
4097
  Stage paths win over same-named owned subgroups for send/ask; \`list\` with \`group\` continues to
4032
4098
  select the group.
4099
+ Choose \`delivery\` per send/ask by urgency. The default "steer" arrives after the recipient's current
4100
+ tool calls finish and never cancels its work. Use "interrupt" when it must stop now (an urgent correction
4101
+ or a stop order); it cancels the current model call or tool call. Use "followUp" when the message can wait
4102
+ until the recipient finishes (low priority, "after you're done"). An idle recipient starts a turn.
4033
4103
  For send/ask/reply, Intercom retries recoverable disconnects internally up to three times with the same operation identity. Each new tool call is a new operation. If recovery ends with an unknown delivery outcome, do not repeat it automatically.
4034
4104
 
4035
4105
  Usage:
@@ -4041,6 +4111,7 @@ Usage:
4041
4111
  intercom({ action: "leave" }) → Return to your resolved home group
4042
4112
  intercom({ action: "send", to: "session-name", message: "..." }) → Send message (shared group only)
4043
4113
  intercom({ action: "ask", to: "session-name", message: "..." }) → Ask and wait for reply
4114
+ intercom({ action: "send", to: "session-name", message: "...", delivery: "interrupt" }) → Cancel the recipient's current work
4044
4115
  intercom({ action: "reply", message: "..." }) → Reply to the active or exact pending ask
4045
4116
  intercom({ action: "pending" }) → List unresolved inbound asks
4046
4117
  intercom({ action: "status" }) → Show connection status and all your groups
@@ -4065,6 +4136,9 @@ one shared membership; contact_supervisor remains the only cross-group path.`,
4065
4136
  content: Type2.String(),
4066
4137
  language: Type2.Optional(Type2.String())
4067
4138
  }))),
4139
+ delivery: Type2.Optional(Type2.Union([Type2.Literal("steer"), Type2.Literal("followUp"), Type2.Literal("interrupt")], {
4140
+ description: "For 'send'/'ask'; choose per message by urgency. 'steer' (default): arrives after the recipient's current tool calls, never cancelling work. 'interrupt': the recipient must stop now (urgent correction, stop order); cancels its current model call or tool call. 'followUp': can wait until the recipient finishes (low priority, after you're done)."
4141
+ })),
4068
4142
  replyTo: Type2.Optional(Type2.String({
4069
4143
  description: "Exact pending-ask message ID or unique 8-hex UUID prefix; disambiguates concurrent asks, including asks from one sender"
4070
4144
  })),
@@ -4082,6 +4156,7 @@ one shared membership; contact_supervisor remains the only cross-group path.`,
4082
4156
  }
4083
4157
  const toolSessionId = ctx.sessionManager.getSessionId();
4084
4158
  const { action, to, message, replyTo, group } = params;
4159
+ const deliveryOption = params.delivery === undefined || params.delivery === "steer" ? {} : { delivery: params.delivery };
4085
4160
  const attachments = params.attachments?.map((attachment) => ({ ...attachment }));
4086
4161
  const executeAttempt = async (retryToken, _signal) => {
4087
4162
  if (retryToken !== undefined) {
@@ -4392,7 +4467,8 @@ ${message}${attachmentText}`);
4392
4467
  logicalTarget: to,
4393
4468
  text: message,
4394
4469
  attachments,
4395
- replyTo
4470
+ replyTo,
4471
+ ...deliveryOption
4396
4472
  });
4397
4473
  if (result.queued === true) {
4398
4474
  retryIdentities.release(retryIdentity);
@@ -4624,6 +4700,7 @@ ${message}${attachmentText}`);
4624
4700
  attachments,
4625
4701
  replyTo,
4626
4702
  expectsReply: true,
4703
+ ...deliveryOption,
4627
4704
  onReplyTarget: wait.bindSender
4628
4705
  });
4629
4706
  if (sendResult.queued === true) {
@@ -5513,6 +5590,13 @@ function registerIntercomLifecycle(pi, deps) {
5513
5590
  deps.syncPresenceIdentity(ctx.sessionManager.getSessionId());
5514
5591
  activeReplyTracker().beginTurn();
5515
5592
  });
5593
+ pi.on("message_start", (event, ctx) => {
5594
+ if (!deps.getLiveContext(ctx))
5595
+ return;
5596
+ const id = admittedIntercomMessageId(event.message, ctx);
5597
+ if (id !== undefined)
5598
+ activeReplyTracker().admitTurnMessage(id);
5599
+ });
5516
5600
  pi.on("model_select", (event, ctx) => {
5517
5601
  if (!deps.getLiveContext(ctx))
5518
5602
  return;
@@ -5527,6 +5611,25 @@ function registerIntercomLifecycle(pi, deps) {
5527
5611
  }
5528
5612
  });
5529
5613
  }
5614
+ function intercomMessageId(customType, details) {
5615
+ if (customType !== "intercom_message" || details === null || typeof details !== "object")
5616
+ return;
5617
+ const id = details.message?.id;
5618
+ return typeof id === "string" ? id : undefined;
5619
+ }
5620
+ function admittedIntercomMessageId(message, ctx) {
5621
+ const custom = message;
5622
+ if (custom?.role !== "custom")
5623
+ return;
5624
+ if (custom.customType !== PROTECTED_RECONCILIATION_CUSTOM_TYPE)
5625
+ return intercomMessageId(custom.customType, custom.details);
5626
+ const intentEntryId = custom.details?.protectedReconciliationOf;
5627
+ if (typeof intentEntryId !== "string")
5628
+ return;
5629
+ const intent = ctx.sessionManager.getEntries().find((entry) => entry.id === intentEntryId);
5630
+ return intent?.type === "custom_message" ? intercomMessageId(intent.customType, intent.details) : undefined;
5631
+ }
5632
+ var PROTECTED_RECONCILIATION_CUSTOM_TYPE = "atomic:protected-streaming-reconciliation";
5530
5633
  var init_lifecycle = __esm(() => {
5531
5634
  init_diagnostics();
5532
5635
  init_intercom_utils();
@@ -6606,8 +6709,9 @@ function createIncomingMessageSender(input) {
6606
6709
  if (!input.canDeliver(generation)) {
6607
6710
  return Promise.reject(new Error("Intercom session retired before inbound delivery"));
6608
6711
  }
6609
- const delivery = (requested === "trigger" || requested === "interrupt") && !mayStartTurn(entry) ? "prelude" : requested;
6610
- if ((delivery === "trigger" || delivery === "interrupt") && trackReplyContext && maySupplyReplyContext(entry)) {
6712
+ const startsTurn = requested === "trigger" || requested === "triggerFollowUp" || requested === "interrupt";
6713
+ const delivery = startsTurn && !mayStartTurn(entry) ? "prelude" : requested;
6714
+ if ((delivery === "trigger" || delivery === "triggerFollowUp" || delivery === "interrupt") && trackReplyContext && maySupplyReplyContext(entry)) {
6611
6715
  input.queueTurnContext(turnContext ?? { from: entry.from, message: entry.message, receivedAt: Date.now() });
6612
6716
  }
6613
6717
  const baseOptions = {
@@ -6615,7 +6719,7 @@ function createIncomingMessageSender(input) {
6615
6719
  persistWhenStreaming: true,
6616
6720
  ...stageAdmissionBarrier ? { stageAdmissionBarrier } : {}
6617
6721
  };
6618
- const options = delivery === "interrupt" ? { ...baseOptions, triggerTurn: true, deliverAs: "interrupt" } : delivery === "trigger" ? { ...baseOptions, triggerTurn: true } : delivery === "followUp" ? { ...baseOptions, deliverAs: "followUp" } : baseOptions;
6722
+ const options = delivery === "interrupt" ? { ...baseOptions, triggerTurn: true, deliverAs: "interrupt" } : delivery === "trigger" ? { ...baseOptions, triggerTurn: true } : delivery === "triggerFollowUp" ? { ...baseOptions, triggerTurn: true, deliverAs: "followUp" } : delivery === "followUp" ? { ...baseOptions, deliverAs: "followUp" } : baseOptions;
6619
6723
  return Promise.resolve(input.pi.sendMessage(buildIncomingCustomMessage(entry), options));
6620
6724
  };
6621
6725
  }
@@ -7472,6 +7576,7 @@ __export(exports_index_heavy, {
7472
7576
  });
7473
7577
  import { APP_NAME, sessionScopedExtensionState } from "@bastani/atomic";
7474
7578
  import { appendFileSync as appendFileSync2 } from "node:fs";
7579
+ import { setTimeout as delay3 } from "node:timers/promises";
7475
7580
  function isPendingStageUndeliverableEvent(value) {
7476
7581
  if (typeof value !== "object" || value === null)
7477
7582
  return false;
@@ -7543,6 +7648,7 @@ function piIntercomExtension(pi, testOverrides = {}) {
7543
7648
  const inboundDeliveries = new InboundMessageAdmission;
7544
7649
  const pendingStageRoutes = new Map;
7545
7650
  const pendingStageRouteClients = new Map;
7651
+ const pendingStageRouteConnections = new Map;
7546
7652
  const routeClientConnectGate = createConcurrencyGate(ROUTE_CLIENT_CONNECT_CONCURRENCY);
7547
7653
  const supervisorAuthorizations = new SupervisorAuthorizationRegistry;
7548
7654
  const releasedStagePeers = new ReleasedStagePeers({
@@ -7852,8 +7958,9 @@ function piIntercomExtension(pi, testOverrides = {}) {
7852
7958
  });
7853
7959
  const activeDelivery = admitActiveSessionInbound(liveContext, (admissionBarrier) => {
7854
7960
  replyTracker.queueTurnContext(replyContext);
7961
+ const delivery = message.delivery === "interrupt" ? "interrupt" : message.delivery === "followUp" ? "triggerFollowUp" : "trigger";
7855
7962
  return retryStableDelivery({
7856
- deliver: () => sendIncomingMessage(entry, "interrupt", messageGeneration, false, undefined, admissionBarrier),
7963
+ deliver: () => sendIncomingMessage(entry, delivery, messageGeneration, false, undefined, admissionBarrier),
7857
7964
  isCurrent: () => Boolean(getLiveContext(liveContext, messageGeneration)) && liveContext.subagentPolicy?.executionEnded?.aborted !== true && liveContext.subagentPolicy?.messageAdmission?.isOpen() !== false
7858
7965
  });
7859
7966
  }, () => foregroundDetachHandoff.claim(from, message, messageGeneration, () => Boolean(getLiveContext(liveContext, messageGeneration))), release);
@@ -8123,42 +8230,105 @@ function piIntercomExtension(pi, testOverrides = {}) {
8123
8230
  });
8124
8231
  }, jitteredReconnectDelayMs(state.reconnectAttempt));
8125
8232
  }
8126
- function attachPendingStageRouteClientHandlers(runId, state, nextClient) {
8233
+ function pendingStageRouteRunsOn(nextClient) {
8234
+ return [...pendingStageRouteClients].filter(([, state]) => state.client === nextClient);
8235
+ }
8236
+ function attachPendingStageRouteConnectionHandlers(connection, nextClient) {
8127
8237
  nextClient.on("pending_stage_message", (request) => {
8128
- handlePendingStageMessage(nextClient, request, () => state.client === nextClient && pendingStageRouteClientIsCurrent(runId, state));
8238
+ handlePendingStageMessage(nextClient, request, () => {
8239
+ const state = pendingStageRouteClients.get(request.runId);
8240
+ return state?.client === nextClient && pendingStageRouteClientIsCurrent(request.runId, state);
8241
+ });
8129
8242
  });
8130
8243
  nextClient.on("disconnected", () => {
8131
- if (state.client !== nextClient)
8132
- return;
8133
- state.client = null;
8134
- schedulePendingStageRouteReconnect(runId, state);
8244
+ if (connection.client === nextClient)
8245
+ connection.client = null;
8246
+ for (const [runId, state] of pendingStageRouteRunsOn(nextClient)) {
8247
+ state.client = null;
8248
+ schedulePendingStageRouteReconnect(runId, state);
8249
+ }
8135
8250
  });
8136
8251
  nextClient.on("error", () => {});
8137
8252
  nextClient.on("sticky_live_delivered", (notice) => {
8138
- if (state.client === nextClient)
8253
+ if (connection.client === nextClient)
8139
8254
  relayStickyLiveDelivered(notice);
8140
8255
  });
8141
8256
  nextClient.on("pending_stage_route_revoked", (notice) => {
8142
- if (notice.runId !== runId || state.client !== nextClient)
8257
+ const state = pendingStageRouteClients.get(notice.runId);
8258
+ if (state === undefined || state.client !== nextClient)
8143
8259
  return;
8144
8260
  state.client = null;
8145
8261
  endPendingStageRouteBackoff(state, new IntercomClientDisconnectedError);
8146
- if (pendingStageRouteClients.get(runId) === state)
8147
- pendingStageRouteClients.delete(runId);
8148
- if (samePendingStageRoute(pendingStageRoutes.get(runId), state.route))
8149
- pendingStageRoutes.delete(runId);
8150
- nextClient.disconnect().catch(() => {});
8151
- pi.events.emit(PENDING_STAGE_ROUTE_REVOKED_EVENT, { runId, capability: state.route.capability });
8262
+ pendingStageRouteClients.delete(notice.runId);
8263
+ if (samePendingStageRoute(pendingStageRoutes.get(notice.runId), state.route))
8264
+ pendingStageRoutes.delete(notice.runId);
8265
+ if (pendingStageRouteRunsOn(nextClient).length === 0)
8266
+ closePendingStageRouteConnection(nextClient);
8267
+ pi.events.emit(PENDING_STAGE_ROUTE_REVOKED_EVENT, { runId: notice.runId, capability: state.route.capability });
8152
8268
  });
8153
8269
  }
8270
+ function closePendingStageRouteConnection(nextClient) {
8271
+ for (const [key, connection] of pendingStageRouteConnections) {
8272
+ if (connection.client !== nextClient)
8273
+ continue;
8274
+ connection.client = null;
8275
+ if (connection.promise === null)
8276
+ pendingStageRouteConnections.delete(key);
8277
+ }
8278
+ nextClient.disconnect().catch(() => {});
8279
+ }
8280
+ function connectPendingStageRouteConnection(key, group) {
8281
+ let connection = pendingStageRouteConnections.get(key);
8282
+ if (connection === undefined) {
8283
+ connection = { client: null, promise: null };
8284
+ pendingStageRouteConnections.set(key, connection);
8285
+ }
8286
+ if (connection.client?.isConnected())
8287
+ return Promise.resolve(connection.client);
8288
+ if (connection.promise !== null)
8289
+ return connection.promise;
8290
+ const owner = connection;
8291
+ const promise = routeClientConnectGate.run(async () => {
8292
+ await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
8293
+ if (pendingStageRouteConnections.get(key) !== owner)
8294
+ throw new IntercomClientDisconnectedError;
8295
+ const routeReturnAddress = `${currentSessionId}:pending-stage-route:${key}`;
8296
+ const nextClient = new IntercomClient(routeReturnAddress, {
8297
+ connectTimeoutMs: testOverrides.connectTimeoutMs?.(routeReturnAddress),
8298
+ multiplexesPendingStageRoutes: true
8299
+ });
8300
+ owner.client = nextClient;
8301
+ attachPendingStageRouteConnectionHandlers(owner, nextClient);
8302
+ try {
8303
+ await nextClient.connect({ ...buildRegistration(), recipientPurpose: "control", name: undefined, groups: [group], group }, undefined, undefined, readSubagentMessageSource(runtimeContext?.subagentPolicy));
8304
+ } catch (error) {
8305
+ if (owner.client === nextClient)
8306
+ owner.client = null;
8307
+ try {
8308
+ await nextClient.disconnect();
8309
+ } catch {}
8310
+ throw error;
8311
+ }
8312
+ return nextClient;
8313
+ }).finally(() => {
8314
+ if (owner.promise === promise)
8315
+ owner.promise = null;
8316
+ });
8317
+ owner.promise = promise;
8318
+ return promise;
8319
+ }
8154
8320
  async function retirePendingStageRouteClient(state) {
8155
8321
  try {
8156
8322
  await state.promise;
8157
8323
  } catch {}
8158
- if (state.client) {
8159
- try {
8160
- await state.client.disconnect();
8161
- } catch {}
8324
+ const retiredClient = state.client;
8325
+ state.client = null;
8326
+ if (retiredClient === null)
8327
+ return;
8328
+ const group = normalizeGroup(state.route.group);
8329
+ const groupInUse = [...pendingStageRoutes.values()].some((route) => !registersOnMainClient(route) && normalizeGroup(route.group) === group);
8330
+ if ((state.isolated || !groupInUse) && pendingStageRouteRunsOn(retiredClient).length === 0) {
8331
+ closePendingStageRouteConnection(retiredClient);
8162
8332
  }
8163
8333
  }
8164
8334
  function supersededPendingStageRouteError(context, generation) {
@@ -8171,6 +8341,7 @@ function piIntercomExtension(pi, testOverrides = {}) {
8171
8341
  throw new Error("Intercom runtime not initialized");
8172
8342
  let existing = pendingStageRouteClients.get(runId);
8173
8343
  let retired;
8344
+ const isolated = existing?.isolated === true && normalizeGroup(existing.route.group) === normalizeGroup(route.group);
8174
8345
  if (existing && !samePendingStageRoute(existing.route, route)) {
8175
8346
  pendingStageRouteClients.delete(runId);
8176
8347
  endPendingStageRouteBackoff(existing, new IntercomClientDisconnectedError);
@@ -8183,13 +8354,24 @@ function piIntercomExtension(pi, testOverrides = {}) {
8183
8354
  promise: null,
8184
8355
  reconnectTimer: null,
8185
8356
  reconnectAttempt: 0,
8186
- retryWaiters: new RouteRetryWaiters
8357
+ retryWaiters: new RouteRetryWaiters,
8358
+ isolated
8187
8359
  };
8188
8360
  if (!existing)
8189
8361
  pendingStageRouteClients.set(runId, state);
8190
8362
  state.route = route;
8191
8363
  if (state.client?.isConnected()) {
8192
- await state.client.registerPendingStageRouteAcknowledged(runId, normalizeGroup(route.group), route.capability, route.stages, route.possibleStages, route.parent, route.dormant === true);
8364
+ await state.client.registerPendingStageRouteAcknowledged(runId, normalizeGroup(route.group), route.capability, route.stages, route.possibleStages, route.parent, route.dormant === true).catch((error) => {
8365
+ if (error instanceof IntercomPendingStageRouteRefusedError) {
8366
+ if (!error.connectionKept)
8367
+ state.isolated = true;
8368
+ else if (state.client !== null) {
8369
+ state.client = null;
8370
+ schedulePendingStageRouteReconnect(runId, state);
8371
+ }
8372
+ }
8373
+ throw error;
8374
+ });
8193
8375
  return;
8194
8376
  }
8195
8377
  if (state.promise) {
@@ -8198,42 +8380,31 @@ function piIntercomExtension(pi, testOverrides = {}) {
8198
8380
  }
8199
8381
  if (state.reconnectTimer !== null && options.bypassBackoff !== true)
8200
8382
  return state.retryWaiters.join();
8201
- const connect = () => routeClientConnectGate.run(async () => {
8383
+ const connect = async () => {
8202
8384
  if (!pendingStageRouteClientIsCurrent(runId, state, contextAtStart, generationAtStart)) {
8203
8385
  throw supersededPendingStageRouteError(contextAtStart, generationAtStart);
8204
8386
  }
8205
- await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
8206
- const routeReturnAddress = `${currentSessionId}:pending-stage-route:${runId}`;
8207
- const nextClient = new IntercomClient(routeReturnAddress, {
8208
- connectTimeoutMs: testOverrides.connectTimeoutMs?.(routeReturnAddress)
8209
- });
8210
- state.client = nextClient;
8211
- attachPendingStageRouteClientHandlers(runId, state, nextClient);
8212
- await nextClient.connect({ ...buildRegistration(), recipientPurpose: "control", name: undefined, groups: [normalizeGroup(route.group)], group: normalizeGroup(route.group) }, undefined, undefined, readSubagentMessageSource(runtimeContext?.subagentPolicy));
8387
+ const group = normalizeGroup(route.group);
8388
+ const nextClient = await connectPendingStageRouteConnection(state.isolated ? runId : group, group);
8213
8389
  if (!pendingStageRouteClientIsCurrent(runId, state, contextAtStart, generationAtStart)) {
8214
- await nextClient.disconnect();
8215
8390
  throw supersededPendingStageRouteError(contextAtStart, generationAtStart);
8216
8391
  }
8392
+ state.client = nextClient;
8217
8393
  await nextClient.registerPendingStageRouteAcknowledged(runId, normalizeGroup(route.group), route.capability, route.stages, route.possibleStages, route.parent, route.dormant === true);
8218
8394
  if (!pendingStageRouteClientIsCurrent(runId, state, contextAtStart, generationAtStart)) {
8219
- await nextClient.disconnect();
8220
8395
  throw supersededPendingStageRouteError(contextAtStart, generationAtStart);
8221
8396
  }
8222
8397
  state.reconnectAttempt = 0;
8223
8398
  endPendingStageRouteBackoff(state);
8224
- });
8399
+ };
8225
8400
  const promise = retired === undefined ? connect() : retired.then(connect);
8226
8401
  state.promise = promise;
8227
8402
  try {
8228
8403
  await promise;
8229
8404
  } catch (error) {
8230
- const failedClient = state.client;
8405
+ if (error instanceof IntercomPendingStageRouteRefusedError && !error.connectionKept)
8406
+ state.isolated = true;
8231
8407
  state.client = null;
8232
- if (failedClient) {
8233
- try {
8234
- await failedClient.disconnect();
8235
- } catch {}
8236
- }
8237
8408
  if (state.promise === promise)
8238
8409
  state.promise = null;
8239
8410
  schedulePendingStageRouteReconnect(runId, state);
@@ -8246,17 +8417,25 @@ function piIntercomExtension(pi, testOverrides = {}) {
8246
8417
  async function disconnectPendingStageRouteClients() {
8247
8418
  const states = [...pendingStageRouteClients.values()];
8248
8419
  pendingStageRouteClients.clear();
8420
+ const connections = [...pendingStageRouteConnections.values()];
8421
+ pendingStageRouteConnections.clear();
8249
8422
  for (const state of states) {
8250
8423
  endPendingStageRouteBackoff(state, new IntercomClientDisconnectedError);
8251
8424
  try {
8252
8425
  await state.promise;
8253
8426
  } catch {}
8254
- if (!state.client)
8427
+ state.client = null;
8428
+ }
8429
+ for (const connection of connections) {
8430
+ try {
8431
+ await connection.promise;
8432
+ } catch {}
8433
+ if (!connection.client)
8255
8434
  continue;
8256
8435
  try {
8257
- await state.client.disconnect();
8436
+ await connection.client.disconnect();
8258
8437
  } catch {}
8259
- state.client = null;
8438
+ connection.client = null;
8260
8439
  }
8261
8440
  }
8262
8441
  async function registerPendingStageRoute(activeClient, runId, route) {
@@ -8306,59 +8485,68 @@ function piIntercomExtension(pi, testOverrides = {}) {
8306
8485
  const nextReconnectPromise = (async () => {
8307
8486
  let connectFailed = false;
8308
8487
  await ownershipRecorded.promise;
8309
- const nextClient = new IntercomClient(sessionIdAtStart, {
8310
- preferredSessionId,
8311
- acknowledgesReceipt: true,
8312
- connectTimeoutMs: testOverrides.connectTimeoutMs?.(sessionIdAtStart)
8313
- });
8314
- client = nextClient;
8315
- attachClientHandlers(nextClient);
8488
+ const ownerWaitDeadline = Date.now() + LIVE_ROUTE_OWNER_WAIT_MS;
8316
8489
  try {
8317
- await testOverrides.beforeConnectAttempt?.(reason);
8318
- await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
8319
- const childMetadata = currentChildOrchestratorMetadata();
8320
- await nextClient.connect(buildRegistration(), childMetadata?.supervisor, supervisorAuthorizations.ownerToken, readSubagentMessageSource(runtimeContext?.subagentPolicy), resolveSessionHomeGroup());
8321
- clientRegistrationGroup = resolveSessionHomeGroup();
8322
- if (replyCapability() === "terminal")
8323
- nextClient.updatePresence({ replyCapability: "terminal" });
8324
- await supervisorAuthorizations.restore(nextClient);
8325
- for (const [runId, route] of pendingStageRoutes) {
8326
- if (registersOnMainClient(route)) {
8327
- await registerPendingStageRoute(nextClient, runId, route);
8328
- continue;
8329
- }
8330
- ensurePendingStageRouteClient(runId, { ...route, group: normalizeGroup(route.group) }).catch(() => {});
8331
- }
8332
- const orchestration = contextAtStart.orchestrationContext;
8333
- if (orchestration?.kind === "workflow-stage" && orchestration.pendingStageDelivery !== undefined) {
8334
- const liveStageKeys = [orchestration.workflowStageId, orchestration.workflowStageName].filter((stageKey) => !stageKey.includes("/") && !stageKey.includes("*"));
8335
- if (liveStageKeys.length > 0) {
8336
- await nextClient.registerLiveWorkflowStageRoute(orchestration.workflowRunId, liveStageKeys, orchestration.pendingStageDelivery.routeCapability);
8490
+ for (let ownerWait = 0;; ownerWait += 1) {
8491
+ const nextClient = new IntercomClient(sessionIdAtStart, {
8492
+ preferredSessionId,
8493
+ acknowledgesReceipt: true,
8494
+ connectTimeoutMs: testOverrides.connectTimeoutMs?.(sessionIdAtStart)
8495
+ });
8496
+ client = nextClient;
8497
+ attachClientHandlers(nextClient);
8498
+ try {
8499
+ await testOverrides.beforeConnectAttempt?.(reason);
8500
+ await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
8501
+ const childMetadata = currentChildOrchestratorMetadata();
8502
+ await nextClient.connect(buildRegistration(), childMetadata?.supervisor, supervisorAuthorizations.ownerToken, readSubagentMessageSource(runtimeContext?.subagentPolicy), resolveSessionHomeGroup());
8503
+ clientRegistrationGroup = resolveSessionHomeGroup();
8504
+ if (replyCapability() === "terminal")
8505
+ nextClient.updatePresence({ replyCapability: "terminal" });
8506
+ await supervisorAuthorizations.restore(nextClient);
8507
+ for (const [runId, route] of pendingStageRoutes) {
8508
+ if (registersOnMainClient(route)) {
8509
+ await registerPendingStageRoute(nextClient, runId, route);
8510
+ continue;
8511
+ }
8512
+ ensurePendingStageRouteClient(runId, { ...route, group: normalizeGroup(route.group) }).catch(() => {});
8513
+ }
8514
+ const orchestration = contextAtStart.orchestrationContext;
8515
+ if (orchestration?.kind === "workflow-stage" && orchestration.pendingStageDelivery !== undefined) {
8516
+ const liveStageKeys = [orchestration.workflowStageId, orchestration.workflowStageName].filter((stageKey) => !stageKey.includes("/") && !stageKey.includes("*"));
8517
+ if (liveStageKeys.length > 0) {
8518
+ await nextClient.registerLiveWorkflowStageRoute(orchestration.workflowRunId, liveStageKeys, orchestration.pendingStageDelivery.routeCapability);
8519
+ }
8520
+ }
8521
+ if (!getLiveContext(contextAtStart, generationAtStart)) {
8522
+ await nextClient.disconnect();
8523
+ throw new Error("Intercom runtime no longer active");
8524
+ }
8525
+ client = nextClient;
8526
+ if (nextClient.sessionId) {
8527
+ process.env[INTERCOM_SESSION_ID_ENV] = nextClient.sessionId;
8528
+ }
8529
+ reconnectAttempt = 0;
8530
+ if (nextClient.sessionId && nextClient.sessionId !== preferredSessionId) {
8531
+ await recordIntercomSessionIdentity(sessionIdAtStart, nextClient.sessionId);
8532
+ }
8533
+ return nextClient;
8534
+ } catch (error) {
8535
+ if (client === nextClient) {
8536
+ client = null;
8537
+ clientRegistrationGroup = null;
8538
+ }
8539
+ try {
8540
+ await nextClient.disconnect();
8541
+ } catch {}
8542
+ if (isOwnerMissingRefusal(error) && Date.now() < ownerWaitDeadline && !disposed && !shuttingDown && getLiveContext(contextAtStart, generationAtStart)) {
8543
+ await delay3(liveRouteOwnerRetryDelayMs(ownerWait));
8544
+ continue;
8545
+ }
8546
+ connectFailed = true;
8547
+ throw toError3(error);
8337
8548
  }
8338
8549
  }
8339
- if (!getLiveContext(contextAtStart, generationAtStart)) {
8340
- await nextClient.disconnect();
8341
- throw new Error("Intercom runtime no longer active");
8342
- }
8343
- client = nextClient;
8344
- if (nextClient.sessionId) {
8345
- process.env[INTERCOM_SESSION_ID_ENV] = nextClient.sessionId;
8346
- }
8347
- reconnectAttempt = 0;
8348
- if (nextClient.sessionId && nextClient.sessionId !== preferredSessionId) {
8349
- await recordIntercomSessionIdentity(sessionIdAtStart, nextClient.sessionId);
8350
- }
8351
- return nextClient;
8352
- } catch (error) {
8353
- if (client === nextClient) {
8354
- client = null;
8355
- clientRegistrationGroup = null;
8356
- }
8357
- connectFailed = true;
8358
- try {
8359
- await nextClient.disconnect();
8360
- } catch {}
8361
- throw toError3(error);
8362
8550
  } finally {
8363
8551
  if (reconnectPromiseGeneration === generationAtStart) {
8364
8552
  reconnectPromise = null;
@@ -8652,6 +8840,7 @@ var init_index_heavy = __esm(() => {
8652
8840
  init_runtime_group();
8653
8841
  init_reconnect_backoff();
8654
8842
  init_recoverable_disconnect();
8843
+ init_live_route_refusal();
8655
8844
  init_route_retry_waiters();
8656
8845
  init_released_stage_peers();
8657
8846
  init_supervisor_authorization_registry();
@@ -8827,7 +9016,8 @@ function createForwardedHandlerMap() {
8827
9016
  agent_end: [],
8828
9017
  tool_execution_start: [],
8829
9018
  tool_execution_end: [],
8830
- model_select: []
9019
+ model_select: [],
9020
+ message_start: []
8831
9021
  };
8832
9022
  }
8833
9023
  function addHandler(captured, event, handler) {
@@ -8861,6 +9051,9 @@ function captureForwardedHandler(captured, event, handler) {
8861
9051
  return;
8862
9052
  case "model_select":
8863
9053
  addHandler(captured, event, handler);
9054
+ return;
9055
+ case "message_start":
9056
+ addHandler(captured, event, handler);
8864
9057
  }
8865
9058
  }
8866
9059
  function addEventHandler(captured, event, handler) {
@@ -9369,6 +9562,13 @@ function intercom(pi, options = {}) {
9369
9562
  if (heavy)
9370
9563
  await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "agent_end", event, ctx));
9371
9564
  });
9565
+ pi.on("message_start", async (event, ctx) => {
9566
+ if (activeLease.retired)
9567
+ return;
9568
+ const heavy = loadedHeavy?.heavy;
9569
+ if (heavy)
9570
+ await lifecycleForward.enqueue(() => dispatchHandlers(heavy, "message_start", event, ctx));
9571
+ });
9372
9572
  pi.on("tool_execution_start", async (event, ctx) => {
9373
9573
  if (activeLease.retired)
9374
9574
  return;