@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.
- package/CHANGELOG.md +42 -0
- package/dist/builtin/intercom/CHANGELOG.md +22 -0
- package/dist/builtin/intercom/broker/broker.ts +31 -7
- package/dist/builtin/intercom/broker/client-message-validation.ts +6 -0
- package/dist/builtin/intercom/broker/client.ts +69 -0
- package/dist/builtin/intercom/broker/send-signature.ts +4 -1
- package/dist/builtin/intercom/index.bundle.mjs +309 -109
- package/dist/builtin/intercom/live-route-refusal.ts +20 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/skills/intercom/SKILL.md +11 -6
- package/dist/builtin/intercom/types.ts +28 -1
- package/dist/builtin/mcp/CHANGELOG.md +7 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +9 -0
- package/dist/builtin/subagents/README.md +8 -8
- package/dist/builtin/subagents/agents/worker.md +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/agent-browser/SKILL.md +1 -1
- package/dist/builtin/subagents/skills/cua-driver/EMBEDDING.md +21 -2
- package/dist/builtin/subagents/skills/cua-driver/LINUX.md +2 -2
- package/dist/builtin/subagents/skills/cua-driver/MACOS.md +342 -10
- package/dist/builtin/subagents/skills/cua-driver/README.md +4 -3
- package/dist/builtin/subagents/skills/cua-driver/RUNTIME.md +3 -1
- package/dist/builtin/subagents/skills/cua-driver/SKILL.md +7 -4
- package/dist/builtin/subagents/skills/cua-driver/WINDOWS.md +6 -5
- package/dist/builtin/subagents/skills/cua-driver/WORKFLOW.md +15 -0
- package/dist/builtin/subagents/skills/herdr/SKILL.md +22 -10
- package/dist/builtin/subagents/skills/subagent/SKILL.md +8 -5
- package/dist/builtin/subagents/src/extension/index.bundle.mjs +6 -6
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +20 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/builtin/{chunk-frqxd4d1.js → chunk-k8d7ehjx.js} +22 -0
- package/dist/builtin/workflows/builtin/{chunk-3s95f7ry.js → chunk-qxpymnaf.js} +1 -1
- package/dist/builtin/workflows/builtin/{chunk-edhf30ef.js → chunk-zjecnjxx.js} +1 -1
- package/dist/builtin/workflows/builtin/goal.js +2 -2
- package/dist/builtin/workflows/builtin/index.js +3 -3
- package/dist/builtin/workflows/builtin/ralph.js +2 -2
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +1844 -603
- package/dist/builtin/workflows/src/extension/local-worker-entry.mjs +1880 -605
- package/dist/builtin/workflows/src/index.js +1896 -655
- package/dist/builtin/workflows/src/local-worker-entry.mjs +1880 -605
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session-custom-message-commit.d.ts.map +1 -1
- package/dist/core/agent-session-custom-message-commit.js +59 -0
- package/dist/core/agent-session-custom-message-commit.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +1 -0
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts +4 -0
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +10 -2
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +9 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/builtin-packages.d.ts.map +1 -1
- package/dist/core/builtin-packages.js +13 -13
- package/dist/core/builtin-packages.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +11 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/package-manager-resolver.d.ts.map +1 -1
- package/dist/core/package-manager-resolver.js +25 -14
- package/dist/core/package-manager-resolver.js.map +1 -1
- package/dist/core/package-manager-types.d.ts +8 -0
- package/dist/core/package-manager-types.d.ts.map +1 -1
- package/dist/core/package-manager-types.js.map +1 -1
- package/dist/core/package-manager.d.ts +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader-extension-warnings.d.ts +4 -1
- package/dist/core/resource-loader-extension-warnings.d.ts.map +1 -1
- package/dist/core/resource-loader-extension-warnings.js +15 -0
- package/dist/core/resource-loader-extension-warnings.js.map +1 -1
- package/dist/core/resource-loader-package-resources.d.ts.map +1 -1
- package/dist/core/resource-loader-package-resources.js +1 -0
- package/dist/core/resource-loader-package-resources.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +5 -3
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.js +4 -1
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/types.d.ts +1 -0
- package/dist/extensions/mcp/client/oauth/types.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/types.js +8 -4
- package/dist/extensions/mcp/client/oauth/types.js.map +1 -1
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -1
- package/dist/extensions/mcp/client/transports/streamable-http.js +2 -1
- package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -10
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +4 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +4 -2
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +6 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +11 -1
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts +10 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js +21 -0
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +5 -0
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +30 -35
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/computer-use.md +5 -5
- package/docs/custom-provider/streaming.md +9 -14
- package/docs/environment-variables.md +1 -0
- package/docs/intercom/operations.md +1 -1
- package/docs/intercom.md +16 -2
- package/docs/packages.md +2 -0
- package/docs/settings.md +2 -2
- package/docs/skills.md +2 -2
- package/docs/subagents.md +47 -10
- package/docs/workflows/api-reference.md +1 -1
- package/docs/workflows/authoring.md +1 -1
- package/docs/workflows/operations.md +8 -6
- package/docs/workflows/reliable-design.md +23 -5
- package/examples/extensions/custom-provider-anthropic/index.ts +31 -31
- package/examples/extensions/todo.ts +7 -0
- package/npm-shrinkwrap.json +32 -32
- 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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
2828
|
-
|
|
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 (
|
|
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
|
|
6610
|
-
|
|
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,
|
|
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
|
|
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, () =>
|
|
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 (
|
|
8132
|
-
|
|
8133
|
-
state
|
|
8134
|
-
|
|
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 (
|
|
8253
|
+
if (connection.client === nextClient)
|
|
8139
8254
|
relayStickyLiveDelivered(notice);
|
|
8140
8255
|
});
|
|
8141
8256
|
nextClient.on("pending_stage_route_revoked", (notice) => {
|
|
8142
|
-
|
|
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
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
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
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
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 =
|
|
8383
|
+
const connect = async () => {
|
|
8202
8384
|
if (!pendingStageRouteClientIsCurrent(runId, state, contextAtStart, generationAtStart)) {
|
|
8203
8385
|
throw supersededPendingStageRouteError(contextAtStart, generationAtStart);
|
|
8204
8386
|
}
|
|
8205
|
-
|
|
8206
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
8436
|
+
await connection.client.disconnect();
|
|
8258
8437
|
} catch {}
|
|
8259
|
-
|
|
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
|
|
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
|
-
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
await
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
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;
|