@sentry/junior 0.144.0 → 0.145.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 (88) hide show
  1. package/dist/{agent-hooks-GCUTGKY3.js → agent-hooks-L7D2BDVV.js} +10 -10
  2. package/dist/api/conversations/detail.d.ts +1 -0
  3. package/dist/api/schema/conversation.d.ts +2 -0
  4. package/dist/api/schema.js +1 -1
  5. package/dist/api.js +40 -22
  6. package/dist/app.js +335 -409
  7. package/dist/{catalog-runtime-DWVYKDC6.js → catalog-runtime-QLAC4Q3W.js} +5 -5
  8. package/dist/chat/agent/request.d.ts +1 -1
  9. package/dist/chat/agent/resume.d.ts +6 -15
  10. package/dist/chat/agent/tools.d.ts +1 -1
  11. package/dist/chat/agent-dispatch/types.d.ts +1 -1
  12. package/dist/chat/app/conversation-work.d.ts +24 -0
  13. package/dist/chat/conversations/projection.d.ts +11 -3
  14. package/dist/chat/conversations/store.d.ts +1 -1
  15. package/dist/chat/runtime/agent-run-outcome.d.ts +1 -1
  16. package/dist/chat/runtime/reply-executor.d.ts +5 -5
  17. package/dist/chat/runtime/slack-resume.d.ts +12 -4
  18. package/dist/chat/state/locks.d.ts +28 -0
  19. package/dist/chat/task-execution/checkpoint.d.ts +86 -0
  20. package/dist/chat/task-execution/paused-turn.d.ts +29 -0
  21. package/dist/chat/task-execution/queue-signing.d.ts +1 -0
  22. package/dist/chat/task-execution/queue.d.ts +7 -1
  23. package/dist/chat/task-execution/slack-work.d.ts +1 -1
  24. package/dist/chat/task-execution/state.d.ts +4 -4
  25. package/dist/chat/task-execution/store.d.ts +2 -2
  26. package/dist/chat/task-execution/turn-cursor-keys.d.ts +6 -0
  27. package/dist/chat/{state/turn-session.d.ts → task-execution/turn-cursor.d.ts} +52 -42
  28. package/dist/chat/task-execution/turn-wake.d.ts +29 -0
  29. package/dist/chat/tools/types.d.ts +1 -1
  30. package/dist/{chunk-HNO2E5WB.js → chunk-27TEJTZO.js} +1 -1
  31. package/dist/{chunk-RIFJUJSI.js → chunk-2LWPFSB4.js} +1 -1
  32. package/dist/{chunk-SBZP2J5Q.js → chunk-2UH3JI64.js} +10 -9
  33. package/dist/{chunk-QUZJDAQQ.js → chunk-2XET6PKP.js} +93 -89
  34. package/dist/{chunk-SUK7NC5A.js → chunk-5PNPQYTO.js} +2 -2
  35. package/dist/{chunk-SSDTQDYQ.js → chunk-64SBYW2O.js} +132 -127
  36. package/dist/{chunk-DVO5VKYQ.js → chunk-B46ZMVOV.js} +5 -5
  37. package/dist/{chunk-A67GZN73.js → chunk-CD2XFGYQ.js} +1 -1
  38. package/dist/{chunk-WTX2RFJG.js → chunk-DS3J6WGY.js} +1 -1
  39. package/dist/{chunk-PKH6762I.js → chunk-DXEQAIUV.js} +1 -1
  40. package/dist/{chunk-WSOLZJJS.js → chunk-EIX2LQ6L.js} +3 -3
  41. package/dist/{chunk-KQBXT5B7.js → chunk-FUBRJA5F.js} +6 -6
  42. package/dist/{chunk-I44JB7HQ.js → chunk-GDV5LXRA.js} +1 -1
  43. package/dist/{chunk-7KAW7UF4.js → chunk-GUWLDMGF.js} +4 -4
  44. package/dist/{chunk-PELZ2ZSY.js → chunk-HISR3DTV.js} +33 -61
  45. package/dist/{chunk-HD6BHR25.js → chunk-HLOUZC5C.js} +32 -34
  46. package/dist/{chunk-BBCWYXHB.js → chunk-I47UGQPJ.js} +7 -7
  47. package/dist/{chunk-IUFM5JWV.js → chunk-JAL3CH4G.js} +3 -0
  48. package/dist/{chunk-E7HCWOHG.js → chunk-JLMVCNXL.js} +2 -1
  49. package/dist/{chunk-STFCL3K4.js → chunk-JTGS3ZZE.js} +1 -1
  50. package/dist/{chunk-GKA74DRA.js → chunk-LVVSIMBB.js} +1 -1
  51. package/dist/{chunk-SHEEZSLY.js → chunk-PJ4NMVQB.js} +2 -2
  52. package/dist/{chunk-W7JFV5SB.js → chunk-QJBDABQA.js} +14 -17
  53. package/dist/{chunk-UDQMY6RS.js → chunk-QUG4JSZK.js} +43 -1
  54. package/dist/{chunk-4X5KM7Z6.js → chunk-RUSS62EN.js} +14 -14
  55. package/dist/{chunk-ZF3N3JD6.js → chunk-SIN3MXH6.js} +1 -1
  56. package/dist/{chunk-QE3TICD4.js → chunk-TZRXYWRE.js} +2 -2
  57. package/dist/{chunk-CNTWB2SM.js → chunk-VTDMB7XX.js} +1 -1
  58. package/dist/{chunk-LDWNYCZ6.js → chunk-WF5HVH3M.js} +1 -1
  59. package/dist/{chunk-KCBZSJRU.js → chunk-WR76IVA5.js} +5 -2
  60. package/dist/{chunk-3GU4PWA3.js → chunk-XFKIRN3Q.js} +29 -29
  61. package/dist/{chunk-ZZCTGAIT.js → chunk-YD54Q45G.js} +4 -4
  62. package/dist/{chunk-BEGGFVFR.js → chunk-ZIAMN2UW.js} +407 -523
  63. package/dist/{chunk-44RJWAND.js → chunk-ZIMRGFYL.js} +6 -6
  64. package/dist/{chunk-54JMYQYS.js → chunk-ZYAJMESY.js} +2 -2
  65. package/dist/cli/chat.js +32 -32
  66. package/dist/cli/check.js +6 -6
  67. package/dist/cli/plugins.js +13 -13
  68. package/dist/cli/snapshot-create.js +9 -9
  69. package/dist/cli/upgrade.js +7 -7
  70. package/dist/{db-EFLHTBU6.js → db-62PW6LM3.js} +7 -7
  71. package/dist/instrumentation.js +4 -4
  72. package/dist/nitro.js +4 -4
  73. package/dist/{oauth-callback-server-RO3IQKWM.js → oauth-callback-server-6NZNHJAM.js} +25 -25
  74. package/dist/{runner-LOWW7JKA.js → runner-GCRPG3GQ.js} +19 -18
  75. package/dist/{skills-ZLMUG7AE.js → skills-2S3MDFIQ.js} +6 -6
  76. package/dist/spawn-7WK37BTD.js +39 -0
  77. package/dist/{validation-MAKEZNTS.js → validation-HAOLCJ5A.js} +6 -6
  78. package/dist/version.js +1 -1
  79. package/dist/{work-5OAGC3I4.js → work-R4XYKMUW.js} +17 -16
  80. package/dist/worker-U2UCVR7M.js +24 -0
  81. package/package.json +4 -4
  82. package/dist/chat/agent/session.d.ts +0 -19
  83. package/dist/chat/runtime/agent-continue-runner.d.ts +0 -37
  84. package/dist/chat/services/agent-continue.d.ts +0 -29
  85. package/dist/chat/services/turn-session-record.d.ts +0 -164
  86. package/dist/chat/state/turn-session-keys.d.ts +0 -6
  87. package/dist/spawn-R3LUV6RF.js +0 -38
  88. package/dist/worker-KTGGRTTP.js +0 -24
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  appendAndEnqueueInboundMessage
3
- } from "./chunk-HD6BHR25.js";
3
+ } from "./chunk-HLOUZC5C.js";
4
4
  import {
5
5
  ConversationTurnLifecycleService
6
6
  } from "./chunk-Q6QZTTLS.js";
@@ -12,36 +12,31 @@ import {
12
12
  agentBindingSchema,
13
13
  agentInvocationSchema,
14
14
  createAgentInvocationSchema
15
- } from "./chunk-DVO5VKYQ.js";
15
+ } from "./chunk-B46ZMVOV.js";
16
16
  import {
17
17
  TurnInputCommitLostError,
18
18
  coerceThreadArtifactsState,
19
- failAgentTurnSessionRecord,
20
- getAgentTurnSessionRecord,
19
+ failTurnRecord,
21
20
  getAssistantReplyText,
22
21
  getConversationTurnBoundaryError,
23
22
  getPersistedSandboxState,
24
23
  getPersistedThreadState,
25
24
  getTerminalAssistantMessages,
25
+ getTurnRecord,
26
26
  isTurnInputCommitLostError,
27
27
  openConversationProjection,
28
- persistCompletedSessionRecord,
29
28
  persistThreadStateById,
30
- persistYieldSessionRecord
31
- } from "./chunk-BEGGFVFR.js";
29
+ saveTurnCheckpoint
30
+ } from "./chunk-ZIAMN2UW.js";
32
31
  import {
33
32
  getConversationEventStore,
34
33
  getConversationStore,
35
34
  getSqlExecutor
36
- } from "./chunk-SBZP2J5Q.js";
35
+ } from "./chunk-2UH3JI64.js";
37
36
  import {
38
37
  juniorAgentBindings,
39
38
  juniorAgentInvocations
40
- } from "./chunk-HNO2E5WB.js";
41
- import {
42
- botConfig,
43
- modelIdForProfile
44
- } from "./chunk-3GU4PWA3.js";
39
+ } from "./chunk-27TEJTZO.js";
45
40
 
46
41
  // src/chat/agent-invocations/work.ts
47
42
  import { z } from "zod";
@@ -399,23 +394,34 @@ async function persistTerminalLifecycle(invocation) {
399
394
  });
400
395
  }
401
396
  }
402
- async function projectTerminalSession(invocation) {
403
- const session = await getAgentTurnSessionRecord(
397
+ async function projectTerminalTurn(invocation) {
398
+ let turn = await getTurnRecord(
404
399
  invocation.childConversationId,
405
400
  getAgentInvocationTurnId(invocation.invocationId)
406
401
  );
407
- if (!session) {
402
+ if (!turn) {
408
403
  return void 0;
409
404
  }
410
- if (session.state === "awaiting_resume" || session.state === "running") {
405
+ if (turn.state === "running") {
406
+ turn = await failTurnRecord({
407
+ conversationId: turn.conversationId,
408
+ expectedVersion: turn.version,
409
+ turnId: turn.turnId,
410
+ errorMessage: "Agent invocation lost its worker before it could pause"
411
+ });
412
+ if (!turn) {
413
+ return void 0;
414
+ }
415
+ }
416
+ if (turn.state === "paused") {
411
417
  return void 0;
412
418
  }
413
- const result = getTerminalAssistantMessages(session.piMessages).map(getAssistantReplyText).filter((text) => text !== void 0).join("\n\n");
414
- const failed = session.state !== "completed" || Boolean(session.errorMessage);
419
+ const result = getTerminalAssistantMessages(turn.piMessages).map(getAssistantReplyText).filter((text) => text !== void 0).join("\n\n");
420
+ const failed = turn.state !== "completed" || Boolean(turn.errorMessage);
415
421
  return await completeAgentInvocation({
416
422
  invocationId: invocation.invocationId,
417
423
  ...failed ? {
418
- errorMessage: session.errorMessage ?? "Agent invocation failed",
424
+ errorMessage: turn.errorMessage ?? "Agent invocation failed",
419
425
  status: "failed"
420
426
  } : {
421
427
  result,
@@ -423,40 +429,6 @@ async function projectTerminalSession(invocation) {
423
429
  }
424
430
  });
425
431
  }
426
- async function recoverRunningSession(invocation) {
427
- const session = await getAgentTurnSessionRecord(
428
- invocation.childConversationId,
429
- getAgentInvocationTurnId(invocation.invocationId)
430
- );
431
- if (!session || session.state !== "running") {
432
- return;
433
- }
434
- const projection = await openConversationProjection({
435
- conversationId: invocation.childConversationId
436
- });
437
- const parked = await persistYieldSessionRecord({
438
- conversationId: invocation.childConversationId,
439
- currentSliceId: session.sliceId,
440
- errorMessage: "Recovered running agent invocation after worker loss",
441
- messages: session.piMessages,
442
- modelId: modelIdForProfile(botConfig, projection.modelProfile),
443
- // Execution actor and reasoning live on the parent invocation, not Redis.
444
- actor: invocation.actor,
445
- reasoningLevel: invocation.reasoningLevel,
446
- sessionId: session.sessionId,
447
- surface: session.surface
448
- });
449
- if (!parked) {
450
- await failAgentTurnSessionRecord({
451
- conversationId: invocation.childConversationId,
452
- expectedVersion: session.version,
453
- sessionId: session.sessionId,
454
- errorMessage: `Running agent invocation had no resumable boundary for ${invocation.invocationId}`
455
- });
456
- return;
457
- }
458
- await markAgentInvocationAwaitingResume(invocation.invocationId);
459
- }
460
432
  function blockingInvocationError(error) {
461
433
  const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
462
434
  return cause instanceof AuthorizationFlowDisabledError || cause instanceof PluginCredentialFailureError ? cause : void 0;
@@ -508,8 +480,7 @@ function createAgentInvocationWorker(options) {
508
480
  await acknowledge();
509
481
  return { status: "completed" };
510
482
  }
511
- await recoverRunningSession(invocation);
512
- const projected = await projectTerminalSession(invocation);
483
+ const projected = await projectTerminalTurn(invocation);
513
484
  if (projected && isTerminalAgentInvocation(projected)) {
514
485
  await persistTerminalLifecycle(projected);
515
486
  await acknowledge();
@@ -653,17 +624,18 @@ function createAgentInvocationWorker(options) {
653
624
  sandboxRef: result.sandboxRef ?? sandboxRef
654
625
  });
655
626
  if (result.piMessages?.length) {
656
- await persistCompletedSessionRecord({
627
+ await saveTurnCheckpoint({
628
+ mode: "completed",
657
629
  conversationId: invocation.childConversationId,
658
- currentDurationMs: result.diagnostics.durationMs,
659
- currentUsage: result.diagnostics.usage,
630
+ turnId,
631
+ durationMs: result.diagnostics.durationMs,
632
+ usage: result.diagnostics.usage,
660
633
  destination: invocation.destination,
661
634
  destinationVisibility: invocation.destinationVisibility,
662
635
  ...failed ? {
663
636
  errorMessage: result.diagnostics.errorMessage ?? "Agent invocation failed"
664
637
  } : {},
665
- sessionId: turnId,
666
- allMessages: result.piMessages,
638
+ messages: result.piMessages,
667
639
  modelId: result.diagnostics.modelId,
668
640
  actor: invocation.actor,
669
641
  reasoningLevel: result.diagnostics.reasoningLevel,
@@ -1,3 +1,6 @@
1
+ import {
2
+ CONVERSATION_QUEUE_SCHEMA_VERSION
3
+ } from "./chunk-JAL3CH4G.js";
1
4
  import {
2
5
  JUNIOR_THREAD_STATE_TTL_MS
3
6
  } from "./chunk-3Y47VMHV.js";
@@ -5,14 +8,14 @@ import {
5
8
  getConversationStore,
6
9
  parseDestination,
7
10
  sameDestination
8
- } from "./chunk-SBZP2J5Q.js";
11
+ } from "./chunk-2UH3JI64.js";
9
12
  import {
10
13
  getDefaultRedisStateAdapterFor,
11
14
  getStateAdapter
12
- } from "./chunk-UDQMY6RS.js";
15
+ } from "./chunk-QUG4JSZK.js";
13
16
  import {
14
17
  getChatConfig
15
- } from "./chunk-3GU4PWA3.js";
18
+ } from "./chunk-XFKIRN3Q.js";
16
19
  import {
17
20
  parseStoredSlackActor
18
21
  } from "./chunk-HZF5P5UN.js";
@@ -20,13 +23,13 @@ import {
20
23
  isRecord,
21
24
  toOptionalNumber,
22
25
  toOptionalString
23
- } from "./chunk-RIFJUJSI.js";
26
+ } from "./chunk-2LWPFSB4.js";
24
27
 
25
28
  // src/chat/task-execution/state.ts
26
29
  import { randomUUID } from "crypto";
27
30
  import { destinationSchema } from "@sentry/junior-plugin-api";
28
31
  import { z } from "zod";
29
- var CONVERSATION_PREFIX = "junior:conversation";
32
+ var CONVERSATION_PREFIX = "junior:conversation:v2";
30
33
  var CONVERSATION_SCHEMA_VERSION = 2;
31
34
  var CONVERSATION_ACTIVITY_INDEX_MAX_LENGTH = 1e4;
32
35
  var CONVERSATION_INDEX_LOCK_TTL_MS = 1e4;
@@ -133,17 +136,16 @@ function normalizeSource(value) {
133
136
  return parsed.success ? parsed.data : void 0;
134
137
  }
135
138
  function normalizeExecutionStatus(value) {
136
- if (value === "awaiting_resume" || value === "failed" || value === "idle" || value === "pending" || value === "running") {
139
+ if (value === "paused") {
140
+ return value;
141
+ }
142
+ if (value === "failed" || value === "idle" || value === "pending" || value === "running") {
137
143
  return value;
138
144
  }
139
145
  return void 0;
140
146
  }
141
- function normalizeMessage(value, schemaVersion) {
142
- const candidate = schemaVersion === 1 && isRecord(value) && value.delivery === void 0 ? {
143
- ...value,
144
- delivery: "defer"
145
- } : value;
146
- const parsed = inboundMessageSchema.safeParse(candidate);
147
+ function normalizeMessage(value) {
148
+ const parsed = inboundMessageSchema.safeParse(value);
147
149
  return parsed.success ? parsed.data : void 0;
148
150
  }
149
151
  function isFinalAttempt(message) {
@@ -170,7 +172,7 @@ function normalizeLease(value) {
170
172
  expiresAtMs
171
173
  };
172
174
  }
173
- function normalizeExecution(conversationId, value, schemaVersion) {
175
+ function normalizeExecution(conversationId, value) {
174
176
  if (!isRecord(value)) {
175
177
  return void 0;
176
178
  }
@@ -181,7 +183,7 @@ function normalizeExecution(conversationId, value, schemaVersion) {
181
183
  const pendingMessages2 = [];
182
184
  if (Array.isArray(value.pendingMessages)) {
183
185
  for (const rawMessage of value.pendingMessages) {
184
- const message = normalizeMessage(rawMessage, schemaVersion);
186
+ const message = normalizeMessage(rawMessage);
185
187
  if (!message || message.conversationId !== conversationId) {
186
188
  return void 0;
187
189
  }
@@ -215,19 +217,14 @@ function normalizeExecution(conversationId, value, schemaVersion) {
215
217
  };
216
218
  }
217
219
  function normalizeConversation(conversationId, value) {
218
- if (!isRecord(value) || value.schemaVersion !== 1 && value.schemaVersion !== CONVERSATION_SCHEMA_VERSION) {
220
+ if (!isRecord(value) || value.schemaVersion !== CONVERSATION_SCHEMA_VERSION) {
219
221
  return void 0;
220
222
  }
221
- const schemaVersion = value.schemaVersion;
222
223
  const storedConversationId = toOptionalString(value.conversationId);
223
224
  const createdAtMs = toOptionalNumber(value.createdAtMs);
224
225
  const lastActivityAtMs = toOptionalNumber(value.lastActivityAtMs);
225
226
  const updatedAtMs = toOptionalNumber(value.updatedAtMs);
226
- const execution = normalizeExecution(
227
- conversationId,
228
- value.execution,
229
- schemaVersion
230
- );
227
+ const execution = normalizeExecution(conversationId, value.execution);
231
228
  const destination = value.destination === void 0 ? void 0 : parseDestination(value.destination);
232
229
  if (storedConversationId !== conversationId || typeof createdAtMs !== "number" || typeof lastActivityAtMs !== "number" || typeof updatedAtMs !== "number" || !execution || value.destination !== void 0 && !destination) {
233
230
  return void 0;
@@ -705,7 +702,7 @@ async function appendInboundMessage(args) {
705
702
  );
706
703
  return { status: "duplicate" };
707
704
  }
708
- const status = current.execution.lease && current.execution.status === "running" ? "running" : current.execution.lease ? "awaiting_resume" : "pending";
705
+ const status = current.execution.lease && current.execution.status === "running" ? "running" : current.execution.lease ? "paused" : "pending";
709
706
  const next = {
710
707
  ...current,
711
708
  destination: current.destination ?? args.message.destination,
@@ -752,7 +749,7 @@ async function requestConversationWork(args) {
752
749
  destination: args.destination,
753
750
  nowMs
754
751
  });
755
- const status = current.execution.lease ? "awaiting_resume" : "pending";
752
+ const status = current.execution.lease ? "paused" : "pending";
756
753
  await writeConversation(
757
754
  state,
758
755
  lock,
@@ -845,7 +842,7 @@ async function startConversationWork(args) {
845
842
  {
846
843
  ...current.execution,
847
844
  lease,
848
- status: current.execution.status === "awaiting_resume" ? "awaiting_resume" : "running",
845
+ status: current.execution.status === "paused" ? "paused" : "running",
849
846
  runId: current.execution.runId ?? randomUUID(),
850
847
  lastEnqueuedAtMs: void 0,
851
848
  retryCount: startsNewRun ? 0 : current.execution.retryCount
@@ -984,7 +981,7 @@ async function ackMessages(args) {
984
981
  return true;
985
982
  });
986
983
  }
987
- async function requestConversationContinuation(args) {
984
+ async function requestAnotherSlice(args) {
988
985
  const nowMs = args.nowMs ?? now();
989
986
  return await withConversationMutation(args, async (state, lock) => {
990
987
  const current = await readConversation(state, args.conversationId);
@@ -1003,7 +1000,7 @@ async function requestConversationContinuation(args) {
1003
1000
  current,
1004
1001
  {
1005
1002
  ...current.execution,
1006
- status: "awaiting_resume"
1003
+ status: "paused"
1007
1004
  },
1008
1005
  nowMs
1009
1006
  )
@@ -1015,7 +1012,7 @@ async function beginConversationResume(args) {
1015
1012
  const nowMs = args.nowMs ?? now();
1016
1013
  return await withConversationMutation(args, async (state, lock) => {
1017
1014
  const current = await readConversation(state, args.conversationId);
1018
- if (!current || current.execution.lease?.token !== args.leaseToken || current.execution.status !== "awaiting_resume") {
1015
+ if (!current || current.execution.lease?.token !== args.leaseToken || current.execution.status !== "paused") {
1019
1016
  return false;
1020
1017
  }
1021
1018
  await writeConversation(
@@ -1077,7 +1074,7 @@ async function recordConversationRetry(args) {
1077
1074
  retryCount: count,
1078
1075
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1079
1076
  runId: stopped ? void 0 : current.execution.runId,
1080
- status: stopped ? "failed" : "awaiting_resume"
1077
+ status: stopped ? "failed" : "paused"
1081
1078
  },
1082
1079
  nowMs
1083
1080
  )
@@ -1093,7 +1090,7 @@ async function completeConversationWork(args) {
1093
1090
  return "lost_lease";
1094
1091
  }
1095
1092
  const hasPending = pendingMessages(current).length > 0;
1096
- const needsRun = current.execution.status === "awaiting_resume";
1093
+ const needsRun = current.execution.status === "paused";
1097
1094
  const runnable = needsRun || hasPending;
1098
1095
  await writeConversation(
1099
1096
  state,
@@ -1103,7 +1100,7 @@ async function completeConversationWork(args) {
1103
1100
  {
1104
1101
  ...current.execution,
1105
1102
  lease: void 0,
1106
- status: needsRun ? "awaiting_resume" : hasPending ? "pending" : "idle",
1103
+ status: needsRun ? "paused" : hasPending ? "pending" : "idle",
1107
1104
  lastProgressAtMs: args.madeProgress === false ? current.execution.lastProgressAtMs : nowMs,
1108
1105
  retryCount: runnable || args.madeProgress === false ? current.execution.retryCount : 0,
1109
1106
  runId: runnable ? current.execution.runId : void 0
@@ -1230,7 +1227,7 @@ async function clearExpiredConversationLease(args) {
1230
1227
  retryCount,
1231
1228
  pendingMessages: stopped ? [] : current.execution.pendingMessages,
1232
1229
  runId: stopped ? void 0 : current.execution.runId,
1233
- status: stopped ? "failed" : "awaiting_resume"
1230
+ status: stopped ? "failed" : "paused"
1234
1231
  },
1235
1232
  nowMs
1236
1233
  )
@@ -1331,6 +1328,7 @@ async function ensureConversationWake(args) {
1331
1328
  }
1332
1329
  const queueResult = await args.queue.send(
1333
1330
  {
1331
+ schemaVersion: CONVERSATION_QUEUE_SCHEMA_VERSION,
1334
1332
  conversationId: args.conversationId
1335
1333
  },
1336
1334
  {
@@ -1447,8 +1445,8 @@ async function ackMessages2(args) {
1447
1445
  await recordExecutionMetadata(args);
1448
1446
  return result;
1449
1447
  }
1450
- async function requestConversationContinuation2(args) {
1451
- const result = await requestConversationContinuation(args);
1448
+ async function requestAnotherSlice2(args) {
1449
+ const result = await requestAnotherSlice(args);
1452
1450
  await recordExecutionMetadata(args);
1453
1451
  return result;
1454
1452
  }
@@ -1511,7 +1509,7 @@ export {
1511
1509
  checkInConversationWork2 as checkInConversationWork,
1512
1510
  drainConversationMailbox2 as drainConversationMailbox,
1513
1511
  ackMessages2 as ackMessages,
1514
- requestConversationContinuation2 as requestConversationContinuation,
1512
+ requestAnotherSlice2 as requestAnotherSlice,
1515
1513
  beginConversationResume2 as beginConversationResume,
1516
1514
  releaseConversationWork2 as releaseConversationWork,
1517
1515
  completeConversationWork2 as completeConversationWork,
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  resolveBaseUrl
3
- } from "./chunk-KQBXT5B7.js";
3
+ } from "./chunk-FUBRJA5F.js";
4
4
  import {
5
5
  createPluginLogger,
6
6
  getPlugins
7
- } from "./chunk-44RJWAND.js";
7
+ } from "./chunk-ZIMRGFYL.js";
8
8
  import {
9
9
  getDb,
10
10
  parseDestination
11
- } from "./chunk-SBZP2J5Q.js";
11
+ } from "./chunk-2UH3JI64.js";
12
12
  import {
13
13
  sleep
14
14
  } from "./chunk-EM225ITJ.js";
15
15
  import {
16
16
  acquireActiveLock,
17
17
  getStateAdapter
18
- } from "./chunk-UDQMY6RS.js";
18
+ } from "./chunk-QUG4JSZK.js";
19
19
  import {
20
20
  pluginCatalogRuntime
21
- } from "./chunk-ZF3N3JD6.js";
21
+ } from "./chunk-SIN3MXH6.js";
22
22
  import {
23
23
  fetchWithBoundedOAuthErrorBodies
24
- } from "./chunk-A67GZN73.js";
24
+ } from "./chunk-CD2XFGYQ.js";
25
25
  import {
26
26
  isRecord
27
- } from "./chunk-RIFJUJSI.js";
27
+ } from "./chunk-2LWPFSB4.js";
28
28
 
29
29
  // src/chat/capabilities/router.ts
30
30
  var ProviderCredentialRouter = class {
@@ -1,6 +1,8 @@
1
1
  // src/chat/task-execution/queue.ts
2
2
  import { z } from "zod";
3
+ var CONVERSATION_QUEUE_SCHEMA_VERSION = 2;
3
4
  var conversationQueueMessageSchema = z.object({
5
+ schemaVersion: z.literal(CONVERSATION_QUEUE_SCHEMA_VERSION),
4
6
  conversationId: z.string().trim().min(1)
5
7
  }).strict();
6
8
  var ConversationQueueMessageRejectedError = class extends Error {
@@ -18,6 +20,7 @@ function isConversationQueueMessageRejectedError(error) {
18
20
  }
19
21
 
20
22
  export {
23
+ CONVERSATION_QUEUE_SCHEMA_VERSION,
21
24
  conversationQueueMessageSchema,
22
25
  ConversationQueueMessageRejectedError,
23
26
  isConversationQueueMessageRejectedError
@@ -88,7 +88,8 @@ var conversationAuxiliaryCostsSchema = z2.object({
88
88
  var conversationSourceTaskSchema = z2.object({
89
89
  id: z2.string().min(1).optional(),
90
90
  kind: z2.enum(["scheduled", "event"]),
91
- label: z2.string().min(1).optional()
91
+ label: z2.string().min(1).optional(),
92
+ title: z2.string().min(1).optional()
92
93
  }).strict().superRefine((value, context) => {
93
94
  if (Boolean(value.id) !== Boolean(value.label)) {
94
95
  context.addIssue({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logWarn
3
- } from "./chunk-RIFJUJSI.js";
3
+ } from "./chunk-2LWPFSB4.js";
4
4
 
5
5
  // src/chat/conversation-privacy.ts
6
6
  import { AsyncLocalStorage } from "async_hooks";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAndEnqueueAgentInvocation
3
- } from "./chunk-PELZ2ZSY.js";
3
+ } from "./chunk-HISR3DTV.js";
4
4
  import {
5
5
  actorFromRouting,
6
6
  toolInvocationDestination
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-UTL3MHPC.js";
4
4
  import {
5
5
  parseSlackThreadId
6
- } from "./chunk-PKH6762I.js";
6
+ } from "./chunk-DXEQAIUV.js";
7
7
  import {
8
8
  normalizeSlackConversationId
9
- } from "./chunk-QE3TICD4.js";
9
+ } from "./chunk-TZRXYWRE.js";
10
10
 
11
11
  // src/handlers/health.ts
12
12
  function readHealthReport() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  recordTaskExecution
3
- } from "./chunk-WSOLZJJS.js";
3
+ } from "./chunk-EIX2LQ6L.js";
4
4
  import {
5
5
  pluginTaskId,
6
6
  pluginTaskParamsSchema,
@@ -10,14 +10,14 @@ import {
10
10
  calculateContextCompactionTargetTokens,
11
11
  estimateTextTokens,
12
12
  getConversationContextCompactionTriggerTokens
13
- } from "./chunk-CNTWB2SM.js";
13
+ } from "./chunk-VTDMB7XX.js";
14
14
  import {
15
15
  buildDeterministicTurnId,
16
16
  clearPendingAuth,
17
17
  coerceThreadConversationState,
18
- getAgentTurnSessionRecord,
19
18
  getPersistedThreadState,
20
19
  getPiMessageRole,
20
+ getTurnRecord,
21
21
  hydrateConversationMessages,
22
22
  instructionTextForProjection,
23
23
  isToolResultError,
@@ -28,14 +28,14 @@ import {
28
28
  normalizeToolNameFromResult,
29
29
  persistThreadStateById,
30
30
  stripRuntimeTurnContext
31
- } from "./chunk-BEGGFVFR.js";
31
+ } from "./chunk-ZIAMN2UW.js";
32
32
  import {
33
33
  JUNIOR_THREAD_STATE_TTL_MS
34
34
  } from "./chunk-3Y47VMHV.js";
35
35
  import {
36
36
  fallbackShortTitle,
37
37
  generateShortTitle
38
- } from "./chunk-54JMYQYS.js";
38
+ } from "./chunk-ZYAJMESY.js";
39
39
  import {
40
40
  createPluginConversationEvents,
41
41
  createPluginEmbedder,
@@ -43,15 +43,15 @@ import {
43
43
  createPluginModel,
44
44
  createPluginState,
45
45
  getPlugins
46
- } from "./chunk-44RJWAND.js";
46
+ } from "./chunk-ZIMRGFYL.js";
47
47
  import {
48
48
  getConversationStore,
49
49
  getDb,
50
50
  sameActorIdentity
51
- } from "./chunk-SBZP2J5Q.js";
51
+ } from "./chunk-2UH3JI64.js";
52
52
  import {
53
53
  getStateAdapter
54
- } from "./chunk-UDQMY6RS.js";
54
+ } from "./chunk-QUG4JSZK.js";
55
55
  import {
56
56
  ProviderError,
57
57
  botConfig,
@@ -59,7 +59,7 @@ import {
59
59
  findProviderError,
60
60
  getProviderErrorAttributes,
61
61
  getProviderErrorUserMessage
62
- } from "./chunk-3GU4PWA3.js";
62
+ } from "./chunk-XFKIRN3Q.js";
63
63
  import {
64
64
  credentialSubjectSchema
65
65
  } from "./chunk-RUIXF3YQ.js";
@@ -70,7 +70,7 @@ import {
70
70
  buildTurnFailureResponse,
71
71
  logWarn,
72
72
  setSpanAttributes
73
- } from "./chunk-RIFJUJSI.js";
73
+ } from "./chunk-2LWPFSB4.js";
74
74
 
75
75
  // src/chat/services/conversation-memory.ts
76
76
  var CONTEXT_MIN_LIVE_MESSAGES = 12;
@@ -410,7 +410,7 @@ import {
410
410
 
411
411
  // src/chat/services/turn-session-routing.ts
412
412
  async function resolveTurnSessionRouting(args) {
413
- const conversationStore = args.conversationStore ?? (await import("./db-EFLHTBU6.js")).getConversationStore();
413
+ const conversationStore = args.conversationStore ?? (await import("./db-62PW6LM3.js")).getConversationStore();
414
414
  const conversation = await conversationStore.get({
415
415
  conversationId: args.conversationId
416
416
  });
@@ -998,10 +998,7 @@ async function withPluginTaskLock(taskId, callback) {
998
998
  }
999
999
  }
1000
1000
  async function loadPluginRun(params) {
1001
- const record = await getAgentTurnSessionRecord(
1002
- params.conversationId,
1003
- params.sessionId
1004
- );
1001
+ const record = await getTurnRecord(params.conversationId, params.sessionId);
1005
1002
  if (!record) {
1006
1003
  throw new Error("Completed plugin task session record is unavailable");
1007
1004
  }
@@ -1033,7 +1030,7 @@ async function loadPluginRun(params) {
1033
1030
  // stripped transcript, so it reflects every committed instruction actor.
1034
1031
  actors: record.actors,
1035
1032
  ...runActor ? { actor: runActor } : {},
1036
- runId: record.sessionId,
1033
+ runId: record.turnId,
1037
1034
  source: routing.source,
1038
1035
  transcript: [...contextEntries, ...runEntries]
1039
1036
  });
@@ -1085,7 +1082,7 @@ async function scheduleSessionCompletedPluginTasks(params, options = {}) {
1085
1082
  if (taskRegistrations.length === 0) {
1086
1083
  return;
1087
1084
  }
1088
- const record = await getAgentTurnSessionRecord(
1085
+ const record = await getTurnRecord(
1089
1086
  coreParams.conversationId,
1090
1087
  coreParams.sessionId
1091
1088
  );
@@ -1,16 +1,54 @@
1
1
  import {
2
2
  getChatConfig
3
- } from "./chunk-3GU4PWA3.js";
3
+ } from "./chunk-XFKIRN3Q.js";
4
4
 
5
5
  // src/chat/state/adapter.ts
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
7
7
  import { createRedisState } from "@chat-adapter/state-redis";
8
8
 
9
9
  // src/chat/state/locks.ts
10
+ import { setTimeout as sleep } from "timers/promises";
10
11
  var ACTIVE_LOCK_TTL_MS = 9e4;
12
+ var MUTATION_LOCK_TTL_MS = 1e4;
11
13
  async function acquireActiveLock(state, threadId) {
12
14
  return await state.acquireLock(threadId, ACTIVE_LOCK_TTL_MS);
13
15
  }
16
+ async function withLock(state, key, run, options = {}) {
17
+ const startedAtMs = Date.now();
18
+ let lock;
19
+ while (true) {
20
+ lock = await state.acquireLock(key, options.ttlMs ?? ACTIVE_LOCK_TTL_MS);
21
+ if (lock) break;
22
+ if (Date.now() - startedAtMs >= (options.waitMs ?? 0)) {
23
+ return { acquired: false };
24
+ }
25
+ await sleep(options.retryMs ?? 25, void 0, { ref: false });
26
+ }
27
+ const ttlMs = options.ttlMs ?? ACTIVE_LOCK_TTL_MS;
28
+ const heartbeat = options.keepAlive ? setInterval(
29
+ () => {
30
+ void state.extendLock(lock, ttlMs);
31
+ },
32
+ Math.max(1, Math.floor(ttlMs / 3))
33
+ ) : void 0;
34
+ heartbeat?.unref();
35
+ try {
36
+ return { acquired: true, value: await run(lock) };
37
+ } finally {
38
+ if (heartbeat) clearInterval(heartbeat);
39
+ await state.releaseLock(lock);
40
+ }
41
+ }
42
+ async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
43
+ if (!await state.extendLock(lock, ttlMs)) {
44
+ throw new Error(
45
+ `Lock ownership was lost before write for ${lock.threadId}`
46
+ );
47
+ }
48
+ }
49
+ async function withActiveLock(state, key, run) {
50
+ return await withLock(state, key, run);
51
+ }
14
52
 
15
53
  // src/chat/state/adapter.ts
16
54
  var ACTIVE_LOCK_HEARTBEAT_MS = 3e4;
@@ -272,7 +310,11 @@ async function disconnectStateAdapter() {
272
310
  }
273
311
 
274
312
  export {
313
+ MUTATION_LOCK_TTL_MS,
275
314
  acquireActiveLock,
315
+ withLock,
316
+ fenceLock,
317
+ withActiveLock,
276
318
  getDefaultRedisStateAdapterFor,
277
319
  getStateAdapter,
278
320
  disconnectStateAdapter