@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
package/dist/app.js CHANGED
@@ -1,26 +1,25 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-4X5KM7Z6.js";
3
+ } from "./chunk-RUSS62EN.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-GKA74DRA.js";
6
+ } from "./chunk-LVVSIMBB.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
11
  routeAgentInvocationWork
12
- } from "./chunk-PELZ2ZSY.js";
12
+ } from "./chunk-HISR3DTV.js";
13
13
  import {
14
14
  GET as GET2,
15
15
  GET2 as GET3,
16
- ResumeTurnBusyError,
17
16
  buildAuthPauseResponse,
18
17
  buildSlackOutputMessage,
19
18
  createSlackAdapterAssistantStatusSession,
20
19
  getAssistantThreadContext,
21
- getAwaitingAgentContinueRequest,
22
20
  getChannelId,
23
21
  getMessageTs,
22
+ getPausedTurnRequest,
24
23
  getRunId,
25
24
  getSlackApiErrorCode,
26
25
  getSlackErrorObservabilityAttributes,
@@ -33,13 +32,13 @@ import {
33
32
  receiveLocalOAuthCredential,
34
33
  resumeSlackTurn,
35
34
  runWithTurnRequestDeadline,
36
- scheduleAgentContinue,
37
35
  sendSlackReply,
38
36
  shouldKeepProcessingReactionForToolInvocation,
39
37
  splitSlackReplyText,
40
38
  startSlackProcessingReaction,
41
- stripLeadingBotMention
42
- } from "./chunk-QUZJDAQQ.js";
39
+ stripLeadingBotMention,
40
+ wakePausedTurn
41
+ } from "./chunk-2XET6PKP.js";
43
42
  import "./chunk-FA6POGLH.js";
44
43
  import {
45
44
  CONVERSATION_WORK_STALE_ENQUEUE_MS,
@@ -51,7 +50,7 @@ import {
51
50
  isInvalidConversationRecordError,
52
51
  listActiveConversationIds,
53
52
  removeActiveConversation
54
- } from "./chunk-HD6BHR25.js";
53
+ } from "./chunk-HLOUZC5C.js";
55
54
  import {
56
55
  buildConversationContext,
57
56
  buildDeliveredTurnStatePatch,
@@ -90,8 +89,9 @@ import {
90
89
  requireTurnFailureEventId,
91
90
  resolveTurnSessionRouting,
92
91
  scheduleSessionCompletedPluginTasks,
92
+ turnHasReply,
93
93
  upsertConversationMessage
94
- } from "./chunk-W7JFV5SB.js";
94
+ } from "./chunk-QJBDABQA.js";
95
95
  import {
96
96
  ConversationTurnLifecycleService
97
97
  } from "./chunk-Q6QZTTLS.js";
@@ -100,21 +100,21 @@ import {
100
100
  conversationVisibilityFromSlackChannelType,
101
101
  resolveSlackChannelTypeFromMessage,
102
102
  resolveSlackConversationContext
103
- } from "./chunk-SHEEZSLY.js";
103
+ } from "./chunk-PJ4NMVQB.js";
104
104
  import "./chunk-4CODA7P5.js";
105
105
  import {
106
106
  recordTaskExecution
107
- } from "./chunk-WSOLZJJS.js";
107
+ } from "./chunk-EIX2LQ6L.js";
108
108
  import "./chunk-UTL3MHPC.js";
109
109
  import {
110
110
  getVercelConversationWorkQueue,
111
111
  resolveConversationWorkQueueTopic,
112
112
  verifyConversationQueueMessage
113
- } from "./chunk-KCBZSJRU.js";
113
+ } from "./chunk-WR76IVA5.js";
114
114
  import {
115
115
  conversationQueueMessageSchema,
116
116
  isConversationQueueMessageRejectedError
117
- } from "./chunk-IUFM5JWV.js";
117
+ } from "./chunk-JAL3CH4G.js";
118
118
  import {
119
119
  PLUGIN_TASK_QUEUE_TOPIC,
120
120
  createVercelQueueClient,
@@ -123,7 +123,7 @@ import {
123
123
  import {
124
124
  validatePluginEgressCredentialHooks,
125
125
  validatePluginRegistrations
126
- } from "./chunk-LDWNYCZ6.js";
126
+ } from "./chunk-WF5HVH3M.js";
127
127
  import {
128
128
  defineJuniorPlugins,
129
129
  pluginCatalogConfigFromEnv,
@@ -156,18 +156,18 @@ import {
156
156
  setConfigDefaults,
157
157
  shouldEmitDevAgentTrace,
158
158
  shouldPropagateSandboxEgressTrace
159
- } from "./chunk-SSDTQDYQ.js";
159
+ } from "./chunk-64SBYW2O.js";
160
160
  import {
161
161
  AuthorizationFlowDisabledError,
162
162
  PluginCredentialFailureError
163
- } from "./chunk-DVO5VKYQ.js";
163
+ } from "./chunk-B46ZMVOV.js";
164
164
  import "./chunk-DIB4GX3G.js";
165
165
  import {
166
166
  createUserTokenStore,
167
167
  deleteMcpAuthSessionsForUserProvider,
168
168
  deleteMcpServerSessionId,
169
169
  deleteMcpStoredOAuthCredentials
170
- } from "./chunk-BBCWYXHB.js";
170
+ } from "./chunk-I47UGQPJ.js";
171
171
  import {
172
172
  RetryableDeliveryError
173
173
  } from "./chunk-R776HKPK.js";
@@ -175,16 +175,16 @@ import {
175
175
  formatProviderLabel,
176
176
  postSlackMessage,
177
177
  startOAuthFlow
178
- } from "./chunk-KQBXT5B7.js";
178
+ } from "./chunk-FUBRJA5F.js";
179
179
  import {
180
180
  estimateTextTokens
181
- } from "./chunk-CNTWB2SM.js";
181
+ } from "./chunk-VTDMB7XX.js";
182
182
  import {
183
183
  ConversationTurnBoundaryError,
184
184
  CooperativeTurnYieldError,
185
185
  TurnInputCommitLostError,
186
186
  TurnInputDeferredError,
187
- abandonAgentTurnSessionRecord,
187
+ abandonTurnRecord,
188
188
  buildDeterministicAssistantMessageId,
189
189
  buildDeterministicTurnId,
190
190
  clearPendingAuth,
@@ -192,24 +192,26 @@ import {
192
192
  coerceThreadConversationState,
193
193
  commitAcceptedReply,
194
194
  commitMessages,
195
- completeDeliveredTurn,
196
- failAgentTurnSessionRecord,
197
- getAgentTurnSessionRecord,
198
- getAgentTurnSessionRecordForResume,
195
+ completeTurnRecord,
196
+ failTurnRecord,
199
197
  getAssistantReplyText,
200
198
  getChannelConfigurationService,
201
199
  getChannelConfigurationServiceById,
202
200
  getConversationTurnBoundaryError,
203
201
  getPersistedSandboxState,
204
202
  getPersistedThreadState,
203
+ getTurnRecord,
204
+ getTurnRecordForResume,
205
205
  hydrateConversationMessages,
206
206
  isCooperativeTurnYieldError,
207
207
  isTurnInputCommitLostError,
208
208
  isTurnInputDeferredError,
209
- listAgentTurnSessionSummariesForConversation,
209
+ listTurnSummaries,
210
210
  loadConversationProjection,
211
211
  loadProjection,
212
+ loadTurnCheckpoint,
212
213
  markTurnClosed,
214
+ markTurnCompleted,
213
215
  markTurnFailed,
214
216
  mergeArtifactsState,
215
217
  persistConversationMessageSummaries,
@@ -218,12 +220,12 @@ import {
218
220
  persistThreadState,
219
221
  persistThreadStateById,
220
222
  persistWithRetry,
221
- persistYieldSessionRecord,
222
- recordAgentTurnSessionSummary,
223
+ recordTurnSummary,
224
+ saveTurnCheckpoint,
223
225
  startActiveTurn,
224
226
  stripRuntimeTurnContext,
225
227
  trimTrailingAssistantMessages
226
- } from "./chunk-BEGGFVFR.js";
228
+ } from "./chunk-ZIAMN2UW.js";
227
229
  import "./chunk-3Y47VMHV.js";
228
230
  import "./chunk-HUO3UTAQ.js";
229
231
  import {
@@ -233,17 +235,17 @@ import {
233
235
  import {
234
236
  getSandboxResourceConfig,
235
237
  setSandboxResourceConfig
236
- } from "./chunk-7KAW7UF4.js";
238
+ } from "./chunk-GUWLDMGF.js";
237
239
  import {
238
240
  createSchedulerSqlStore,
239
241
  findMatchingEventTasks,
240
242
  logScheduledTaskRunSkipped,
241
243
  scheduledTaskRunAttributes
242
- } from "./chunk-ZZCTGAIT.js";
244
+ } from "./chunk-YD54Q45G.js";
243
245
  import {
244
246
  parseSlackThreadId
245
- } from "./chunk-PKH6762I.js";
246
- import "./chunk-54JMYQYS.js";
247
+ } from "./chunk-DXEQAIUV.js";
248
+ import "./chunk-ZYAJMESY.js";
247
249
  import "./chunk-HLXXQI5Q.js";
248
250
  import "./chunk-PDO5BLNM.js";
249
251
  import "./chunk-UIE3R5XU.js";
@@ -263,7 +265,7 @@ import {
263
265
  verifyEventTaskCredentialSubject,
264
266
  verifyScheduledTaskCredentialSubject,
265
267
  verifySlackDirectCredentialSubject
266
- } from "./chunk-44RJWAND.js";
268
+ } from "./chunk-ZIMRGFYL.js";
267
269
  import {
268
270
  SlackActionError,
269
271
  downloadPrivateSlackFile,
@@ -273,7 +275,7 @@ import {
273
275
  normalizeSlackConversationId,
274
276
  runWithSlackInstallationToken,
275
277
  runWithWorkspaceTeamId
276
- } from "./chunk-QE3TICD4.js";
278
+ } from "./chunk-TZRXYWRE.js";
277
279
  import {
278
280
  contextProvenance,
279
281
  createSlackDestination,
@@ -285,20 +287,19 @@ import {
285
287
  requireSlackDestination,
286
288
  withConversationEventLock,
287
289
  withConversationMutationLock
288
- } from "./chunk-SBZP2J5Q.js";
290
+ } from "./chunk-2UH3JI64.js";
289
291
  import {
290
292
  juniorAgentBindings,
291
293
  juniorAgentInvocations,
292
294
  juniorConversationEvents,
293
295
  juniorConversations
294
- } from "./chunk-HNO2E5WB.js";
295
- import {
296
- sleep
297
- } from "./chunk-EM225ITJ.js";
296
+ } from "./chunk-27TEJTZO.js";
297
+ import "./chunk-EM225ITJ.js";
298
298
  import {
299
299
  acquireActiveLock,
300
- getStateAdapter
301
- } from "./chunk-UDQMY6RS.js";
300
+ getStateAdapter,
301
+ withActiveLock
302
+ } from "./chunk-QUG4JSZK.js";
302
303
  import {
303
304
  STANDARD_MODEL_PROFILE,
304
305
  botConfig,
@@ -316,16 +317,16 @@ import {
316
317
  modelIdForProfile,
317
318
  setSlackReactionConfig,
318
319
  standardModelId
319
- } from "./chunk-3GU4PWA3.js";
320
+ } from "./chunk-XFKIRN3Q.js";
320
321
  import {
321
322
  juniorDestinations
322
323
  } from "./chunk-VFUK3X5B.js";
323
- import "./chunk-STFCL3K4.js";
324
- import "./chunk-SUK7NC5A.js";
324
+ import "./chunk-JTGS3ZZE.js";
325
+ import "./chunk-5PNPQYTO.js";
325
326
  import {
326
327
  pluginCatalogRuntime
327
- } from "./chunk-ZF3N3JD6.js";
328
- import "./chunk-A67GZN73.js";
328
+ } from "./chunk-SIN3MXH6.js";
329
+ import "./chunk-CD2XFGYQ.js";
329
330
  import {
330
331
  credentialContextForActor
331
332
  } from "./chunk-RUIXF3YQ.js";
@@ -357,7 +358,7 @@ import {
357
358
  withContext,
358
359
  withLogContext,
359
360
  withSpan
360
- } from "./chunk-RIFJUJSI.js";
361
+ } from "./chunk-2LWPFSB4.js";
361
362
  import {
362
363
  continueTrace
363
364
  } from "./chunk-6GWA276C.js";
@@ -365,10 +366,10 @@ import "./chunk-OOUNJNMR.js";
365
366
  import "./chunk-H4HBKISO.js";
366
367
  import {
367
368
  JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
368
- } from "./chunk-WTX2RFJG.js";
369
+ } from "./chunk-DS3J6WGY.js";
369
370
  import {
370
371
  JUNIOR_VERSION
371
- } from "./chunk-I44JB7HQ.js";
372
+ } from "./chunk-GDV5LXRA.js";
372
373
  import "./chunk-MLKGABMK.js";
373
374
 
374
375
  // src/app.ts
@@ -533,12 +534,10 @@ async function resolveAgentDispatchId(context) {
533
534
  if (context.attempt.messages.length > 0) {
534
535
  return void 0;
535
536
  }
536
- const summaries = await listAgentTurnSessionSummariesForConversation(
537
- context.conversationId
538
- );
537
+ const summaries = await listTurnSummaries(context.conversationId);
539
538
  const activeDispatchIds = new Set(
540
539
  summaries.filter(
541
- (summary) => (summary.state === "awaiting_resume" || summary.state === "running") && Boolean(summary.dispatchId)
540
+ (summary) => (summary.state === "paused" || summary.state === "running") && Boolean(summary.dispatchId)
542
541
  ).map((summary) => summary.dispatchId).filter((id) => Boolean(id))
543
542
  );
544
543
  if (activeDispatchIds.size > 1) {
@@ -585,8 +584,10 @@ function createAgentDispatchWorkRouter(options) {
585
584
  async function readDispatchTurnResult(dispatch2) {
586
585
  const conversationId = getDispatchConversationId(dispatch2);
587
586
  const turnId = getDispatchTurnId(dispatch2.id);
588
- const storedSession = await getAgentTurnSessionRecord(conversationId, turnId);
589
- const summary = (await listAgentTurnSessionSummariesForConversation(conversationId)).find((candidate) => candidate.sessionId === turnId);
587
+ const storedSession = await getTurnRecord(conversationId, turnId);
588
+ const summary = (await listTurnSummaries(conversationId)).find(
589
+ (candidate) => candidate.turnId === turnId
590
+ );
590
591
  const session = storedSession ?? summary;
591
592
  const dispatchOutcome = summary?.dispatchOutcome ?? storedSession?.dispatchOutcome;
592
593
  const resultMessageTs = summary?.resultMessageId ?? storedSession?.resultMessageId;
@@ -607,7 +608,7 @@ async function readDispatchTurnResult(dispatch2) {
607
608
  if (!session) {
608
609
  return {};
609
610
  }
610
- if (session.state === "awaiting_resume") {
611
+ if (session.state === "paused") {
611
612
  return { hasResumableRun: true, outcome: "awaiting_resume" };
612
613
  }
613
614
  if (session.state === "running") {
@@ -652,15 +653,15 @@ function getDispatchBlockingError(error) {
652
653
  async function persistBlockedDispatchTurn(dispatch2, error) {
653
654
  const conversationId = getDispatchConversationId(dispatch2);
654
655
  const sessionId = getDispatchTurnId(dispatch2.id);
655
- const session = await getAgentTurnSessionRecord(conversationId, sessionId);
656
- await recordAgentTurnSessionSummary({
656
+ const session = await getTurnRecord(conversationId, sessionId);
657
+ await recordTurnSummary({
657
658
  actor: dispatch2.actor,
658
659
  conversationId,
659
660
  destination: dispatch2.destination,
660
661
  destinationVisibility: dispatch2.destinationVisibility,
661
662
  dispatchId: dispatch2.id,
662
663
  dispatchOutcome: "blocked",
663
- sessionId,
664
+ turnId: sessionId,
664
665
  sliceId: session?.sliceId ?? 1,
665
666
  source: dispatch2.source,
666
667
  state: "failed",
@@ -880,7 +881,9 @@ async function recoverConversationWork(args) {
880
881
  }
881
882
  if (recovery === "stopped") {
882
883
  logException(
883
- new Error("Conversation work stopped after repeated failed attempts"),
884
+ new Error(
885
+ "Conversation work stopped after repeated failed attempts"
886
+ ),
884
887
  "conversation.work.retry.exhausted",
885
888
  {
886
889
  "app.run.id": work.execution.runId ?? "unknown",
@@ -3098,14 +3101,14 @@ function createSlackConversationWorker(options) {
3098
3101
  if (records.length === 0) {
3099
3102
  const destination = requireSlackDestination(
3100
3103
  context.destination,
3101
- "Slack continuation recovery"
3104
+ "Slack paused-turn recovery"
3102
3105
  );
3103
3106
  await runWithSlackInstallation({
3104
3107
  adapter,
3105
3108
  installation: { teamId: destination.teamId },
3106
3109
  state,
3107
3110
  task: async () => {
3108
- await options.resumeAwaitingContinuation(context.conversationId, {
3111
+ await options.runNextPausedTurn(context.conversationId, {
3109
3112
  shouldYield: context.shouldYield
3110
3113
  });
3111
3114
  }
@@ -5945,9 +5948,9 @@ function createJuniorRuntimeServices(overrides = {}) {
5945
5948
  replyExecutor: {
5946
5949
  contextCompactor: overrides.replyExecutor?.contextCompactor ?? contextCompactor,
5947
5950
  agentRunner,
5948
- getAwaitingAgentContinueRequest: overrides.replyExecutor?.getAwaitingAgentContinueRequest ?? getAwaitingAgentContinueRequest,
5951
+ getPausedTurnRequest: overrides.replyExecutor?.getPausedTurnRequest ?? getPausedTurnRequest,
5949
5952
  lookupSlackUser: overrides.replyExecutor?.lookupSlackUser ?? lookupSlackUser,
5950
- scheduleAgentContinue: overrides.replyExecutor?.scheduleAgentContinue ?? scheduleAgentContinue,
5953
+ wakePausedTurn: overrides.replyExecutor?.wakePausedTurn ?? wakePausedTurn,
5951
5954
  scheduleSessionCompletedPluginTasks: overrides.replyExecutor?.scheduleSessionCompletedPluginTasks ?? (async (params) => {
5952
5955
  await scheduleSessionCompletedPluginTasks(params);
5953
5956
  }),
@@ -6183,7 +6186,7 @@ async function loadPiMessagesForTurn(args) {
6183
6186
  return {};
6184
6187
  }
6185
6188
  if (args.activeTurnId) {
6186
- const sessionRecord = await getAgentTurnSessionRecord(
6189
+ const sessionRecord = await getTurnRecord(
6187
6190
  args.conversationId,
6188
6191
  args.activeTurnId
6189
6192
  );
@@ -6473,20 +6476,20 @@ function createReplyToThread(deps) {
6473
6476
  return;
6474
6477
  }
6475
6478
  if (conversationId && activeTurnId) {
6476
- const resumeRequest = await deps.services.getAwaitingAgentContinueRequest({
6479
+ const pausedTurn = await deps.services.getPausedTurnRequest({
6477
6480
  conversationId,
6478
- sessionId: activeTurnId
6481
+ turnId: activeTurnId
6479
6482
  });
6480
- if (resumeRequest) {
6481
- if (!await appendParkedTurnInput(resumeRequest.sessionId)) {
6483
+ if (pausedTurn) {
6484
+ if (!await appendParkedTurnInput(pausedTurn.turnId)) {
6482
6485
  throw new TurnInputDeferredError();
6483
6486
  }
6484
6487
  try {
6485
- await deps.services.scheduleAgentContinue(resumeRequest);
6488
+ await deps.services.wakePausedTurn(pausedTurn);
6486
6489
  } catch (error) {
6487
6490
  logException(error, "agent.continue.schedule.failed", {
6488
- "app.ai.resume_session_version": resumeRequest.expectedVersion,
6489
- "app.ai.resume_session_id": resumeRequest.sessionId,
6491
+ "app.ai.resume_session_version": pausedTurn.expectedVersion,
6492
+ "app.ai.resume_session_id": pausedTurn.turnId,
6490
6493
  ...messageTs ? { "messaging.message.id": messageTs } : {}
6491
6494
  });
6492
6495
  throw error;
@@ -6498,15 +6501,15 @@ function createReplyToThread(deps) {
6498
6501
  await options.ack?.();
6499
6502
  return;
6500
6503
  }
6501
- const sessionRecord = await getAgentTurnSessionRecord(
6504
+ const sessionRecord = await getTurnRecord(
6502
6505
  conversationId,
6503
6506
  activeTurnId
6504
6507
  );
6505
- if (sessionRecord?.state === "awaiting_resume") {
6508
+ if (sessionRecord?.state === "paused") {
6506
6509
  if (sessionRecord.resumeReason === "auth") {
6507
- await abandonAgentTurnSessionRecord({
6510
+ await abandonTurnRecord({
6508
6511
  conversationId,
6509
- sessionId: activeTurnId,
6512
+ turnId: activeTurnId,
6510
6513
  errorMessage: "Auth-parked session superseded by a new user message"
6511
6514
  });
6512
6515
  markTurnClosed({
@@ -6516,11 +6519,11 @@ function createReplyToThread(deps) {
6516
6519
  });
6517
6520
  activeTurnId = void 0;
6518
6521
  } else {
6519
- await failAgentTurnSessionRecord({
6522
+ await failTurnRecord({
6520
6523
  conversationId,
6521
6524
  expectedVersion: sessionRecord.version,
6522
- sessionId: activeTurnId,
6523
- errorMessage: "Awaiting agent continuation metadata could not be materialized"
6525
+ turnId: activeTurnId,
6526
+ errorMessage: "Awaiting paused-turn metadata could not be materialized"
6524
6527
  });
6525
6528
  markTurnFailed({
6526
6529
  conversation: preparedState.conversation,
@@ -6590,10 +6593,10 @@ function createReplyToThread(deps) {
6590
6593
  }
6591
6594
  if (conversationId) {
6592
6595
  const turnStartedAtMs = message.metadata.dateSent.getTime();
6593
- void recordAgentTurnSessionSummary({
6596
+ void recordTurnSummary({
6594
6597
  channelName,
6595
6598
  conversationId,
6596
- sessionId: turnId,
6599
+ turnId,
6597
6600
  sliceId: 1,
6598
6601
  startedAtMs: turnStartedAtMs,
6599
6602
  state: "running",
@@ -6669,7 +6672,7 @@ function createReplyToThread(deps) {
6669
6672
  if (!dispatchId) {
6670
6673
  return;
6671
6674
  }
6672
- await recordAgentTurnSessionSummary({
6675
+ await recordTurnSummary({
6673
6676
  channelName,
6674
6677
  conversationId,
6675
6678
  destination,
@@ -6677,7 +6680,7 @@ function createReplyToThread(deps) {
6677
6680
  dispatchId,
6678
6681
  dispatchOutcome,
6679
6682
  ...acceptedDeliveryId ? { resultMessageId: acceptedDeliveryId } : {},
6680
- sessionId: turnId,
6683
+ turnId,
6681
6684
  sliceId: 1,
6682
6685
  source,
6683
6686
  startedAtMs: message.metadata.dateSent.getTime(),
@@ -6687,7 +6690,7 @@ function createReplyToThread(deps) {
6687
6690
  };
6688
6691
  let latestArtifacts = preparedState.artifacts;
6689
6692
  let assistantTitleArtifacts = {};
6690
- let agentContinueScheduleError;
6693
+ let turnWakeError;
6691
6694
  let boundaryFailureCode = "agent_run_failed";
6692
6695
  let finalizedFailureEventId;
6693
6696
  let terminalDispatchFailureOutcome;
@@ -6789,14 +6792,14 @@ function createReplyToThread(deps) {
6789
6792
  if (slackTs && options.execution?.dispatch?.id) {
6790
6793
  try {
6791
6794
  await persistWithRetry(
6792
- () => recordAgentTurnSessionSummary({
6795
+ () => recordTurnSummary({
6793
6796
  channelName,
6794
6797
  conversationId,
6795
6798
  destination,
6796
6799
  destinationVisibility,
6797
6800
  dispatchId: options.execution?.dispatch?.id,
6798
6801
  resultMessageId: slackTs,
6799
- sessionId: turnId,
6802
+ turnId,
6800
6803
  sliceId: 1,
6801
6804
  source,
6802
6805
  startedAtMs: message.metadata.dateSent.getTime(),
@@ -7063,14 +7066,14 @@ function createReplyToThread(deps) {
7063
7066
  }
7064
7067
  if (!destination || !conversationId) {
7065
7068
  throw new Error(
7066
- "Agent continuation requires a destination and conversation id"
7069
+ "Paused turn requires a destination and conversation id"
7067
7070
  );
7068
7071
  }
7069
7072
  try {
7070
- await deps.services.scheduleAgentContinue({
7073
+ await deps.services.wakePausedTurn({
7071
7074
  conversationId,
7072
7075
  destination,
7073
- sessionId: turnId,
7076
+ turnId,
7074
7077
  expectedVersion: outcome.resumeVersion
7075
7078
  });
7076
7079
  shouldPersistFailureState = false;
@@ -7080,7 +7083,7 @@ function createReplyToThread(deps) {
7080
7083
  "app.ai.resume_session_version": outcome.resumeVersion
7081
7084
  });
7082
7085
  shouldPersistFailureState = true;
7083
- agentContinueScheduleError = scheduleError;
7086
+ turnWakeError = scheduleError;
7084
7087
  throw scheduleError;
7085
7088
  }
7086
7089
  return;
@@ -7122,16 +7125,17 @@ function createReplyToThread(deps) {
7122
7125
  }
7123
7126
  try {
7124
7127
  if (conversationId && reply.piMessages?.length) {
7125
- await completeDeliveredTurn({
7128
+ await saveTurnCheckpoint({
7129
+ mode: "completed",
7126
7130
  channelName,
7127
7131
  conversationId,
7132
+ turnId,
7128
7133
  durationMs: reply.diagnostics.durationMs,
7129
7134
  usage: reply.diagnostics.usage,
7130
7135
  reasoningLevel: reply.diagnostics.reasoningLevel,
7131
7136
  destination,
7132
7137
  destinationVisibility,
7133
7138
  source,
7134
- sessionId: turnId,
7135
7139
  sliceId: 1,
7136
7140
  dispatchOutcome: reply.diagnostics.outcome === "success" ? "completed" : "failed",
7137
7141
  ...options.execution?.dispatch && turnResult.errorMessage ? { errorMessage: turnResult.errorMessage } : {},
@@ -7143,12 +7147,12 @@ function createReplyToThread(deps) {
7143
7147
  dispatchId: options.execution?.dispatch?.id
7144
7148
  });
7145
7149
  } else if (conversationId) {
7146
- await recordAgentTurnSessionSummary({
7150
+ await recordTurnSummary({
7147
7151
  channelName,
7148
7152
  conversationId,
7149
7153
  cumulativeDurationMs: reply.diagnostics.durationMs,
7150
7154
  cumulativeUsage: reply.diagnostics.usage,
7151
- sessionId: turnId,
7155
+ turnId,
7152
7156
  sliceId: 1,
7153
7157
  startedAtMs: message.metadata.dateSent.getTime(),
7154
7158
  state: "completed",
@@ -7262,7 +7266,7 @@ function createReplyToThread(deps) {
7262
7266
  shouldPersistFailureState = false;
7263
7267
  throw error;
7264
7268
  }
7265
- if (error === agentContinueScheduleError) {
7269
+ if (error === turnWakeError) {
7266
7270
  shouldPersistFailureState = true;
7267
7271
  }
7268
7272
  shouldPersistFailureState = true;
@@ -7285,15 +7289,12 @@ function createReplyToThread(deps) {
7285
7289
  const recoveryText = buildCanvasRecoveryReply(createdCanvasUrl);
7286
7290
  await deliverAssistantMessage(recoveryText, dispatchOutcome);
7287
7291
  if (conversationId) {
7288
- const sessionRecord = await getAgentTurnSessionRecord(
7289
- conversationId,
7290
- turnId
7291
- );
7292
+ const sessionRecord = await getTurnRecord(conversationId, turnId);
7292
7293
  if (sessionRecord) {
7293
- await failAgentTurnSessionRecord({
7294
+ await failTurnRecord({
7294
7295
  conversationId,
7295
7296
  expectedVersion: sessionRecord.version,
7296
- sessionId: turnId,
7297
+ turnId,
7297
7298
  errorMessage
7298
7299
  });
7299
7300
  }
@@ -7343,10 +7344,10 @@ function createReplyToThread(deps) {
7343
7344
  });
7344
7345
  if (conversationId) {
7345
7346
  try {
7346
- await recordAgentTurnSessionSummary({
7347
+ await recordTurnSummary({
7347
7348
  channelName,
7348
7349
  conversationId,
7349
- sessionId: turnId,
7350
+ turnId,
7350
7351
  sliceId: 1,
7351
7352
  startedAtMs: message.metadata.dateSent.getTime(),
7352
7353
  state: "failed",
@@ -7361,15 +7362,15 @@ function createReplyToThread(deps) {
7361
7362
  } : {},
7362
7363
  traceId: getActiveTraceId()
7363
7364
  });
7364
- const sessionRecord = await getAgentTurnSessionRecord(
7365
+ const sessionRecord = await getTurnRecord(
7365
7366
  conversationId,
7366
7367
  turnId
7367
7368
  );
7368
7369
  if (sessionRecord) {
7369
- await failAgentTurnSessionRecord({
7370
+ await failTurnRecord({
7370
7371
  conversationId,
7371
7372
  expectedVersion: sessionRecord.version,
7372
- sessionId: turnId,
7373
+ turnId,
7373
7374
  errorMessage: "Agent turn failed before assistant output handling completed"
7374
7375
  });
7375
7376
  }
@@ -7871,39 +7872,33 @@ function createJuniorSlackAdapter(config) {
7871
7872
  return createSlackAdapter(config);
7872
7873
  }
7873
7874
 
7874
- // src/chat/runtime/agent-continue-runner.ts
7875
- var AGENT_CONTINUE_LOCK_RETRY_DELAYS_MS = [250, 1e3, 2e3];
7875
+ // src/chat/task-execution/paused-turn.ts
7876
7876
  async function persistCompletedReplyState(args) {
7877
- const currentState = await getPersistedThreadState(
7878
- args.sessionRecord.conversationId
7879
- );
7877
+ const currentState = await getPersistedThreadState(args.turn.conversationId);
7880
7878
  const conversation = coerceThreadConversationState(currentState);
7881
7879
  await hydrateConversationMessages({
7882
7880
  conversation,
7883
- conversationId: args.sessionRecord.conversationId
7881
+ conversationId: args.turn.conversationId
7884
7882
  });
7885
7883
  const artifacts = coerceThreadArtifactsState(currentState);
7886
- const userMessage = getTurnUserMessage(
7887
- conversation,
7888
- args.sessionRecord.sessionId
7889
- );
7884
+ const userMessage = getTurnUserMessage(conversation, args.turn.turnId);
7890
7885
  const statePatch = buildDeliveredTurnStatePatch({
7891
7886
  artifacts,
7892
7887
  conversation,
7893
7888
  reply: args.reply,
7894
- sessionId: args.sessionRecord.sessionId,
7889
+ sessionId: args.turn.turnId,
7895
7890
  userMessageId: userMessage?.id
7896
7891
  });
7897
- await persistThreadStateById(args.sessionRecord.conversationId, {
7892
+ await persistThreadStateById(args.turn.conversationId, {
7898
7893
  ...statePatch
7899
7894
  });
7900
7895
  }
7901
- async function failSessionRecordBestEffort(args) {
7896
+ async function failTurnBestEffort(args) {
7902
7897
  try {
7903
- await failAgentTurnSessionRecord({
7904
- conversationId: args.sessionRecord.conversationId,
7905
- expectedVersion: args.sessionRecord.version,
7906
- sessionId: args.sessionRecord.sessionId,
7898
+ await failTurnRecord({
7899
+ conversationId: args.turn.conversationId,
7900
+ expectedVersion: args.turn.version,
7901
+ turnId: args.turn.turnId,
7907
7902
  errorMessage: args.errorMessage
7908
7903
  });
7909
7904
  } catch (error) {
@@ -7911,51 +7906,49 @@ async function failSessionRecordBestEffort(args) {
7911
7906
  error,
7912
7907
  "agent.continue.session_record.failure_persistence.failed",
7913
7908
  {
7914
- "app.ai.conversation_id": args.sessionRecord.conversationId,
7915
- "app.ai.session_id": args.sessionRecord.sessionId
7909
+ "app.ai.conversation_id": args.turn.conversationId,
7910
+ "app.ai.session_id": args.turn.turnId
7916
7911
  }
7917
7912
  );
7918
7913
  }
7919
7914
  }
7920
- async function persistFailedReplyState(sessionRecord, errorMessage = "Paused agent run failed while continuing") {
7921
- const currentState = await getPersistedThreadState(
7922
- sessionRecord.conversationId
7923
- );
7915
+ async function persistFailedReplyState(turn, errorMessage = "Paused agent run failed while continuing") {
7916
+ const currentState = await getPersistedThreadState(turn.conversationId);
7924
7917
  const conversation = coerceThreadConversationState(currentState);
7925
7918
  await hydrateConversationMessages({
7926
7919
  conversation,
7927
- conversationId: sessionRecord.conversationId
7920
+ conversationId: turn.conversationId
7928
7921
  });
7929
- clearPendingAuth(conversation, sessionRecord.sessionId);
7922
+ clearPendingAuth(conversation, turn.turnId);
7930
7923
  markTurnFailed({
7931
7924
  conversation,
7932
7925
  nowMs: Date.now(),
7933
- sessionId: sessionRecord.sessionId,
7934
- userMessageId: getTurnUserMessage(conversation, sessionRecord.sessionId)?.id,
7926
+ sessionId: turn.turnId,
7927
+ userMessageId: getTurnUserMessage(conversation, turn.turnId)?.id,
7935
7928
  markConversationMessage
7936
7929
  });
7937
- await failSessionRecordBestEffort({
7938
- sessionRecord,
7930
+ await failTurnBestEffort({
7931
+ turn,
7939
7932
  errorMessage
7940
7933
  });
7941
- await persistThreadStateById(sessionRecord.conversationId, {
7934
+ await persistThreadStateById(turn.conversationId, {
7942
7935
  conversation
7943
7936
  });
7944
7937
  }
7945
- async function failContinuationStartup(args) {
7938
+ async function failPausedTurnStart(args) {
7946
7939
  try {
7947
- await persistFailedReplyState(args.sessionRecord, args.errorMessage);
7940
+ await persistFailedReplyState(args.turn, args.errorMessage);
7948
7941
  } catch (persistError) {
7949
- await failSessionRecordBestEffort({
7950
- sessionRecord: args.sessionRecord,
7951
- errorMessage: "Paused agent run failed while preparing continuation"
7942
+ await failTurnBestEffort({
7943
+ turn: args.turn,
7944
+ errorMessage: "Paused turn failed before it could run"
7952
7945
  });
7953
7946
  logException(
7954
7947
  persistError,
7955
7948
  "agent.continue.startup_failure_persist.failed",
7956
7949
  {
7957
- "app.ai.conversation_id": args.sessionRecord.conversationId,
7958
- "app.ai.session_id": args.sessionRecord.sessionId
7950
+ "app.ai.conversation_id": args.turn.conversationId,
7951
+ "app.ai.session_id": args.turn.turnId
7959
7952
  }
7960
7953
  );
7961
7954
  }
@@ -8012,74 +8005,78 @@ async function resolveResumeExecutionIdentity(args) {
8012
8005
  credentialContext: credentialContextForActor(actor)
8013
8006
  };
8014
8007
  }
8015
- function isContinuationResume(summary) {
8016
- return summary.state === "awaiting_resume" && (summary.resumeReason === "timeout" || summary.resumeReason === "yield" || summary.resumeReason === "retry");
8008
+ function isPausedTurn(summary) {
8009
+ return summary.state === "paused" && (summary.resumeReason === "timeout" || summary.resumeReason === "yield" || summary.resumeReason === "retry");
8017
8010
  }
8018
- async function failUnresumableContinuation(args) {
8019
- await failAgentTurnSessionRecord({
8011
+ async function failPausedTurn(args) {
8012
+ const failed = await failTurnRecord({
8020
8013
  conversationId: args.conversationId,
8021
8014
  expectedVersion: args.expectedVersion ?? args.summary.version,
8022
- sessionId: args.summary.sessionId,
8015
+ turnId: args.summary.turnId,
8023
8016
  errorMessage: args.errorMessage
8024
8017
  });
8025
- if (args.summary.dispatchId) {
8018
+ if (!failed) return;
8019
+ if (failed.dispatchId) {
8026
8020
  try {
8027
8021
  const routing = await resolveTurnSessionRouting({
8028
8022
  conversationId: args.conversationId
8029
8023
  });
8030
- await recordAgentTurnSessionSummary({
8024
+ await recordTurnSummary({
8031
8025
  conversationId: args.conversationId,
8032
8026
  destination: routing.destination,
8033
- dispatchId: args.summary.dispatchId,
8027
+ dispatchId: failed.dispatchId,
8034
8028
  dispatchOutcome: "failed",
8035
- sessionId: args.summary.sessionId,
8036
- sliceId: args.summary.sliceId,
8029
+ turnId: failed.turnId,
8030
+ sliceId: failed.sliceId,
8037
8031
  source: routing.source,
8038
8032
  state: "failed",
8039
- surface: args.summary.surface
8033
+ surface: failed.surface
8040
8034
  });
8041
8035
  } catch (error) {
8042
8036
  logException(error, "agent.continue.dispatch_failure_summary.failed", {
8043
8037
  "app.ai.conversation_id": args.conversationId,
8044
- "app.ai.session_id": args.summary.sessionId
8038
+ "app.ai.session_id": args.summary.turnId
8045
8039
  });
8046
8040
  }
8047
8041
  }
8048
8042
  }
8049
- async function continueSlackAgentRun(payload, options, runOptions = {}) {
8043
+ async function runPausedTurn(payload, options, runOptions = {}) {
8050
8044
  return withLogContext(
8051
8045
  { conversationId: payload.conversationId },
8052
- () => continueSlackAgentRunInContext(payload, options, runOptions)
8046
+ () => runPausedTurnInContext(payload, options, runOptions)
8053
8047
  );
8054
8048
  }
8055
- async function continueSlackAgentRunInContext(payload, options, runOptions) {
8049
+ async function runPausedTurnInContext(payload, options, runOptions) {
8056
8050
  const thread = parseSlackThreadId(payload.conversationId);
8057
8051
  const destination = requireSlackDestination(
8058
8052
  payload.destination,
8059
- "Agent continuation"
8053
+ "Paused turn"
8060
8054
  );
8061
- const scheduleAgentContinue2 = options.scheduleAgentContinue ?? scheduleAgentContinue;
8055
+ const wakePausedTurn2 = options.wakePausedTurn ?? wakePausedTurn;
8062
8056
  const resumeTurn = options.resumeTurn ?? resumeSlackTurn;
8063
8057
  return await resumeTurn({
8064
8058
  messageText: "",
8065
8059
  conversationId: payload.conversationId,
8066
- turnId: payload.sessionId,
8060
+ turnId: payload.turnId,
8067
8061
  channelId: thread?.channelId ?? destination.channelId,
8068
8062
  ...thread?.threadTs ? { threadTs: thread.threadTs } : {},
8069
8063
  lockKey: payload.conversationId,
8064
+ // Queue continue runs under the conversation work lease already.
8065
+ ownsConversationLease: true,
8070
8066
  agentRunner: options.agentRunner,
8071
8067
  scheduleSessionCompletedPluginTasks: options.scheduleSessionCompletedPluginTasks,
8072
8068
  beforeStart: async () => {
8073
- let sessionRecord;
8069
+ let turn;
8074
8070
  try {
8075
- sessionRecord = await getAgentTurnSessionRecord(
8076
- payload.conversationId,
8077
- payload.sessionId
8078
- );
8079
- if (!sessionRecord || sessionRecord.state !== "awaiting_resume" || sessionRecord.resumeReason !== "timeout" && sessionRecord.resumeReason !== "yield" && sessionRecord.resumeReason !== "retry" || sessionRecord.version !== payload.expectedVersion) {
8071
+ const checkpoint = await loadTurnCheckpoint({
8072
+ conversationId: payload.conversationId,
8073
+ turnId: payload.turnId
8074
+ });
8075
+ turn = checkpoint.record;
8076
+ if (!turn || turn.state !== "paused" || turn.resumeReason !== "timeout" && turn.resumeReason !== "yield" && turn.resumeReason !== "retry" || turn.version !== payload.expectedVersion) {
8080
8077
  return false;
8081
8078
  }
8082
- const activeSessionRecord = sessionRecord;
8079
+ const activeTurn = turn;
8083
8080
  const currentState = await getPersistedThreadState(
8084
8081
  payload.conversationId
8085
8082
  );
@@ -8089,20 +8086,20 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8089
8086
  conversationId: payload.conversationId
8090
8087
  });
8091
8088
  const artifacts = coerceThreadArtifactsState(currentState);
8092
- const dispatchId = activeSessionRecord.dispatchId ?? options.routingContext?.dispatch?.id;
8089
+ const dispatchId = activeTurn.dispatchId ?? options.routingContext?.dispatch?.id;
8093
8090
  const dispatchUserMessage = dispatchId ? conversation.messages.find(
8094
8091
  (message) => message.role === "user" && options.inputMessageIds?.includes(message.id)
8095
8092
  ) : void 0;
8096
- const userMessage = getTurnUserMessage(conversation, payload.sessionId) ?? dispatchUserMessage;
8093
+ const userMessage = getTurnUserMessage(conversation, payload.turnId) ?? dispatchUserMessage;
8097
8094
  if (!userMessage) {
8098
- await failStrandedSessionWithFallback({
8095
+ await failStrandedTurnWithFallback({
8099
8096
  conversationId: payload.conversationId,
8100
- errorMessage: `Unable to locate the persisted user message for agent continuation session "${payload.sessionId}"`,
8101
- sessionRecord: activeSessionRecord
8097
+ errorMessage: `Unable to locate the persisted user message for paused turn "${payload.turnId}"`,
8098
+ turn: activeTurn
8102
8099
  });
8103
8100
  return false;
8104
8101
  }
8105
- if (conversation.processing.activeTurnId !== payload.sessionId) {
8102
+ if (conversation.processing.activeTurnId !== payload.turnId) {
8106
8103
  return false;
8107
8104
  }
8108
8105
  const identity = await resolveResumeExecutionIdentity({
@@ -8112,10 +8109,10 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8112
8109
  userMessage
8113
8110
  });
8114
8111
  if (!identity) {
8115
- await failStrandedSessionWithFallback({
8112
+ await failStrandedTurnWithFallback({
8116
8113
  conversationId: payload.conversationId,
8117
- errorMessage: "Unable to rebuild Slack actor for continuation",
8118
- sessionRecord: activeSessionRecord
8114
+ errorMessage: "Unable to rebuild the Slack actor for the paused turn",
8115
+ turn: activeTurn
8119
8116
  });
8120
8117
  return false;
8121
8118
  }
@@ -8132,22 +8129,20 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8132
8129
  });
8133
8130
  const source = routing.source;
8134
8131
  const routingDestination = routing.destination;
8135
- const turnMessages = activeSessionRecord.turnStartMessageIndex === void 0 ? [] : activeSessionRecord.piMessages.slice(
8136
- activeSessionRecord.turnStartMessageIndex
8137
- );
8132
+ const turnMessages = activeTurn.turnStartMessageIndex === void 0 ? [] : activeTurn.piMessages.slice(activeTurn.turnStartMessageIndex);
8138
8133
  const recordDispatchOutcome = async (dispatchOutcome) => {
8139
8134
  const dispatchId2 = options.routingContext?.dispatch?.id;
8140
8135
  if (!dispatchId2) {
8141
8136
  return;
8142
8137
  }
8143
- await recordAgentTurnSessionSummary({
8138
+ await recordTurnSummary({
8144
8139
  conversationId: payload.conversationId,
8145
8140
  destination: routingDestination,
8146
8141
  destinationVisibility: options.routingContext?.destinationVisibility,
8147
8142
  dispatchId: dispatchId2,
8148
8143
  dispatchOutcome,
8149
- sessionId: payload.sessionId,
8150
- sliceId: activeSessionRecord.sliceId,
8144
+ turnId: payload.turnId,
8145
+ sliceId: activeTurn.sliceId,
8151
8146
  source,
8152
8147
  state: "failed",
8153
8148
  surface: options.routingContext?.surface ?? "slack"
@@ -8155,7 +8150,7 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8155
8150
  };
8156
8151
  return {
8157
8152
  messageText: userMessage.text,
8158
- sliceId: activeSessionRecord.sliceId,
8153
+ sliceId: activeTurn.sliceId,
8159
8154
  messageTs: getTurnUserSlackMessageTs(userMessage),
8160
8155
  inputMessageIds: [userMessage.id],
8161
8156
  initialStatus: latestReportedProgress(turnMessages),
@@ -8166,7 +8161,7 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8166
8161
  // exact dispatch session so unrelated conversation input cannot
8167
8162
  // gain system authority. Interactive turns retain their merged
8168
8163
  // projection so queued steering remains visible.
8169
- piMessages: dispatchId ? activeSessionRecord.piMessages : await loadProjection({
8164
+ piMessages: dispatchId ? activeTurn.piMessages : await loadProjection({
8170
8165
  conversationId: payload.conversationId
8171
8166
  }),
8172
8167
  ...getTurnUserReplyAttachmentContext(userMessage)
@@ -8199,51 +8194,51 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8199
8194
  },
8200
8195
  commitResult: async (reply) => {
8201
8196
  await persistCompletedReplyState({
8202
- sessionRecord: activeSessionRecord,
8197
+ turn: activeTurn,
8203
8198
  reply
8204
8199
  });
8205
8200
  },
8206
8201
  onFailure: async (error) => {
8207
8202
  await persistFailedReplyState(
8208
- activeSessionRecord,
8203
+ activeTurn,
8209
8204
  error instanceof Error ? error.message : String(error)
8210
8205
  );
8211
8206
  await recordDispatchOutcome("failed");
8212
8207
  },
8213
8208
  onPostDeliveryCommitFailure: async () => {
8214
- await failAgentTurnSessionRecord({
8215
- conversationId: activeSessionRecord.conversationId,
8216
- expectedVersion: activeSessionRecord.version,
8217
- sessionId: activeSessionRecord.sessionId,
8209
+ await failTurnRecord({
8210
+ conversationId: activeTurn.conversationId,
8211
+ expectedVersion: activeTurn.version,
8212
+ turnId: activeTurn.turnId,
8218
8213
  errorMessage: "Continued agent reply was delivered but completion state did not persist"
8219
8214
  });
8220
8215
  await recordDispatchOutcome("failed");
8221
8216
  },
8222
8217
  onAuthPause: async () => {
8223
8218
  await persistAuthPauseTurnState({
8224
- sessionId: payload.sessionId,
8219
+ sessionId: payload.turnId,
8225
8220
  threadStateId: payload.conversationId
8226
8221
  });
8227
8222
  await recordDispatchOutcome("blocked");
8228
8223
  logWarn("agent.continue.reparked_for_auth", {
8229
8224
  "app.ai.conversation_id": payload.conversationId,
8230
- "app.ai.session_id": payload.sessionId
8225
+ "app.ai.session_id": payload.turnId
8231
8226
  });
8232
8227
  },
8233
8228
  onSuspend: async (resumeVersion) => {
8234
- await scheduleAgentContinue2({
8229
+ await wakePausedTurn2({
8235
8230
  conversationId: payload.conversationId,
8236
8231
  destination: payload.destination,
8237
- sessionId: payload.sessionId,
8232
+ turnId: payload.turnId,
8238
8233
  expectedVersion: resumeVersion
8239
8234
  });
8240
8235
  }
8241
8236
  };
8242
8237
  } catch (error) {
8243
- if (sessionRecord) {
8244
- await failContinuationStartup({
8238
+ if (turn) {
8239
+ await failPausedTurnStart({
8245
8240
  errorMessage: error instanceof Error ? error.message : String(error),
8246
- sessionRecord
8241
+ turn
8247
8242
  });
8248
8243
  }
8249
8244
  throw error;
@@ -8251,13 +8246,14 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
8251
8246
  }
8252
8247
  });
8253
8248
  }
8254
- async function failStrandedSessionWithFallback(args) {
8255
- await failAgentTurnSessionRecord({
8249
+ async function failStrandedTurnWithFallback(args) {
8250
+ const failed = await failTurnRecord({
8256
8251
  conversationId: args.conversationId,
8257
- expectedVersion: args.sessionRecord.version,
8258
- sessionId: args.sessionRecord.sessionId,
8252
+ expectedVersion: args.turn.version,
8253
+ turnId: args.turn.turnId,
8259
8254
  errorMessage: args.errorMessage
8260
8255
  });
8256
+ if (!failed) return false;
8261
8257
  const currentState = await getPersistedThreadState(args.conversationId);
8262
8258
  const conversation = coerceThreadConversationState(currentState);
8263
8259
  await hydrateConversationMessages({
@@ -8267,18 +8263,15 @@ async function failStrandedSessionWithFallback(args) {
8267
8263
  markTurnFailed({
8268
8264
  conversation,
8269
8265
  nowMs: Date.now(),
8270
- sessionId: args.sessionRecord.sessionId,
8271
- userMessageId: getTurnUserMessage(
8272
- conversation,
8273
- args.sessionRecord.sessionId
8274
- )?.id,
8266
+ sessionId: failed.turnId,
8267
+ userMessageId: getTurnUserMessage(conversation, failed.turnId)?.id,
8275
8268
  markConversationMessage
8276
8269
  });
8277
8270
  await persistThreadStateById(args.conversationId, { conversation });
8278
8271
  const eventName = "agent.turn.stranded_session.failed";
8279
8272
  const eventId = logException(new Error(args.errorMessage), eventName, {
8280
8273
  "app.ai.conversation_id": args.conversationId,
8281
- "app.ai.session_id": args.sessionRecord.sessionId
8274
+ "app.ai.session_id": failed.turnId
8282
8275
  });
8283
8276
  let routing;
8284
8277
  try {
@@ -8288,25 +8281,25 @@ async function failStrandedSessionWithFallback(args) {
8288
8281
  } catch (error) {
8289
8282
  logException(error, "agent.turn.stranded_session.routing_unavailable", {
8290
8283
  "app.ai.conversation_id": args.conversationId,
8291
- "app.ai.session_id": args.sessionRecord.sessionId
8284
+ "app.ai.session_id": failed.turnId
8292
8285
  });
8293
- return;
8286
+ return true;
8294
8287
  }
8295
- if (args.sessionRecord.dispatchId) {
8296
- await recordAgentTurnSessionSummary({
8288
+ if (failed.dispatchId) {
8289
+ await recordTurnSummary({
8297
8290
  conversationId: args.conversationId,
8298
8291
  destination: routing.destination,
8299
- dispatchId: args.sessionRecord.dispatchId,
8292
+ dispatchId: failed.dispatchId,
8300
8293
  dispatchOutcome: "failed",
8301
- sessionId: args.sessionRecord.sessionId,
8302
- sliceId: args.sessionRecord.sliceId,
8294
+ turnId: failed.turnId,
8295
+ sliceId: failed.sliceId,
8303
8296
  source: routing.source,
8304
8297
  state: "failed",
8305
- surface: args.sessionRecord.surface
8298
+ surface: failed.surface
8306
8299
  });
8307
8300
  }
8308
8301
  const thread = parseSlackThreadId(args.conversationId);
8309
- const channelId = thread?.channelId ?? requireSlackDestination(routing.destination, "Stranded agent continuation").channelId;
8302
+ const channelId = thread?.channelId ?? requireSlackDestination(routing.destination, "Stranded paused turn").channelId;
8310
8303
  await postSlackMessage({
8311
8304
  channelId,
8312
8305
  ...thread?.threadTs ? { threadTs: thread.threadTs } : {},
@@ -8314,173 +8307,154 @@ async function failStrandedSessionWithFallback(args) {
8314
8307
  requireTurnFailureEventId(eventId, eventName)
8315
8308
  )
8316
8309
  });
8310
+ return true;
8317
8311
  }
8318
- async function recoverStrandedRunningSession(args) {
8319
- const stateAdapter = getStateAdapter();
8320
- await stateAdapter.connect();
8321
- const probe = await acquireActiveLock(stateAdapter, args.conversationId);
8322
- if (!probe) {
8323
- return false;
8324
- }
8325
- await stateAdapter.releaseLock(probe);
8326
- const sessionRecord = await getAgentTurnSessionRecordForResume(
8327
- args.conversationId,
8328
- args.summary.sessionId
8329
- );
8330
- if (!sessionRecord || sessionRecord.state !== "running") {
8331
- return false;
8332
- }
8333
- const recoveryProjection = await loadConversationProjection({
8334
- conversationId: args.conversationId
8335
- });
8336
- const modelProfile = recoveryProjection.modelProfile;
8337
- const modelId = modelIdForProfile(botConfig, modelProfile);
8338
- let routing;
8339
- try {
8340
- routing = await resolveTurnSessionRouting({
8341
- conversationId: args.conversationId
8342
- });
8343
- } catch (error) {
8344
- await failStrandedSessionWithFallback({
8345
- conversationId: args.conversationId,
8346
- errorMessage: error instanceof Error ? error.message : String(error),
8347
- sessionRecord
8348
- });
8349
- return false;
8350
- }
8351
- const parked = await persistYieldSessionRecord({
8352
- channelName: sessionRecord.channelName,
8353
- conversationId: args.conversationId,
8354
- sessionId: sessionRecord.sessionId,
8355
- currentSliceId: sessionRecord.sliceId,
8356
- destination: routing.destination,
8357
- source: routing.source,
8358
- messages: sessionRecord.piMessages,
8359
- errorMessage: "Recovered running session after hard worker death",
8360
- modelId,
8361
- surface: sessionRecord.surface
8362
- });
8363
- if (!parked) {
8364
- await failStrandedSessionWithFallback({
8365
- conversationId: args.conversationId,
8366
- errorMessage: "Stranded running session had no resumable boundary after worker death",
8367
- sessionRecord
8368
- });
8369
- return false;
8370
- }
8371
- const request = await getAwaitingAgentContinueRequest({
8372
- conversationId: args.conversationId,
8373
- sessionId: sessionRecord.sessionId
8374
- });
8375
- if (!request) {
8376
- await failStrandedSessionWithFallback({
8377
- conversationId: args.conversationId,
8378
- errorMessage: "Stranded running session could not materialize continuation metadata",
8379
- sessionRecord: parked
8380
- });
8381
- return false;
8382
- }
8383
- if (await continueSlackAgentRunWithLockRetry(
8384
- request,
8385
- args.options,
8386
- args.runOptions
8387
- )) {
8388
- return true;
8389
- }
8390
- await failUnresumableContinuation({
8391
- conversationId: args.conversationId,
8392
- expectedVersion: request.expectedVersion,
8393
- summary: args.summary,
8394
- errorMessage: "Awaiting agent continuation was stale before it could run"
8395
- });
8396
- return false;
8397
- }
8398
- async function resumeAwaitingSlackContinuation(conversationId, options, runOptions = {}) {
8312
+ async function runNextPausedTurn(conversationId, options, runOptions = {}) {
8399
8313
  return withLogContext(
8400
8314
  { conversationId },
8401
- () => resumeAwaitingSlackContinuationInContext(
8402
- conversationId,
8403
- options,
8404
- runOptions
8405
- )
8315
+ () => runNextPausedTurnInContext(conversationId, options, runOptions)
8406
8316
  );
8407
8317
  }
8408
- async function resumeAwaitingSlackContinuationInContext(conversationId, options, runOptions) {
8409
- const summaries = await listAgentTurnSessionSummariesForConversation(conversationId);
8318
+ async function runNextPausedTurnInContext(conversationId, options, runOptions) {
8319
+ const summaries = await listTurnSummaries(conversationId);
8320
+ const persisted = await getPersistedThreadState(conversationId);
8321
+ const conversation = coerceThreadConversationState(persisted);
8322
+ await hydrateConversationMessages({ conversation, conversationId });
8410
8323
  const newest = summaries[0];
8411
- if (newest?.state === "running") {
8412
- return await recoverStrandedRunningSession({
8413
- conversationId,
8414
- options,
8415
- runOptions,
8416
- summary: newest
8324
+ const running = newest ? await getTurnRecord(conversationId, newest.turnId) : void 0;
8325
+ if (running?.state === "running") {
8326
+ if (turnHasReply(conversation, running.turnId)) {
8327
+ const acceptedReply = [...conversation.messages].reverse().find(
8328
+ (message) => message.role === "assistant" && message.id.startsWith(`${running.turnId}:assistant:`)
8329
+ );
8330
+ const completed = await completeTurnRecord({
8331
+ conversationId,
8332
+ expectedVersion: running.version,
8333
+ resultMessageId: acceptedReply?.meta?.slackTs,
8334
+ turnId: running.turnId
8335
+ });
8336
+ if (!completed) return false;
8337
+ markTurnCompleted({
8338
+ conversation,
8339
+ nowMs: Date.now(),
8340
+ sessionId: running.turnId
8341
+ });
8342
+ await persistThreadStateById(conversationId, { conversation });
8343
+ return false;
8344
+ }
8345
+ const state = getStateAdapter();
8346
+ await state.connect();
8347
+ await withActiveLock(state, conversationId, async () => {
8348
+ const record = await getTurnRecordForResume(
8349
+ conversationId,
8350
+ running.turnId
8351
+ );
8352
+ if (!record || record.state !== "running") return;
8353
+ await failStrandedTurnWithFallback({
8354
+ conversationId,
8355
+ errorMessage: "Turn lost its worker before reaching a safe boundary",
8356
+ turn: record
8357
+ });
8417
8358
  });
8359
+ return false;
8418
8360
  }
8419
8361
  for (const summary of summaries) {
8420
- if (!isContinuationResume(summary)) {
8362
+ if (!isPausedTurn(summary)) {
8421
8363
  continue;
8422
8364
  }
8423
- const request = await getAwaitingAgentContinueRequest({
8365
+ const request = await getPausedTurnRequest({
8424
8366
  conversationId,
8425
- sessionId: summary.sessionId
8367
+ turnId: summary.turnId
8426
8368
  });
8427
8369
  if (!request) {
8428
- await failUnresumableContinuation({
8370
+ await failPausedTurn({
8429
8371
  conversationId,
8430
8372
  summary,
8431
- errorMessage: "Awaiting agent continuation metadata could not be materialized"
8373
+ errorMessage: "Awaiting paused-turn metadata could not be materialized"
8432
8374
  });
8433
8375
  continue;
8434
8376
  }
8435
- if (await continueSlackAgentRunWithLockRetry(request, options, runOptions)) {
8377
+ if (await runPausedTurn(request, options, runOptions)) {
8436
8378
  return true;
8437
8379
  }
8438
- await failUnresumableContinuation({
8380
+ await failPausedTurn({
8439
8381
  conversationId,
8440
8382
  expectedVersion: request.expectedVersion,
8441
8383
  summary,
8442
- errorMessage: "Awaiting agent continuation was stale before it could run"
8384
+ errorMessage: "Awaiting paused turn was stale before it could run"
8443
8385
  });
8444
8386
  }
8445
8387
  return false;
8446
8388
  }
8447
- async function continueSlackAgentRunWithLockRetry(payload, options, runOptions = {}) {
8448
- return withLogContext(
8449
- { conversationId: payload.conversationId },
8450
- () => continueSlackAgentRunWithLockRetryInContext(payload, options, runOptions)
8451
- );
8452
- }
8453
- async function continueSlackAgentRunWithLockRetryInContext(payload, options, runOptions) {
8454
- const scheduleAgentContinue2 = options.scheduleAgentContinue ?? scheduleAgentContinue;
8455
- for (const [attempt, delayMs] of [
8456
- ...AGENT_CONTINUE_LOCK_RETRY_DELAYS_MS,
8457
- void 0
8458
- ].entries()) {
8459
- try {
8460
- return await continueSlackAgentRun(payload, options, runOptions);
8461
- } catch (error) {
8462
- if (!(error instanceof ResumeTurnBusyError)) {
8463
- throw error;
8464
- }
8465
- if (typeof delayMs !== "number") {
8466
- logWarn("agent.continue.lock.busy", {
8467
- "app.ai.conversation_id": payload.conversationId,
8468
- "app.ai.session_id": payload.sessionId,
8469
- "app.ai.resume_lock_retry_count": attempt
8470
- });
8471
- await scheduleAgentContinue2(payload);
8472
- return true;
8473
- }
8474
- logWarn("agent.continue.lock.retrying", {
8475
- "app.ai.conversation_id": payload.conversationId,
8476
- "app.ai.session_id": payload.sessionId,
8477
- "app.ai.resume_lock_retry_attempt": attempt + 1,
8478
- "app.ai.resume_lock_retry_delay_ms": delayMs
8479
- });
8480
- await sleep(delayMs);
8389
+
8390
+ // src/chat/app/conversation-work.ts
8391
+ function createConversationWork(options) {
8392
+ const services = {
8393
+ ...options.services,
8394
+ replyExecutor: {
8395
+ ...options.services?.replyExecutor,
8396
+ agentRunner: options.agentRunner,
8397
+ getPausedTurnRequest: options.services?.replyExecutor?.getPausedTurnRequest ?? (async (request) => await getPausedTurnRequest({
8398
+ ...request,
8399
+ conversationStore: options.conversationStore
8400
+ })),
8401
+ wakePausedTurn: options.services?.replyExecutor?.wakePausedTurn ?? (async (request) => await wakePausedTurn(request, {
8402
+ queue: options.queue,
8403
+ state: options.state
8404
+ }))
8481
8405
  }
8482
- }
8483
- return true;
8406
+ };
8407
+ const runtime = createSlackRuntime({
8408
+ getSlackAdapter: options.getSlackAdapter,
8409
+ services
8410
+ });
8411
+ const slackWorker = createSlackConversationWorker({
8412
+ getSlackAdapter: options.getSlackAdapter,
8413
+ conversationStore: options.conversationStore,
8414
+ runNextPausedTurn: async (conversationId, runOptions) => await runNextPausedTurn(
8415
+ conversationId,
8416
+ {
8417
+ agentRunner: options.agentRunner,
8418
+ scheduleSessionCompletedPluginTasks: services.replyExecutor?.scheduleSessionCompletedPluginTasks,
8419
+ wakePausedTurn: services.replyExecutor?.wakePausedTurn
8420
+ },
8421
+ runOptions
8422
+ ),
8423
+ runtime,
8424
+ state: options.state
8425
+ });
8426
+ const dispatchWorker = createAgentDispatchConversationWorker({
8427
+ resumeTurn: async (dispatch2, hooks) => {
8428
+ await runNextPausedTurn(
8429
+ getDispatchConversationId(dispatch2),
8430
+ {
8431
+ agentRunner: options.agentRunner,
8432
+ inputMessageIds: getDispatchInputMessageIds(dispatch2.id),
8433
+ routingContext: buildDispatchRoutingContext(dispatch2),
8434
+ scheduleSessionCompletedPluginTasks: services.replyExecutor?.scheduleSessionCompletedPluginTasks,
8435
+ wakePausedTurn: services.replyExecutor?.wakePausedTurn
8436
+ },
8437
+ { shouldYield: hooks.shouldYield }
8438
+ );
8439
+ },
8440
+ runTurn: runtime.runDispatchTurn
8441
+ });
8442
+ const providerWorker = createAgentDispatchWorkRouter({
8443
+ dispatchWorker,
8444
+ fallbackWorker: slackWorker
8445
+ });
8446
+ return {
8447
+ conversationStore: options.conversationStore,
8448
+ queue: options.queue,
8449
+ run: routeAgentInvocationWork({
8450
+ invocationWorker: createAgentInvocationWorker({
8451
+ agentRunner: options.agentRunner
8452
+ }),
8453
+ fallbackWorker: providerWorker
8454
+ }),
8455
+ runtime,
8456
+ state: options.state
8457
+ };
8484
8458
  }
8485
8459
 
8486
8460
  // src/chat/app/production.ts
@@ -8524,61 +8498,13 @@ function createProductionSlackWebhookServices(options) {
8524
8498
  }
8525
8499
  function createProductionConversationWorkOptions(options) {
8526
8500
  const conversationStore = getProductionConversationStore();
8527
- const { agentRunner } = options;
8528
- const services = {
8529
- ...options.services,
8530
- replyExecutor: {
8531
- ...options.services?.replyExecutor,
8532
- agentRunner
8533
- }
8534
- };
8535
- const runtime = createSlackRuntime({
8536
- getSlackAdapter: getProductionSlackAdapter,
8537
- services
8538
- });
8539
- const queue = getVercelConversationWorkQueue();
8540
- const slackWorker = createSlackConversationWorker({
8541
- getSlackAdapter: getProductionSlackAdapter,
8501
+ return createConversationWork({
8502
+ agentRunner: options.agentRunner,
8542
8503
  conversationStore,
8543
- resumeAwaitingContinuation: async (conversationId, runOptions) => await resumeAwaitingSlackContinuation(
8544
- conversationId,
8545
- {
8546
- agentRunner,
8547
- scheduleSessionCompletedPluginTasks: services.replyExecutor?.scheduleSessionCompletedPluginTasks
8548
- },
8549
- runOptions
8550
- ),
8551
- runtime
8552
- });
8553
- const dispatchWorker = createAgentDispatchConversationWorker({
8554
- resumeTurn: async (dispatch2, hooks) => {
8555
- await resumeAwaitingSlackContinuation(
8556
- getDispatchConversationId(dispatch2),
8557
- {
8558
- agentRunner,
8559
- inputMessageIds: getDispatchInputMessageIds(dispatch2.id),
8560
- routingContext: buildDispatchRoutingContext(dispatch2),
8561
- scheduleSessionCompletedPluginTasks: services.replyExecutor?.scheduleSessionCompletedPluginTasks
8562
- },
8563
- { shouldYield: hooks.shouldYield }
8564
- );
8565
- },
8566
- runTurn: runtime.runDispatchTurn
8567
- });
8568
- const providerWorker = createAgentDispatchWorkRouter({
8569
- dispatchWorker,
8570
- fallbackWorker: slackWorker
8504
+ getSlackAdapter: getProductionSlackAdapter,
8505
+ queue: getVercelConversationWorkQueue(),
8506
+ services: options.services
8571
8507
  });
8572
- return {
8573
- conversationStore,
8574
- queue,
8575
- run: routeAgentInvocationWork({
8576
- invocationWorker: createAgentInvocationWorker({
8577
- agentRunner
8578
- }),
8579
- fallbackWorker: providerWorker
8580
- })
8581
- };
8582
8508
  }
8583
8509
 
8584
8510
  // src/chat/resource-events/ingest.ts