@sentry/junior 0.179.0 → 0.180.0

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 (126) hide show
  1. package/dist/{agent-hooks-32IDCLMW.js → agent-hooks-DKDDRKZA.js} +16 -18
  2. package/dist/api/schema.js +0 -1
  3. package/dist/api.js +199 -197
  4. package/dist/app.d.ts +4 -0
  5. package/dist/app.js +300 -1259
  6. package/dist/catalog-runtime-WXKGUF3W.js +14 -0
  7. package/dist/chat/agent/sandbox.d.ts +0 -2
  8. package/dist/chat/api-turns/routing.d.ts +4 -0
  9. package/dist/chat/api-turns/work.d.ts +5 -0
  10. package/dist/chat/config.d.ts +5 -2
  11. package/dist/chat/configuration/defaults.d.ts +1 -1
  12. package/dist/chat/conversations/projection.d.ts +6 -4
  13. package/dist/chat/ingress/message-router.d.ts +3 -0
  14. package/dist/chat/model-profile.d.ts +8 -10
  15. package/dist/chat/pi/conversation-events.d.ts +3 -2
  16. package/dist/chat/plugins/task-queue.d.ts +40 -3
  17. package/dist/chat/plugins/task-runner.d.ts +1 -1
  18. package/dist/chat/queue/callback.d.ts +26 -0
  19. package/dist/chat/queue/sign.d.ts +30 -0
  20. package/dist/chat/sandbox/sandbox.d.ts +0 -2
  21. package/dist/chat/sandbox/session.d.ts +0 -2
  22. package/dist/chat/sandbox/skill-sync.d.ts +1 -1
  23. package/dist/chat/sandbox/snapshot/events.d.ts +23 -0
  24. package/dist/chat/sandbox/snapshot/job-callback.d.ts +5 -0
  25. package/dist/chat/sandbox/snapshot/job-queue.d.ts +26 -0
  26. package/dist/chat/sandbox/snapshot/job-runner.d.ts +11 -0
  27. package/dist/chat/sandbox/snapshot/not-ready-error.d.ts +6 -0
  28. package/dist/chat/sandbox/snapshot/workspace.d.ts +9 -3
  29. package/dist/chat/services/turn-router.d.ts +4 -3
  30. package/dist/chat/task-execution/queue-signing.d.ts +10 -21
  31. package/dist/chat/task-execution/state.d.ts +48 -0
  32. package/dist/chat/task-execution/store.d.ts +28 -2
  33. package/dist/chat/task-execution/worker.d.ts +4 -1
  34. package/dist/chat/tools/handoff/tool.d.ts +1 -1
  35. package/dist/{chunk-B6ECUSVX.js → chunk-2AYEVN7K.js} +8 -8
  36. package/dist/{chunk-SLGGOASN.js → chunk-2YIRH4E3.js} +46 -46
  37. package/dist/{chunk-KJLHIHFF.js → chunk-3ILJBWP7.js} +35 -227
  38. package/dist/{chunk-RZRYOLCE.js → chunk-5PUMIMNQ.js} +2292 -1147
  39. package/dist/{chunk-CJLBLELR.js → chunk-5TUR4M3M.js} +8 -61
  40. package/dist/{chunk-6ZWRNC4D.js → chunk-6Y5B5PEX.js} +1 -1
  41. package/dist/{chunk-XSPSCWLH.js → chunk-6YCEWOLO.js} +4 -4
  42. package/dist/chunk-7H2VZTWN.js +103 -0
  43. package/dist/{chunk-FAS6AIMF.js → chunk-CCDXTDSY.js} +8 -8
  44. package/dist/{chunk-CGA4ERJ5.js → chunk-CEMMLV5L.js} +1 -1
  45. package/dist/{chunk-XZY6G5YZ.js → chunk-CK6EINVZ.js} +180 -87
  46. package/dist/{chunk-FIANEE7Z.js → chunk-CM5HNV2W.js} +6 -6
  47. package/dist/{chunk-JT4WMD3C.js → chunk-CP73FKME.js} +144 -218
  48. package/dist/{chunk-3I7XE3PA.js → chunk-DHLOGWYH.js} +36 -36
  49. package/dist/chunk-DKIJ2RP5.js +68 -0
  50. package/dist/{chunk-YFNAMRGE.js → chunk-DRHEGXTZ.js} +1 -1
  51. package/dist/{chunk-OOUNJNMR.js → chunk-DWPN6SCH.js} +1 -1
  52. package/dist/chunk-EWHP2IRG.js +209 -0
  53. package/dist/{chunk-R6U7N4FS.js → chunk-FGC3PHNH.js} +3 -3
  54. package/dist/{chunk-3TM3FYLQ.js → chunk-GA5NS74S.js} +1 -1
  55. package/dist/{chunk-FIDMHAO6.js → chunk-GPXAHUQH.js} +84 -274
  56. package/dist/chunk-GUKXEPMX.js +218 -0
  57. package/dist/{chunk-GENV6KF2.js → chunk-I6IFTAPF.js} +108 -76
  58. package/dist/{chunk-R5NWWYIS.js → chunk-IANUX7HX.js} +5 -5
  59. package/dist/{chunk-G2CAC4CV.js → chunk-KCL6AWYW.js} +74 -68
  60. package/dist/{chunk-5IRROPA5.js → chunk-L7LTGN4Z.js} +129 -31
  61. package/dist/{chunk-Q5B3WTGG.js → chunk-LGVQLNLS.js} +42 -41
  62. package/dist/chunk-M3QYTBQ6.js +55 -0
  63. package/dist/{chunk-FTGD2FBP.js → chunk-MXEUIGHO.js} +2 -2
  64. package/dist/{chunk-M63DETLL.js → chunk-N7TMSOZH.js} +6 -6
  65. package/dist/{chunk-2HIPYNQI.js → chunk-O4QYZTDK.js} +33 -32
  66. package/dist/chunk-PEQXYSSE.js +45 -0
  67. package/dist/{chunk-RTRBYSF3.js → chunk-QSO7B5JO.js} +1 -1
  68. package/dist/{chunk-HQNE5APD.js → chunk-RAZG3YHC.js} +100 -79
  69. package/dist/{chunk-VP4OVRDD.js → chunk-S7YRTOSQ.js} +69 -73
  70. package/dist/{chunk-U4TKB6F6.js → chunk-SDBKZ5LV.js} +108 -5
  71. package/dist/{chunk-GPLAT6H7.js → chunk-TC5DE5KJ.js} +22 -18
  72. package/dist/{chunk-H4HBKISO.js → chunk-TXKUKMVO.js} +1 -1
  73. package/dist/chunk-U5EUCUBH.js +164 -0
  74. package/dist/{chunk-3AFVR5UC.js → chunk-VG722ONZ.js} +18 -16
  75. package/dist/{chunk-ZQMG3CL5.js → chunk-VGPPWWHF.js} +16 -16
  76. package/dist/{chunk-JMJNFEDC.js → chunk-WVAMRKYG.js} +9 -54
  77. package/dist/chunk-X6GDDWQH.js +60 -0
  78. package/dist/{chunk-4GWXAILB.js → chunk-ZE2KOV3G.js} +1 -1
  79. package/dist/{chunk-TIEKUH4Q.js → chunk-ZM7ZURJS.js} +4 -3
  80. package/dist/cli/chat.js +47 -43
  81. package/dist/cli/check.js +13 -15
  82. package/dist/cli/env.js +0 -1
  83. package/dist/cli/init.js +0 -1
  84. package/dist/cli/main.js +2 -3
  85. package/dist/cli/plugins.js +18 -20
  86. package/dist/cli/run.js +0 -1
  87. package/dist/cli/snapshot-create.js +14 -16
  88. package/dist/cli/upgrade.js +16 -18
  89. package/dist/{conversation-work-KATFHLG3.js → conversation-work-VIOQ5ZF3.js} +0 -2
  90. package/dist/{db-EJAV7JL6.js → db-6SBHIAJK.js} +8 -10
  91. package/dist/deployment.d.ts +1 -0
  92. package/dist/{discovery-GUFTFBTL.js → discovery-DWVDM7UK.js} +1 -2
  93. package/dist/{experimental-XVDOSRBS.js → experimental-SIJSRDJD.js} +0 -1
  94. package/dist/instrumentation.js +7 -9
  95. package/dist/nitro.js +39 -13
  96. package/dist/{oauth-callback-server-GAVSUBTQ.js → oauth-callback-server-WSDQPZZS.js} +34 -32
  97. package/dist/{oauth-relay-3ZU72UGL.js → oauth-relay-5XPVRPYB.js} +0 -1
  98. package/dist/{plugins-HW4VWW6G.js → plugins-YTYJMMJF.js} +1 -2
  99. package/dist/{runner-34JL64JF.js → runner-GWTSWESR.js} +39 -33
  100. package/dist/{sandbox-egress-signals-DXOOBSBI.js → sandbox-egress-signals-FIL7EGPR.js} +5 -6
  101. package/dist/{sentry-JMWTS32N.js → sentry-MB3NL3IR.js} +1 -2
  102. package/dist/skills-F32BPFYW.js +27 -0
  103. package/dist/spawn-X5BPP5OE.js +37 -0
  104. package/dist/task-runner-2FPBV5PP.js +32 -0
  105. package/dist/validation-62WO524A.js +17 -0
  106. package/dist/vercel.js +0 -1
  107. package/dist/version.js +1 -2
  108. package/dist/work-3C3CMZ24.js +45 -0
  109. package/dist/worker-MFAI6ZEK.js +22 -0
  110. package/package.json +8 -7
  111. package/dist/catalog-runtime-FBVA6WAQ.js +0 -16
  112. package/dist/chat/plugins/task-callback.d.ts +0 -5
  113. package/dist/chat/plugins/task-message.d.ts +0 -23
  114. package/dist/chat/plugins/task-signing.d.ts +0 -31
  115. package/dist/chat/sandbox/snapshot/waiting-error.d.ts +0 -15
  116. package/dist/chat/services/workspace-snapshot-wait.d.ts +0 -27
  117. package/dist/chunk-5I6ORJUY.js +0 -127
  118. package/dist/chunk-6GWA276C.js +0 -72
  119. package/dist/chunk-MLKGABMK.js +0 -9
  120. package/dist/chunk-UT6X7XN7.js +0 -51
  121. package/dist/chunk-WR76IVA5.js +0 -130
  122. package/dist/skills-U545HALM.js +0 -29
  123. package/dist/spawn-I2S4IDUQ.js +0 -37
  124. package/dist/validation-EVXVGA44.js +0 -19
  125. package/dist/work-QOAUPDBU.js +0 -45
  126. package/dist/worker-5GX2IKLZ.js +0 -24
@@ -8,22 +8,22 @@ import {
8
8
  getConversationStore,
9
9
  parseDestination,
10
10
  sameDestination
11
- } from "./chunk-VP4OVRDD.js";
11
+ } from "./chunk-S7YRTOSQ.js";
12
12
  import {
13
13
  getDefaultRedisStateAdapterFor,
14
14
  getStateAdapter
15
- } from "./chunk-3TM3FYLQ.js";
15
+ } from "./chunk-GA5NS74S.js";
16
16
  import {
17
17
  getChatConfig
18
- } from "./chunk-GENV6KF2.js";
18
+ } from "./chunk-I6IFTAPF.js";
19
19
  import {
20
20
  parseStoredSlackActor
21
- } from "./chunk-M63DETLL.js";
21
+ } from "./chunk-N7TMSOZH.js";
22
22
  import {
23
23
  isRecord,
24
24
  toOptionalNumber,
25
25
  toOptionalString
26
- } from "./chunk-HQNE5APD.js";
26
+ } from "./chunk-RAZG3YHC.js";
27
27
 
28
28
  // src/chat/task-execution/state.ts
29
29
  import { randomUUID } from "crypto";
@@ -118,7 +118,7 @@ function upgradedPendingMessage(stored, duplicate) {
118
118
  const delivery = promotesInterrupt ? "interrupt" : stored.delivery;
119
119
  const input = promotesInterrupt ? {
120
120
  ...duplicate.input,
121
- ...inputHasAttachments(duplicate.input) || !inputHasAttachments(stored.input) ? {} : { attachments: stored.input.attachments }
121
+ ...inputHasAttachments(duplicate.input) || !inputHasAttachments(stored.input) ? void 0 : { attachments: stored.input.attachments }
122
122
  } : inputHasAttachments(duplicate.input) && !inputHasAttachments(stored.input) ? duplicate.input : stored.input;
123
123
  if (input === stored.input && delivery === stored.delivery) {
124
124
  return stored;
@@ -175,6 +175,18 @@ function normalizeLease(value) {
175
175
  expiresAtMs
176
176
  };
177
177
  }
178
+ function normalizeStop(value) {
179
+ if (!isRecord(value)) {
180
+ return void 0;
181
+ }
182
+ const inboundMessageIds = Array.isArray(value.inboundMessageIds) ? uniqueStrings(
183
+ value.inboundMessageIds.filter(
184
+ (id) => typeof id === "string"
185
+ )
186
+ ) : [];
187
+ const runId = toOptionalString(value.runId);
188
+ return runId ? { inboundMessageIds, runId } : void 0;
189
+ }
178
190
  function normalizeExecution(conversationId, value) {
179
191
  if (!isRecord(value)) {
180
192
  return void 0;
@@ -201,6 +213,9 @@ function normalizeExecution(conversationId, value) {
201
213
  value.inboundMessageIds.map((id) => typeof id === "string" ? id : void 0).filter((id) => Boolean(id))
202
214
  ) : [];
203
215
  const lease = normalizeLease(value.lease);
216
+ const runId = toOptionalString(value.runId);
217
+ const normalizedStop = normalizeStop(value.stop);
218
+ const stop = normalizedStop?.runId === runId ? normalizedStop : void 0;
204
219
  const normalizedStatus = status === "idle" && lease ? "running" : status === "idle" && pendingMessages2.length > 0 ? "pending" : status;
205
220
  return {
206
221
  status: normalizedStatus,
@@ -215,7 +230,8 @@ function normalizeExecution(conversationId, value) {
215
230
  lastEnqueuedAtMs: toOptionalNumber(value.lastEnqueuedAtMs),
216
231
  lastProgressAtMs: toOptionalNumber(value.lastProgressAtMs),
217
232
  retryCount: toOptionalNumber(value.retryCount),
218
- runId: toOptionalString(value.runId),
233
+ runId,
234
+ stop,
219
235
  updatedAtMs: toOptionalNumber(value.updatedAtMs)
220
236
  };
221
237
  }
@@ -244,11 +260,11 @@ function normalizeConversation(conversationId, value) {
244
260
  lastActivityAtMs,
245
261
  updatedAtMs,
246
262
  execution,
247
- ...destination ? { destination } : {},
248
- ...toOptionalString(value.title) ? { title: toOptionalString(value.title) } : {},
249
- ...toOptionalString(value.channelName) ? { channelName: toOptionalString(value.channelName) } : {},
250
- ...normalizeActor(value.actor) ? { actor: normalizeActor(value.actor) } : {},
251
- ...normalizeSource(value.source) ? { source: normalizeSource(value.source) } : {}
263
+ ...destination ? { destination } : void 0,
264
+ ...toOptionalString(value.title) ? { title: toOptionalString(value.title) } : void 0,
265
+ ...toOptionalString(value.channelName) ? { channelName: toOptionalString(value.channelName) } : void 0,
266
+ ...normalizeActor(value.actor) ? { actor: normalizeActor(value.actor) } : void 0,
267
+ ...normalizeSource(value.source) ? { source: normalizeSource(value.source) } : void 0
252
268
  };
253
269
  }
254
270
  function emptyConversation(args) {
@@ -258,8 +274,8 @@ function emptyConversation(args) {
258
274
  createdAtMs: args.nowMs,
259
275
  lastActivityAtMs: args.nowMs,
260
276
  updatedAtMs: args.nowMs,
261
- ...args.destination ? { destination: args.destination } : {},
262
- ...args.source ? { source: args.source } : {},
277
+ ...args.destination ? { destination: args.destination } : void 0,
278
+ ...args.source ? { source: args.source } : void 0,
263
279
  execution: {
264
280
  status: "idle",
265
281
  inboundMessageIds: [],
@@ -642,7 +658,7 @@ function conversationWorkState(conversation) {
642
658
  leaseExpiresAtMs: lease.expiresAtMs,
643
659
  leaseToken: lease.token
644
660
  }
645
- } : {},
661
+ } : void 0,
646
662
  messages: pendingMessages(conversation),
647
663
  needsRun: hasRunnableWork(conversation)
648
664
  };
@@ -655,7 +671,7 @@ async function getConversationWorkState(args) {
655
671
  const conversation = await getConversation(args);
656
672
  return conversation ? conversationWorkState(conversation) : void 0;
657
673
  }
658
- async function appendInboundMessage(args) {
674
+ async function appendInboundMessageWithAdmission(args) {
659
675
  const nowMs = args.nowMs ?? now();
660
676
  return await withConversationMutation(
661
677
  { conversationId: args.message.conversationId, state: args.state },
@@ -705,6 +721,9 @@ async function appendInboundMessage(args) {
705
721
  );
706
722
  return { status: "duplicate" };
707
723
  }
724
+ if (args.exclusive && hasRunnableWork(current)) {
725
+ return { status: "active" };
726
+ }
708
727
  const status = current.execution.lease && current.execution.status === "running" ? "running" : current.execution.lease ? "paused" : "pending";
709
728
  const next = {
710
729
  ...current,
@@ -736,6 +755,16 @@ async function appendInboundMessage(args) {
736
755
  }
737
756
  );
738
757
  }
758
+ async function appendInboundMessage(args) {
759
+ const result = await appendInboundMessageWithAdmission({
760
+ ...args,
761
+ exclusive: false
762
+ });
763
+ if (result.status === "active") {
764
+ throw new Error("Non-exclusive mailbox append returned active");
765
+ }
766
+ return result;
767
+ }
739
768
  async function requestConversationWork(args) {
740
769
  const nowMs = args.nowMs ?? now();
741
770
  return await withConversationMutation(args, async (state, lock) => {
@@ -984,6 +1013,50 @@ async function ackMessages(args) {
984
1013
  return true;
985
1014
  });
986
1015
  }
1016
+ function isHumanFacingMessage(message) {
1017
+ return message.source === "web" || message.source === "slack";
1018
+ }
1019
+ async function completeConversationStop(args) {
1020
+ const nowMs = args.nowMs ?? now();
1021
+ return await withConversationMutation(args, async (state, lock) => {
1022
+ const current = await readConversation(state, args.conversationId);
1023
+ if (!current || current.execution.lease?.token !== args.leaseToken) {
1024
+ return { status: "lost_lease", removedInboundMessageIds: [] };
1025
+ }
1026
+ const stop = current.execution.stop;
1027
+ if (!stop || stop.runId !== args.runId) {
1028
+ return { status: "none", removedInboundMessageIds: [] };
1029
+ }
1030
+ const stoppedInboundMessageIds = new Set(stop.inboundMessageIds);
1031
+ const removedInboundMessageIds = [];
1032
+ const pendingMessages2 = current.execution.pendingMessages.filter(
1033
+ (message) => {
1034
+ const shouldStop = stoppedInboundMessageIds.has(
1035
+ message.inboundMessageId
1036
+ );
1037
+ if (shouldStop) {
1038
+ removedInboundMessageIds.push(message.inboundMessageId);
1039
+ }
1040
+ return !shouldStop;
1041
+ }
1042
+ );
1043
+ await writeConversation(
1044
+ state,
1045
+ lock,
1046
+ withExecutionUpdate(
1047
+ current,
1048
+ {
1049
+ ...current.execution,
1050
+ lastEnqueuedAtMs: pendingMessages2.length === 0 ? void 0 : current.execution.lastEnqueuedAtMs,
1051
+ pendingMessages: pendingMessages2,
1052
+ stop: void 0
1053
+ },
1054
+ nowMs
1055
+ )
1056
+ );
1057
+ return { status: "cleared", removedInboundMessageIds };
1058
+ });
1059
+ }
987
1060
  async function cancelHumanFacingPendingMessages(args) {
988
1061
  const nowMs = args.nowMs ?? now();
989
1062
  const requestedIds = args.inboundMessageIds === void 0 ? void 0 : new Set(args.inboundMessageIds);
@@ -995,10 +1068,9 @@ async function cancelHumanFacingPendingMessages(args) {
995
1068
  const cancelledInboundMessageIds = [];
996
1069
  const pendingMessages2 = [];
997
1070
  for (const message of current.execution.pendingMessages) {
998
- const isHumanFacing = message.source === "web" || message.source === "slack";
999
1071
  const isRequested = requestedIds === void 0 || requestedIds.has(message.inboundMessageId);
1000
1072
  const isInSnapshot = args.receivedBeforeMs === void 0 || message.receivedAtMs <= args.receivedBeforeMs;
1001
- if (isHumanFacing && isRequested && isInSnapshot) {
1073
+ if (isHumanFacingMessage(message) && isRequested && isInSnapshot) {
1002
1074
  cancelledInboundMessageIds.push(message.inboundMessageId);
1003
1075
  continue;
1004
1076
  }
@@ -1019,7 +1091,8 @@ async function cancelHumanFacingPendingMessages(args) {
1019
1091
  pendingMessages: pendingMessages2,
1020
1092
  retryCount: becomesIdle ? 0 : current.execution.retryCount,
1021
1093
  runId: becomesIdle ? void 0 : current.execution.runId,
1022
- status: becomesIdle ? "idle" : current.execution.status
1094
+ status: becomesIdle ? "idle" : current.execution.status,
1095
+ stop: becomesIdle ? void 0 : current.execution.stop
1023
1096
  },
1024
1097
  nowMs
1025
1098
  )
@@ -1120,7 +1193,8 @@ async function recordConversationRetry(args) {
1120
1193
  retryCount: count,
1121
1194
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1122
1195
  runId: stopped ? void 0 : current.execution.runId,
1123
- status: stopped ? "failed" : "paused"
1196
+ status: stopped ? "failed" : "paused",
1197
+ stop: stopped ? void 0 : current.execution.stop
1124
1198
  },
1125
1199
  nowMs
1126
1200
  )
@@ -1136,7 +1210,7 @@ async function completeConversationWork(args) {
1136
1210
  return "lost_lease";
1137
1211
  }
1138
1212
  const hasPending = pendingMessages(current).length > 0;
1139
- const needsRun = current.execution.status === "paused";
1213
+ const needsRun = current.execution.status === "paused" || args.resumeIfStopped === true && current.execution.stop !== void 0;
1140
1214
  const runnable = needsRun || hasPending;
1141
1215
  await writeConversation(
1142
1216
  state,
@@ -1149,7 +1223,8 @@ async function completeConversationWork(args) {
1149
1223
  status: needsRun ? "paused" : hasPending ? "pending" : "idle",
1150
1224
  lastProgressAtMs: args.madeProgress === false ? current.execution.lastProgressAtMs : nowMs,
1151
1225
  retryCount: runnable || args.madeProgress === false ? current.execution.retryCount : 0,
1152
- runId: runnable ? current.execution.runId : void 0
1226
+ runId: runnable ? current.execution.runId : void 0,
1227
+ stop: runnable ? current.execution.stop : void 0
1153
1228
  },
1154
1229
  nowMs
1155
1230
  )
@@ -1244,7 +1319,8 @@ async function deadLetterAttempt(args) {
1244
1319
  ...current.execution,
1245
1320
  lease: void 0,
1246
1321
  status: runnable ? "pending" : "failed",
1247
- runId: runnable ? current.execution.runId : void 0
1322
+ runId: runnable ? current.execution.runId : void 0,
1323
+ stop: runnable ? current.execution.stop : void 0
1248
1324
  },
1249
1325
  nowMs
1250
1326
  )
@@ -1273,7 +1349,8 @@ async function clearExpiredConversationLease(args) {
1273
1349
  retryCount,
1274
1350
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1275
1351
  runId: stopped ? void 0 : current.execution.runId,
1276
- status: stopped ? "failed" : "paused"
1352
+ status: stopped ? "failed" : "paused",
1353
+ stop: stopped ? void 0 : current.execution.stop
1277
1354
  },
1278
1355
  nowMs
1279
1356
  )
@@ -1393,13 +1470,10 @@ async function ensureConversationWake(args) {
1393
1470
  });
1394
1471
  return { status: "enqueued", queueMessageId: queueResult?.messageId };
1395
1472
  }
1396
- async function appendAndEnqueueInboundMessage(args) {
1473
+ async function enqueueAfterAppend(args) {
1397
1474
  const nowMs = args.nowMs ?? now2();
1398
- const appendResult = await appendInboundMessage({
1399
- message: args.message,
1400
- nowMs,
1401
- state: args.state
1402
- });
1475
+ const appendResult = args.appendResult;
1476
+ if (appendResult.status === "active") return appendResult;
1403
1477
  let idempotencyKey = args.message.inboundMessageId;
1404
1478
  if (appendResult.status === "duplicate") {
1405
1479
  const conversation = await getConversation({
@@ -1447,9 +1521,32 @@ async function appendAndEnqueueInboundMessage(args) {
1447
1521
  }
1448
1522
  return {
1449
1523
  ...appendResult,
1450
- ...wake.status === "enqueued" ? { queueMessageId: wake.queueMessageId } : {}
1524
+ ...wake.status === "enqueued" ? { queueMessageId: wake.queueMessageId } : void 0
1451
1525
  };
1452
1526
  }
1527
+ async function appendAndEnqueueInboundMessage(args) {
1528
+ const nowMs = args.nowMs ?? now2();
1529
+ const result = await enqueueAfterAppend({
1530
+ ...args,
1531
+ appendResult: await appendInboundMessage({
1532
+ message: args.message,
1533
+ nowMs,
1534
+ state: args.state
1535
+ }),
1536
+ nowMs
1537
+ });
1538
+ if (result.status === "active") {
1539
+ throw new Error("Non-exclusive mailbox enqueue returned active");
1540
+ }
1541
+ return result;
1542
+ }
1543
+ async function completeConversationStop2(args) {
1544
+ const result = await completeConversationStop(args);
1545
+ if (result.status === "cleared") {
1546
+ await recordExecutionMetadata(args);
1547
+ }
1548
+ return result;
1549
+ }
1453
1550
  async function clearConsumedConversationWake2(args) {
1454
1551
  const result = await clearConsumedConversationWake(args);
1455
1552
  if (result) {
@@ -1560,6 +1657,7 @@ export {
1560
1657
  hasRunnableConversationWork,
1561
1658
  ensureConversationWake,
1562
1659
  appendAndEnqueueInboundMessage,
1660
+ completeConversationStop2 as completeConversationStop,
1563
1661
  clearConsumedConversationWake2 as clearConsumedConversationWake,
1564
1662
  requestConversationWork2 as requestConversationWork,
1565
1663
  startConversationWork2 as startConversationWork,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-RF6J3DIO.js";
4
4
  import {
5
5
  resolveBaseUrl
6
- } from "./chunk-2HIPYNQI.js";
6
+ } from "./chunk-O4QYZTDK.js";
7
7
  import {
8
8
  isExperimentalFeatureEnabled
9
9
  } from "./chunk-VRS6WDK5.js";
@@ -12,27 +12,27 @@ import {
12
12
  getPlugins,
13
13
  getSlackClient,
14
14
  withSlackRetries
15
- } from "./chunk-3I7XE3PA.js";
15
+ } from "./chunk-DHLOGWYH.js";
16
16
  import {
17
17
  getDb,
18
18
  parseDestination
19
- } from "./chunk-VP4OVRDD.js";
19
+ } from "./chunk-S7YRTOSQ.js";
20
20
  import {
21
21
  sleep
22
- } from "./chunk-JMJNFEDC.js";
22
+ } from "./chunk-WVAMRKYG.js";
23
23
  import {
24
24
  acquireActiveLock,
25
25
  getStateAdapter
26
- } from "./chunk-3TM3FYLQ.js";
26
+ } from "./chunk-GA5NS74S.js";
27
27
  import {
28
28
  pluginCatalogRuntime
29
- } from "./chunk-YFNAMRGE.js";
29
+ } from "./chunk-DRHEGXTZ.js";
30
30
  import {
31
31
  fetchWithBoundedOAuthErrorBodies
32
- } from "./chunk-SLGGOASN.js";
32
+ } from "./chunk-2YIRH4E3.js";
33
33
  import {
34
34
  isRecord
35
- } from "./chunk-HQNE5APD.js";
35
+ } from "./chunk-RAZG3YHC.js";
36
36
 
37
37
  // src/chat/capabilities/router.ts
38
38
  var ProviderCredentialRouter = class {
@@ -167,7 +167,7 @@ function createAgentRunner(execute, options) {
167
167
  ...run.durability,
168
168
  spawnAgent
169
169
  }
170
- } : {}
170
+ } : void 0
171
171
  };
172
172
  return await execute(nextRun, streamFn);
173
173
  }
@@ -262,8 +262,8 @@ function getMcpProviderErrorAttributes(error) {
262
262
  return {
263
263
  "app.credential.provider": error.provider,
264
264
  "app.mcp.error.phase": error.phase,
265
- ...error.status !== void 0 ? { "http.response.status_code": error.status } : {},
266
- ...error.resourceHost ? { "server.address": error.resourceHost } : {}
265
+ ...error.status !== void 0 ? { "http.response.status_code": error.status } : void 0,
266
+ ...error.resourceHost ? { "server.address": error.resourceHost } : void 0
267
267
  };
268
268
  }
269
269
  var McpToolError = class extends Error {
@@ -322,7 +322,7 @@ function normalizeUser(raw) {
322
322
  is_bot: raw.is_bot ?? false,
323
323
  is_deleted: raw.deleted ?? false,
324
324
  timezone: raw.tz || void 0,
325
- ...profileFields.length > 0 ? { profile_fields: profileFields } : {}
325
+ ...profileFields.length > 0 ? { profile_fields: profileFields } : void 0
326
326
  };
327
327
  }
328
328
  function normalizeNameTokens(value) {
@@ -420,7 +420,7 @@ async function listWorkspaceUsers(options) {
420
420
  const result = await withSlackRetries(
421
421
  () => client.users.list({
422
422
  limit: 200,
423
- ...cursor ? { cursor } : {}
423
+ ...cursor ? { cursor } : void 0
424
424
  }),
425
425
  3,
426
426
  { action: "users.list" }
@@ -547,9 +547,9 @@ async function selectPluginGrant(input) {
547
547
  const result = await hook({
548
548
  ...basePluginContext(plugin),
549
549
  request: {
550
- ...input.bodyText !== void 0 ? { bodyText: input.bodyText } : {},
550
+ ...input.bodyText !== void 0 ? { bodyText: input.bodyText } : void 0,
551
551
  method: input.method,
552
- ...input.operation ? { operation: input.operation } : {},
552
+ ...input.operation ? { operation: input.operation } : void 0,
553
553
  url: input.upstreamUrl.toString()
554
554
  }
555
555
  });
@@ -576,7 +576,7 @@ async function onPluginEgressResponse(input) {
576
576
  },
577
577
  request: {
578
578
  method: input.method,
579
- ...input.operation ? { operation: input.operation } : {},
579
+ ...input.operation ? { operation: input.operation } : void 0,
580
580
  url: input.upstreamUrl.toString()
581
581
  },
582
582
  response: input.response
@@ -618,7 +618,7 @@ async function issuePluginCredential(input) {
618
618
  ...basePluginContext(plugin),
619
619
  actor: input.actor,
620
620
  grant: input.grant,
621
- ...input.credentialSubject ? { credentialSubject: input.credentialSubject } : {},
621
+ ...input.credentialSubject ? { credentialSubject: input.credentialSubject } : void 0,
622
622
  tokens: {
623
623
  ...currentUserId ? {
624
624
  currentUser: {
@@ -640,7 +640,7 @@ async function issuePluginCredential(input) {
640
640
  callback
641
641
  )
642
642
  }
643
- } : {},
643
+ } : void 0,
644
644
  ...credentialSubjectUserId ? {
645
645
  credentialSubject: {
646
646
  userId: credentialSubjectUserId,
@@ -661,7 +661,7 @@ async function issuePluginCredential(input) {
661
661
  callback
662
662
  )
663
663
  }
664
- } : {}
664
+ } : void 0
665
665
  }
666
666
  });
667
667
  return parseCredentialResult(result, plugin.manifest.name);
@@ -732,18 +732,18 @@ function parseMcpAuthSession(value) {
732
732
  provider: parsed.provider,
733
733
  userId: parsed.userId,
734
734
  conversationId: parsed.conversationId,
735
- ...destination ? { destination } : {},
736
- ...source?.success ? { source: source.data } : {},
735
+ ...destination ? { destination } : void 0,
736
+ ...source?.success ? { source: source.data } : void 0,
737
737
  sessionId: parsed.sessionId,
738
738
  userMessage: parsed.userMessage,
739
739
  createdAtMs: parsed.createdAtMs,
740
740
  updatedAtMs: parsed.updatedAtMs,
741
- ...typeof parsed.channelId === "string" ? { channelId: parsed.channelId } : {},
742
- ...typeof parsed.threadTs === "string" ? { threadTs: parsed.threadTs } : {},
743
- ...typeof parsed.toolChannelId === "string" ? { toolChannelId: parsed.toolChannelId } : {},
744
- ...isRecord(parsed.configuration) ? { configuration: parsed.configuration } : {},
745
- ...typeof parsed.authorizationUrl === "string" ? { authorizationUrl: parsed.authorizationUrl } : {},
746
- ...typeof parsed.codeVerifier === "string" ? { codeVerifier: parsed.codeVerifier } : {}
741
+ ...typeof parsed.channelId === "string" ? { channelId: parsed.channelId } : void 0,
742
+ ...typeof parsed.threadTs === "string" ? { threadTs: parsed.threadTs } : void 0,
743
+ ...typeof parsed.toolChannelId === "string" ? { toolChannelId: parsed.toolChannelId } : void 0,
744
+ ...isRecord(parsed.configuration) ? { configuration: parsed.configuration } : void 0,
745
+ ...typeof parsed.authorizationUrl === "string" ? { authorizationUrl: parsed.authorizationUrl } : void 0,
746
+ ...typeof parsed.codeVerifier === "string" ? { codeVerifier: parsed.codeVerifier } : void 0
747
747
  };
748
748
  } catch {
749
749
  return void 0;
@@ -778,11 +778,12 @@ function parseStoredCredentials(value) {
778
778
  return {
779
779
  ...isRecord(parsed.clientInformation) ? {
780
780
  clientInformation: parsed.clientInformation
781
- } : {},
781
+ } : void 0,
782
782
  ...isRecord(parsed.discoveryState) ? {
783
+ // @ts-expect-error non-overlapping boundary cast; rule forbids as-unknown-as chains
783
784
  discoveryState: parsed.discoveryState
784
- } : {},
785
- ...isRecord(parsed.tokens) ? { tokens: parsed.tokens } : {}
785
+ } : void 0,
786
+ ...isRecord(parsed.tokens) ? { tokens: parsed.tokens } : void 0
786
787
  };
787
788
  } catch {
788
789
  return void 0;
@@ -829,7 +830,7 @@ async function patchMcpAuthSession(authSessionId, patch) {
829
830
  provider: current.provider,
830
831
  userId: current.userId,
831
832
  conversationId: current.conversationId,
832
- ...current.destination ? { destination: current.destination } : {},
833
+ ...current.destination ? { destination: current.destination } : void 0,
833
834
  sessionId: current.sessionId,
834
835
  userMessage: current.userMessage,
835
836
  createdAtMs: current.createdAtMs,
@@ -1050,9 +1051,9 @@ var StateBackedMcpOAuthClientProvider = class {
1050
1051
  session.provider
1051
1052
  ) ?? {};
1052
1053
  await putMcpStoredOAuthCredentials(session.userId, session.provider, {
1053
- ...scope === "tokens" || scope === "all" ? {} : credentials.tokens ? { tokens: credentials.tokens } : {},
1054
- ...scope === "client" || scope === "all" ? {} : credentials.clientInformation ? { clientInformation: credentials.clientInformation } : {},
1055
- ...scope === "discovery" || scope === "all" ? {} : credentials.discoveryState ? { discoveryState: credentials.discoveryState } : {}
1054
+ ...scope === "tokens" || scope === "all" ? void 0 : credentials.tokens ? { tokens: credentials.tokens } : {},
1055
+ ...scope === "client" || scope === "all" ? void 0 : credentials.clientInformation ? { clientInformation: credentials.clientInformation } : {},
1056
+ ...scope === "discovery" || scope === "all" ? void 0 : credentials.discoveryState ? { discoveryState: credentials.discoveryState } : {}
1056
1057
  });
1057
1058
  });
1058
1059
  }
@@ -1133,14 +1134,14 @@ async function createMcpOAuthClientProvider(input) {
1133
1134
  provider: input.provider,
1134
1135
  userId: input.userId,
1135
1136
  conversationId: input.conversationId,
1136
- ...input.destination ? { destination: input.destination } : {},
1137
- ...input.source ? { source: input.source } : {},
1137
+ ...input.destination ? { destination: input.destination } : void 0,
1138
+ ...input.source ? { source: input.source } : void 0,
1138
1139
  sessionId: input.sessionId,
1139
1140
  userMessage: input.userMessage,
1140
- ...input.channelId ? { channelId: input.channelId } : {},
1141
- ...input.threadTs ? { threadTs: input.threadTs } : {},
1142
- ...input.toolChannelId ? { toolChannelId: input.toolChannelId } : {},
1143
- ...input.configuration ? { configuration: input.configuration } : {}
1141
+ ...input.channelId ? { channelId: input.channelId } : void 0,
1142
+ ...input.threadTs ? { threadTs: input.threadTs } : void 0,
1143
+ ...input.toolChannelId ? { toolChannelId: input.toolChannelId } : void 0,
1144
+ ...input.configuration ? { configuration: input.configuration } : void 0
1144
1145
  }
1145
1146
  );
1146
1147
  }
@@ -1178,7 +1179,7 @@ async function finalizeMcpAuthorization(provider, authSessionId, authorizationCo
1178
1179
  }
1179
1180
  let providerStatus2;
1180
1181
  const transport = new StreamableHTTPClientTransport(new URL(mcp.url), {
1181
- ...Object.keys(requestInit).length > 0 ? { requestInit } : {},
1182
+ ...Object.keys(requestInit).length > 0 ? { requestInit } : void 0,
1182
1183
  authProvider,
1183
1184
  fetch: fetchWithBoundedOAuthErrorBodies(void 0, (status) => {
1184
1185
  providerStatus2 = status;
@@ -0,0 +1,55 @@
1
+ // src/chat/conversations/turn-lifecycle.ts
2
+ var ConversationTurnLifecycleService = class {
3
+ constructor(events) {
4
+ this.events = events;
5
+ }
6
+ events;
7
+ /** Record the turn start once after every input message is durable. */
8
+ async start(input) {
9
+ await this.events.append(input.conversationId, [
10
+ {
11
+ idempotencyKey: `turn:${input.turnId}:started`,
12
+ createdAtMs: input.createdAtMs,
13
+ data: {
14
+ type: "turn_started",
15
+ turnId: input.turnId,
16
+ inputMessageIds: input.inputMessageIds,
17
+ surface: input.surface
18
+ }
19
+ }
20
+ ]);
21
+ }
22
+ /** Record successful or intentional-silence completion once. */
23
+ async complete(input) {
24
+ await this.events.append(input.conversationId, [
25
+ {
26
+ idempotencyKey: `turn:${input.turnId}:terminal`,
27
+ createdAtMs: input.createdAtMs,
28
+ data: {
29
+ type: "turn_completed",
30
+ turnId: input.turnId,
31
+ outcome: input.outcome
32
+ }
33
+ }
34
+ ]);
35
+ }
36
+ /** Record a classified failure once without accepting raw error details. */
37
+ async fail(input) {
38
+ await this.events.append(input.conversationId, [
39
+ {
40
+ idempotencyKey: `turn:${input.turnId}:terminal`,
41
+ createdAtMs: input.createdAtMs,
42
+ data: {
43
+ type: "turn_failed",
44
+ turnId: input.turnId,
45
+ failureCode: input.failureCode,
46
+ ...input.eventId ? { eventId: input.eventId } : void 0
47
+ }
48
+ }
49
+ ]);
50
+ }
51
+ };
52
+
53
+ export {
54
+ ConversationTurnLifecycleService
55
+ };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getStateAdapter
3
- } from "./chunk-3TM3FYLQ.js";
3
+ } from "./chunk-GA5NS74S.js";
4
4
  import {
5
5
  getClient
6
- } from "./chunk-6GWA276C.js";
6
+ } from "./chunk-PEQXYSSE.js";
7
7
 
8
8
  // src/chat/api-turns/authorization.ts
9
9
  import { randomUUID } from "crypto";
@@ -138,15 +138,15 @@ function createActor(input, context) {
138
138
  }
139
139
  const canUseInputProfile = (!contextUserId || !inputUserId || contextUserId === inputUserId) && (platform !== "slack" || !contextTeamId || !inputTeamId || contextTeamId === inputTeamId);
140
140
  const actor = {
141
- ...canUseInputProfile && cleanActorEmail(input?.email) ? { email: cleanActorEmail(input?.email) } : {},
141
+ ...canUseInputProfile && cleanActorEmail(input?.email) ? { email: cleanActorEmail(input?.email) } : void 0,
142
142
  ...canUseInputProfile && cleanActorDisplayName(input?.fullName, actorUserId) ? {
143
143
  fullName: cleanActorDisplayName(input?.fullName, actorUserId)
144
- } : {},
144
+ } : void 0,
145
145
  platform,
146
146
  userId: actorUserId,
147
147
  ...canUseInputProfile && cleanActorDisplayName(input?.userName, actorUserId) ? {
148
148
  userName: cleanActorDisplayName(input?.userName, actorUserId)
149
- } : {}
149
+ } : void 0
150
150
  };
151
151
  if (platform === "slack") {
152
152
  return { ...actor, platform, teamId: actorTeamId };
@@ -193,11 +193,11 @@ function parseStoredSlackActor(value) {
193
193
  }
194
194
  function toStoredSlackActor(actor) {
195
195
  return {
196
- ...actor.email ? { email: actor.email } : {},
197
- ...actor.fullName ? { fullName: actor.fullName } : {},
196
+ ...actor.email ? { email: actor.email } : void 0,
197
+ ...actor.fullName ? { fullName: actor.fullName } : void 0,
198
198
  platform: actor.platform,
199
199
  slackUserId: actor.userId,
200
- ...actor.userName ? { slackUserName: actor.userName } : {},
200
+ ...actor.userName ? { slackUserName: actor.userName } : void 0,
201
201
  teamId: actor.teamId
202
202
  };
203
203
  }