@sentry/junior 0.187.0 → 0.189.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 (108) hide show
  1. package/dist/{agent-hooks-XVAE2554.js → agent-hooks-6QRYH6PX.js} +11 -11
  2. package/dist/api/acp/conversations.d.ts +2 -2
  3. package/dist/api/conversations/list.d.ts +7 -0
  4. package/dist/api/people/shared.d.ts +54 -0
  5. package/dist/api.js +41 -52
  6. package/dist/app.d.ts +1 -1
  7. package/dist/app.js +1001 -338
  8. package/dist/{catalog-runtime-DWFAC562.js → catalog-runtime-IETJLJFG.js} +4 -4
  9. package/dist/chat/agent/resume.d.ts +0 -2
  10. package/dist/chat/agent/types.d.ts +9 -14
  11. package/dist/chat/agent-dispatch/work.d.ts +1 -10
  12. package/dist/chat/agent-invocations/spawn.d.ts +1 -1
  13. package/dist/chat/agent-invocations/types.d.ts +296 -24
  14. package/dist/chat/app/conversation-work.d.ts +16 -8
  15. package/dist/chat/conversation-privacy.d.ts +7 -7
  16. package/dist/chat/conversations/destination.d.ts +12 -0
  17. package/dist/chat/conversations/location.d.ts +3 -8
  18. package/dist/chat/conversations/projection.d.ts +2 -2
  19. package/dist/chat/conversations/sql/location.d.ts +13 -4
  20. package/dist/chat/{api-turns → conversations}/stop.d.ts +2 -2
  21. package/dist/chat/conversations/store.d.ts +8 -11
  22. package/dist/chat/conversations/structured-events.d.ts +1 -1
  23. package/dist/chat/{api-turns/authorization.d.ts → conversations/web-authorization.d.ts} +1 -0
  24. package/dist/chat/conversations/web-input.d.ts +98 -0
  25. package/dist/chat/conversations/web-mailbox.d.ts +12 -0
  26. package/dist/chat/providers/slack/runtime.d.ts +1 -0
  27. package/dist/chat/providers/slack/system-turn.d.ts +8 -0
  28. package/dist/chat/resource-events/actor.d.ts +13 -12
  29. package/dist/chat/resource-events/notification.d.ts +1 -1
  30. package/dist/chat/services/guardian-action-policy.d.ts +1 -1
  31. package/dist/chat/services/turn-session-routing.d.ts +5 -5
  32. package/dist/chat/task-execution/assistant-message.d.ts +32 -0
  33. package/dist/chat/task-execution/conversation-turn.d.ts +8 -0
  34. package/dist/chat/{api-turns → task-execution}/mailbox-input.d.ts +1 -2
  35. package/dist/chat/task-execution/mailbox-turn.d.ts +42 -0
  36. package/dist/chat/task-execution/paused-turn.d.ts +1 -1
  37. package/dist/chat/task-execution/slack-work.d.ts +0 -2
  38. package/dist/{chunk-WL3R2KTS.js → chunk-4RHJ3CXR.js} +90 -289
  39. package/dist/{chunk-U6ZQHRIP.js → chunk-5CXCGDIL.js} +1 -1
  40. package/dist/{chunk-HXR3FHTE.js → chunk-5VWAY27R.js} +7 -3
  41. package/dist/{chunk-D3GDGREI.js → chunk-6AUR6PWR.js} +3 -3
  42. package/dist/{chunk-EIWYZXSM.js → chunk-7R5JRPCY.js} +8 -6
  43. package/dist/{chunk-WRDW3A3D.js → chunk-AC7MDOJW.js} +5 -7
  44. package/dist/{chunk-URZ7UD4P.js → chunk-BYBSI5TI.js} +2 -2
  45. package/dist/{chunk-MUPPP7A7.js → chunk-CMWIMFM6.js} +4 -182
  46. package/dist/{chunk-WKIS4VRK.js → chunk-CUYFCI4G.js} +70 -39
  47. package/dist/chunk-DA2KGZZI.js +13 -0
  48. package/dist/{chunk-Q6OCUQ7W.js → chunk-DYXVAO2E.js} +1 -1
  49. package/dist/{chunk-QH3I7ZOK.js → chunk-E3PDZPGV.js} +1 -1
  50. package/dist/{chunk-NU775DLU.js → chunk-GP32KD2J.js} +4 -12
  51. package/dist/{chunk-STF4GSK4.js → chunk-KN32OWL2.js} +5 -5
  52. package/dist/chunk-LHKZKAZ4.js +285 -0
  53. package/dist/{chunk-D5BWM37G.js → chunk-MFSET7Q7.js} +51 -341
  54. package/dist/{chunk-DUE4EUNL.js → chunk-MI6ZBDTS.js} +6 -6
  55. package/dist/{chunk-27T5HZHO.js → chunk-MRXMFB4L.js} +6 -87
  56. package/dist/{chunk-4A2R3AQB.js → chunk-MVPLEPSI.js} +1 -1
  57. package/dist/{chunk-7LRRVMPH.js → chunk-NY2F7BZA.js} +1 -1
  58. package/dist/chunk-O35GZCKL.js +311 -0
  59. package/dist/{chunk-U3KMII5Y.js → chunk-OEIITG5F.js} +1 -1
  60. package/dist/{chunk-6FKNNUSN.js → chunk-PCPSX4ES.js} +209 -7
  61. package/dist/{chunk-6YCIYOVA.js → chunk-PY3EIEAF.js} +1 -1
  62. package/dist/{chunk-U5POFCKM.js → chunk-QNIOBNOY.js} +284 -123
  63. package/dist/{chunk-JCRXXEMC.js → chunk-S3SGZUOI.js} +1 -1
  64. package/dist/chunk-SR6OMO5C.js +703 -0
  65. package/dist/{chunk-TQHCZXN7.js → chunk-UCWO5MKP.js} +7 -7
  66. package/dist/{chunk-ITLYUKGZ.js → chunk-VKQWU4PO.js} +2 -2
  67. package/dist/{chunk-JZPDYKRG.js → chunk-WDHPN2GH.js} +3 -3
  68. package/dist/{chunk-P2VU5JNH.js → chunk-WMUAKAIF.js} +42 -42
  69. package/dist/{chunk-NIKLTFBP.js → chunk-WN6VLHOU.js} +12 -5
  70. package/dist/{chunk-VC343WHM.js → chunk-WWYUYKKV.js} +1 -1
  71. package/dist/{chunk-OM4SFFJK.js → chunk-WYDF6PGK.js} +3 -3
  72. package/dist/{chunk-KRYJ5VOD.js → chunk-YNZPOFF3.js} +16 -21
  73. package/dist/{chunk-Z6OHCDXP.js → chunk-YYSEH2WC.js} +2 -2
  74. package/dist/{chunk-BITZUBPJ.js → chunk-YYZNESC3.js} +8 -8
  75. package/dist/{chunk-2VUDJGB6.js → chunk-ZUPDSJUE.js} +2 -5
  76. package/dist/{chunk-X5SXFVZT.js → chunk-ZV6PFUA4.js} +1 -1
  77. package/dist/cli/chat.js +34 -33
  78. package/dist/cli/check.js +5 -5
  79. package/dist/cli/plugins.js +12 -12
  80. package/dist/cli/snapshot-create.js +9 -9
  81. package/dist/cli/upgrade.js +6 -6
  82. package/dist/db/schema/conversations.d.ts +62 -0
  83. package/dist/db/schema.d.ts +31 -0
  84. package/dist/{db-FBHAWVXU.js → db-LPJKR2EO.js} +6 -6
  85. package/dist/instrumentation.js +3 -3
  86. package/dist/nitro.js +6 -6
  87. package/dist/{oauth-callback-server-5HS5ULC6.js → oauth-callback-server-DMXF4TTQ.js} +30 -28
  88. package/dist/{runner-46W6NV6B.js → runner-L5DPVYCN.js} +24 -20
  89. package/dist/{skills-TG3QC4B6.js → skills-NXG3LBCK.js} +5 -5
  90. package/dist/spawn-VRUIGKWW.js +42 -0
  91. package/dist/task-runner-7YTBSPXW.js +36 -0
  92. package/dist/{validation-GMRIDBC5.js → validation-CH36LTOS.js} +5 -5
  93. package/dist/version.js +1 -1
  94. package/dist/{work-W4ULBJTU.js → work-HBC5Y5VZ.js} +22 -21
  95. package/dist/{worker-M6NVACS2.js → worker-5RDZHLXH.js} +10 -10
  96. package/migrations/0037_conversation_location.sql +23 -0
  97. package/migrations/meta/0037_snapshot.json +3192 -0
  98. package/migrations/meta/_journal.json +7 -0
  99. package/package.json +4 -4
  100. package/dist/chat/api-turns/assistant-message.d.ts +0 -12
  101. package/dist/chat/api-turns/cancellation.d.ts +0 -24
  102. package/dist/chat/api-turns/routing.d.ts +0 -51
  103. package/dist/chat/api-turns/work.d.ts +0 -99
  104. package/dist/chat/task-execution/slack-resource-event.d.ts +0 -47
  105. package/dist/chunk-4YD3DET6.js +0 -1503
  106. package/dist/chunk-6FGN7ZEG.js +0 -221
  107. package/dist/spawn-Y6YWBIJS.js +0 -41
  108. package/dist/task-runner-YSGBPN4U.js +0 -34
package/dist/app.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-TQHCZXN7.js";
3
+ } from "./chunk-UCWO5MKP.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-2VUDJGB6.js";
6
+ } from "./chunk-ZUPDSJUE.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
- routeAgentInvocationWork
12
- } from "./chunk-KRYJ5VOD.js";
11
+ resolveAgentInvocationId
12
+ } from "./chunk-YNZPOFF3.js";
13
13
  import {
14
14
  GET as GET2,
15
15
  GET2 as GET3,
@@ -37,30 +37,12 @@ import {
37
37
  startProcessingReaction,
38
38
  stripLeadingBotMention,
39
39
  wakePausedTurn
40
- } from "./chunk-P2VU5JNH.js";
40
+ } from "./chunk-WMUAKAIF.js";
41
41
  import "./chunk-FA6POGLH.js";
42
- import {
43
- GET,
44
- apiTurnIdForMessage,
45
- appendAndEnqueueApiConversationMessage,
46
- conversationVisibilityFromSlackChannelType,
47
- createApiTurnCancellation,
48
- createApiTurnWorker,
49
- createVercelAttachmentStorage,
50
- getAuthPausedApiTurnId,
51
- lookupSlackUser,
52
- readConversationAccessFromSql,
53
- recordApiConversationActivity,
54
- resolveSlackChannelTypeFromMessage,
55
- resolveSlackConversationContext,
56
- routeApiTurnWork,
57
- webActorFromEmail
58
- } from "./chunk-4YD3DET6.js";
59
- import "./chunk-ITLYUKGZ.js";
60
42
  import {
61
43
  AgentRunError,
62
44
  executeTurn
63
- } from "./chunk-OM4SFFJK.js";
45
+ } from "./chunk-WYDF6PGK.js";
64
46
  import {
65
47
  buildDeliveredTurnStatePatch,
66
48
  completeAuthPauseTurn,
@@ -71,7 +53,7 @@ import {
71
53
  getTurnUserSlackMessageTs,
72
54
  persistAuthPauseTurnState,
73
55
  requireTurnFailureEventId
74
- } from "./chunk-EIWYZXSM.js";
56
+ } from "./chunk-7R5JRPCY.js";
75
57
  import {
76
58
  claimDispatchMailboxAppend,
77
59
  confirmDispatchMailboxAppend,
@@ -88,12 +70,14 @@ import {
88
70
  markDispatchCompleted,
89
71
  markDispatchFailed,
90
72
  markDispatchRunning,
91
- recordTaskExecution,
73
+ processPluginTask,
74
+ resolveTurnSessionRouting,
92
75
  scheduleSessionCompletedPluginTasks
93
- } from "./chunk-WL3R2KTS.js";
76
+ } from "./chunk-4RHJ3CXR.js";
94
77
  import {
78
+ ConversationTurnLifecycleService,
95
79
  getTurnLifecycle
96
- } from "./chunk-VC343WHM.js";
80
+ } from "./chunk-WWYUYKKV.js";
97
81
  import {
98
82
  coerceThreadConversationState,
99
83
  getLocationConfigurationService,
@@ -101,20 +85,40 @@ import {
101
85
  getPersistedThreadState,
102
86
  persistThreadRuntimeState,
103
87
  persistThreadState,
104
- persistThreadStateById,
105
- resolveConversationRouting,
106
- resolveTurnSessionRouting
107
- } from "./chunk-27T5HZHO.js";
88
+ persistThreadStateById
89
+ } from "./chunk-MRXMFB4L.js";
90
+ import {
91
+ GET,
92
+ appendAndEnqueueWebMessage,
93
+ conversationTurnIdForMessage,
94
+ conversationVisibilityFromSlackChannelType,
95
+ createVercelAttachmentStorage,
96
+ legacyWebMailboxMetadataSchema,
97
+ lookupSlackUser,
98
+ readConversationAccessFromSql,
99
+ recordWebConversationActivity,
100
+ resolveConversationDestination,
101
+ resolveSlackChannelTypeFromMessage,
102
+ resolveSlackConversationContext,
103
+ webActorFromEmail
104
+ } from "./chunk-SR6OMO5C.js";
105
+ import {
106
+ createWebAuthorization,
107
+ deleteWebAuthorization
108
+ } from "./chunk-VKQWU4PO.js";
109
+ import {
110
+ recordTaskExecution
111
+ } from "./chunk-LHKZKAZ4.js";
108
112
  import "./chunk-UTL3MHPC.js";
109
113
  import {
110
114
  createVercelPluginTaskCallback,
111
115
  queueCallback,
112
116
  registerVercelPluginTaskDevConsumer
113
- } from "./chunk-STF4GSK4.js";
117
+ } from "./chunk-KN32OWL2.js";
114
118
  import {
115
119
  validatePluginEgressCredentialHooks,
116
120
  validatePluginRegistrations
117
- } from "./chunk-U3KMII5Y.js";
121
+ } from "./chunk-OEIITG5F.js";
118
122
  import {
119
123
  defineJuniorPlugins,
120
124
  pluginCatalogConfigFromEnv,
@@ -122,6 +126,8 @@ import {
122
126
  pluginRuntimeRegistrationsFromPluginSet
123
127
  } from "./chunk-CM5HNV2W.js";
124
128
  import {
129
+ RESOURCE_EVENT_MESSAGE_AUTHOR,
130
+ RESOURCE_EVENT_SYSTEM_ACTOR,
125
131
  SANDBOX_EGRESS_PROXY_PATH,
126
132
  buildSteeringPiMessage,
127
133
  clearSandboxEgressSignals,
@@ -133,6 +139,8 @@ import {
133
139
  getConfigDefaults,
134
140
  getNextRunAtMs,
135
141
  ingestResourceEvent,
142
+ isResourceEventConversationMessage,
143
+ isResourceEventMailboxMetadata,
136
144
  latestReportedProgress,
137
145
  listThreadReplies,
138
146
  logScheduledTaskRunSkipped,
@@ -143,18 +151,18 @@ import {
143
151
  readPublicArtifact,
144
152
  renderAttachmentText,
145
153
  renderBlockText,
146
- resolveDestinationVisibility,
154
+ renderTaskInput,
147
155
  resolveSandboxEgressProviderForHost,
148
156
  scheduledTaskRunAttributes,
149
157
  setConfigDefaults,
150
158
  shouldEmitDevAgentTrace,
151
159
  shouldPropagateSandboxEgressTrace,
152
160
  unpublishedArtifactHeaders
153
- } from "./chunk-U5POFCKM.js";
161
+ } from "./chunk-QNIOBNOY.js";
154
162
  import {
155
163
  AuthorizationFlowDisabledError,
156
164
  PluginCredentialFailureError
157
- } from "./chunk-WRDW3A3D.js";
165
+ } from "./chunk-AC7MDOJW.js";
158
166
  import "./chunk-6Y5B5PEX.js";
159
167
  import "./chunk-DIB4GX3G.js";
160
168
  import {
@@ -162,63 +170,19 @@ import {
162
170
  deleteMcpAuthSessionsForUserProvider,
163
171
  deleteMcpServerSessionId,
164
172
  deleteMcpStoredOAuthCredentials
165
- } from "./chunk-BITZUBPJ.js";
173
+ } from "./chunk-YYZNESC3.js";
166
174
  import {
175
+ RetryableDeliveryError,
176
+ createAgentRunner,
167
177
  formatProviderLabel,
168
178
  postSlackMessage,
169
179
  startOAuthFlow
170
- } from "./chunk-6FKNNUSN.js";
171
- import {
172
- RESOURCE_EVENT_AUTHOR_ID,
173
- RESOURCE_EVENT_MESSAGE_AUTHOR,
174
- RESOURCE_EVENT_SYSTEM_ACTOR,
175
- collectAttachmentGarbage,
176
- collectEventTaskMatchKeys,
177
- findMatchingEventTasks,
178
- getResourceEventCatalog,
179
- isResourceEventConversationMessage,
180
- isResourceEventMailboxMetadata,
181
- isResourceEventSlackMessage,
182
- listScheduledTasks,
183
- listScheduledTasksForTeam,
184
- readScheduledTask,
185
- renderTaskInput,
186
- requestAttachmentDeletion,
187
- resourceEventGuidance,
188
- saveScheduledTaskInLock,
189
- scheduledRunId,
190
- scheduledRunSchema,
191
- withScheduledTaskLock
192
- } from "./chunk-MUPPP7A7.js";
193
- import {
194
- parseSlackThreadId
195
- } from "./chunk-4A2R3AQB.js";
196
- import {
197
- RetryableDeliveryError,
198
- createAgentRunner
199
- } from "./chunk-6FGN7ZEG.js";
200
- import {
201
- CONVERSATION_WORK_STALE_ENQUEUE_MS,
202
- appendAndEnqueueInboundMessage,
203
- clearExpiredConversationLease,
204
- ensureConversationWake,
205
- getConversation,
206
- getConversationWorkState,
207
- hasRunnableConversationWork,
208
- hasRunnableConversationWork2,
209
- isInvalidConversationRecordError,
210
- listActiveConversationIds,
211
- removeActiveConversation,
212
- requestConversationWork,
213
- stopConversationWork
214
- } from "./chunk-NIKLTFBP.js";
180
+ } from "./chunk-PCPSX4ES.js";
215
181
  import {
216
182
  ConversationTurnBoundaryError,
217
183
  CooperativeTurnYieldError,
218
184
  TurnInputCommitLostError,
219
185
  TurnInputDeferredError,
220
- buildDeterministicAssistantMessageId,
221
- buildDeterministicTurnId,
222
186
  clearPendingAuth,
223
187
  getAssistantReplyText,
224
188
  getConversationTurnBoundaryError,
@@ -229,7 +193,7 @@ import {
229
193
  markTurnCompleted,
230
194
  markTurnFailed,
231
195
  startActiveTurn
232
- } from "./chunk-NU775DLU.js";
196
+ } from "./chunk-GP32KD2J.js";
233
197
  import {
234
198
  abandonTurnRecord,
235
199
  appendThreadContextMessages,
@@ -265,22 +229,63 @@ import {
265
229
  trimTrailingAssistantMessages,
266
230
  turnHasReply,
267
231
  upsertConversationMessage
268
- } from "./chunk-D5BWM37G.js";
232
+ } from "./chunk-MFSET7Q7.js";
269
233
  import {
270
234
  getExperimentalFeatures,
271
235
  isExperimentalFeatureEnabled,
272
236
  setExperimentalFeatures
273
237
  } from "./chunk-2LYHWMR4.js";
238
+ import {
239
+ collectAttachmentGarbage,
240
+ collectEventTaskMatchKeys,
241
+ findMatchingEventTasks,
242
+ getResourceEventCatalog,
243
+ listScheduledTasks,
244
+ listScheduledTasksForTeam,
245
+ readScheduledTask,
246
+ requestAttachmentDeletion,
247
+ resourceEventGuidance,
248
+ saveScheduledTaskInLock,
249
+ scheduledRunId,
250
+ scheduledRunSchema,
251
+ withScheduledTaskLock
252
+ } from "./chunk-CMWIMFM6.js";
253
+ import {
254
+ parseSlackThreadId
255
+ } from "./chunk-MVPLEPSI.js";
256
+ import {
257
+ CONVERSATION_WORK_STALE_ENQUEUE_MS,
258
+ appendAndEnqueueInboundMessage,
259
+ clearExpiredConversationLease,
260
+ ensureConversationWake,
261
+ getConversation,
262
+ getConversationWorkState,
263
+ hasRunnableConversationWork,
264
+ hasRunnableConversationWork2,
265
+ isInvalidConversationRecordError,
266
+ listActiveConversationIds,
267
+ removeActiveConversation,
268
+ requestConversationWork,
269
+ stopConversationWork
270
+ } from "./chunk-WN6VLHOU.js";
271
+ import {
272
+ buildDeterministicAssistantMessageId,
273
+ buildDeterministicTurnId
274
+ } from "./chunk-DA2KGZZI.js";
275
+ import "./chunk-O35GZCKL.js";
274
276
  import {
275
277
  getSandboxResourceConfig,
276
278
  setSandboxResourceConfig
277
- } from "./chunk-D3GDGREI.js";
279
+ } from "./chunk-6AUR6PWR.js";
278
280
  import "./chunk-PDO5BLNM.js";
279
281
  import "./chunk-UIE3R5XU.js";
280
282
  import {
281
283
  WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC,
282
284
  verifyWorkspaceSnapshotJobMessage
283
285
  } from "./chunk-X6GDDWQH.js";
286
+ import {
287
+ getTurnRequestDeadline
288
+ } from "./chunk-S3SGZUOI.js";
284
289
  import {
285
290
  getVercelConversationWorkQueue,
286
291
  resolveConversationWorkQueueTopic,
@@ -291,9 +296,6 @@ import {
291
296
  isConversationQueueMessageRejectedError
292
297
  } from "./chunk-JAL3CH4G.js";
293
298
  import "./chunk-7H2VZTWN.js";
294
- import {
295
- getTurnRequestDeadline
296
- } from "./chunk-JCRXXEMC.js";
297
299
  import {
298
300
  SlackActionError,
299
301
  bindEventTaskCredentialSubject,
@@ -319,7 +321,7 @@ import {
319
321
  verifyEventTaskCredentialSubject,
320
322
  verifyScheduledTaskCredentialSubject,
321
323
  verifySlackDirectCredentialSubject
322
- } from "./chunk-DUE4EUNL.js";
324
+ } from "./chunk-MI6ZBDTS.js";
323
325
  import "./chunk-3Y47VMHV.js";
324
326
  import {
325
327
  createSlackDestination,
@@ -331,7 +333,7 @@ import {
331
333
  requireSlackDestination,
332
334
  withConversationEventLock,
333
335
  withConversationMutationLock
334
- } from "./chunk-WKIS4VRK.js";
336
+ } from "./chunk-CUYFCI4G.js";
335
337
  import {
336
338
  juniorAgentBindings,
337
339
  juniorAgentInvocations,
@@ -339,15 +341,14 @@ import {
339
341
  juniorConversations,
340
342
  juniorSchedulerRuns,
341
343
  juniorSchedulerTasks
342
- } from "./chunk-HXR3FHTE.js";
343
- import "./chunk-JZPDYKRG.js";
344
+ } from "./chunk-5VWAY27R.js";
345
+ import "./chunk-WDHPN2GH.js";
344
346
  import {
345
347
  acquireActiveLock,
346
348
  getStateAdapter,
347
349
  withActiveLock
348
- } from "./chunk-U6ZQHRIP.js";
350
+ } from "./chunk-5CXCGDIL.js";
349
351
  import {
350
- contextProvenance,
351
352
  instructionProvenanceFor
352
353
  } from "./chunk-GFBR4S3Q.js";
353
354
  import {
@@ -368,17 +369,17 @@ import {
368
369
  isProviderRetryError,
369
370
  setProfiles,
370
371
  setSlackReactionConfig
371
- } from "./chunk-URZ7UD4P.js";
372
+ } from "./chunk-BYBSI5TI.js";
372
373
  import {
373
374
  defaultModelId,
374
375
  modelIdForProfile
375
376
  } from "./chunk-D4YV5TDV.js";
376
- import "./chunk-Q6OCUQ7W.js";
377
- import "./chunk-Z6OHCDXP.js";
377
+ import "./chunk-DYXVAO2E.js";
378
+ import "./chunk-YYSEH2WC.js";
378
379
  import {
379
380
  pluginCatalogRuntime
380
- } from "./chunk-QH3I7ZOK.js";
381
- import "./chunk-X5SXFVZT.js";
381
+ } from "./chunk-E3PDZPGV.js";
382
+ import "./chunk-ZV6PFUA4.js";
382
383
  import {
383
384
  credentialContextForActor
384
385
  } from "./chunk-CEMMLV5L.js";
@@ -414,13 +415,13 @@ import {
414
415
  withContext,
415
416
  withLogContext,
416
417
  withSpan
417
- } from "./chunk-6YCIYOVA.js";
418
+ } from "./chunk-PY3EIEAF.js";
418
419
  import {
419
420
  continueTrace
420
421
  } from "./chunk-PEQXYSSE.js";
421
422
  import {
422
423
  JUNIOR_VERSION
423
- } from "./chunk-7LRRVMPH.js";
424
+ } from "./chunk-NY2F7BZA.js";
424
425
 
425
426
  // src/app.ts
426
427
  import { createRequire } from "module";
@@ -569,7 +570,6 @@ function buildDispatchRoutingContext(dispatch2) {
569
570
  dispatch2.actor,
570
571
  dispatch2.credentialSubject
571
572
  ),
572
- destinationVisibility: dispatch2.destinationVisibility,
573
573
  dispatch: {
574
574
  actor: dispatch2.actor,
575
575
  id: dispatch2.id,
@@ -689,12 +689,6 @@ async function resolveAgentDispatchId(context) {
689
689
  const dispatch2 = await getDispatchRecord(durableDispatchId);
690
690
  return dispatch2 && !isTerminalDispatchStatus(dispatch2.status) ? durableDispatchId : void 0;
691
691
  }
692
- function createAgentDispatchWorkRouter(options) {
693
- return async (context) => {
694
- const dispatchId = await resolveAgentDispatchId(context);
695
- return dispatchId ? await options.dispatchWorker(context, dispatchId) : await options.fallbackWorker(context);
696
- };
697
- }
698
692
  async function readDispatchTurnResult(dispatch2) {
699
693
  const conversationId = getDispatchConversationId(dispatch2);
700
694
  const turnId = getDispatchTurnId(dispatch2.id);
@@ -2742,13 +2736,13 @@ async function GET6(request) {
2742
2736
  // src/chat/ingress/slack-webhook.ts
2743
2737
  import {
2744
2738
  ChannelImpl,
2745
- ThreadImpl as ThreadImpl3
2739
+ ThreadImpl as ThreadImpl2
2746
2740
  } from "chat";
2747
2741
 
2748
2742
  // src/chat/task-execution/slack-work.ts
2749
2743
  import {
2750
- Message as Message3,
2751
- ThreadImpl as ThreadImpl2
2744
+ Message as Message2,
2745
+ ThreadImpl
2752
2746
  } from "chat";
2753
2747
  import { z as z3 } from "zod";
2754
2748
 
@@ -2938,87 +2932,6 @@ async function ensureSlackMessageActorIdentity(message, teamId, lookupSlackUser2
2938
2932
  return actor;
2939
2933
  }
2940
2934
 
2941
- // src/chat/task-execution/slack-resource-event.ts
2942
- import { Message as Message2, ThreadImpl } from "chat";
2943
- async function resolveSlackResourceEventThread(args) {
2944
- const routing = await resolveConversationRouting({
2945
- conversationId: args.conversationId,
2946
- conversationStore: args.conversationStore
2947
- });
2948
- const destination = requireSlackDestination(
2949
- routing?.destination ?? args.destination,
2950
- "Slack resource-event turn"
2951
- );
2952
- const threadTs = routing?.source?.platform === "slack" ? routing.source.threadTs?.trim() : void 0;
2953
- if (!threadTs) {
2954
- throw new Error(
2955
- `Conversation ${args.conversationId} is missing a Slack thread for resource-event delivery`
2956
- );
2957
- }
2958
- return { destination, threadTs };
2959
- }
2960
- function isPlainResourceEventRecord(record) {
2961
- return record.source === "resource_event" && isResourceEventMailboxMetadata(record.input.metadata) && !hasSlackConversationMetadata(record.input.metadata);
2962
- }
2963
- function hasSlackConversationMetadata(value) {
2964
- if (!value || typeof value !== "object" || Array.isArray(value)) {
2965
- return false;
2966
- }
2967
- const record = value;
2968
- return record.platform === "slack" && typeof record.thread === "object" && record.thread !== null && typeof record.message === "object" && record.message !== null;
2969
- }
2970
- function buildResourceEventSlackMessage(args) {
2971
- if (!isResourceEventMailboxMetadata(args.record.input.metadata)) {
2972
- throw new Error(
2973
- "Resource-event Slack turn requires resource-event metadata"
2974
- );
2975
- }
2976
- const event = args.record.input.metadata.resourceEvent;
2977
- const messageId = `resource-event-${event.subscriptionId}-${event.eventKey}`;
2978
- const threadId = `slack:${args.channelId}:${args.threadTs}`;
2979
- return new Message2({
2980
- id: messageId,
2981
- threadId,
2982
- text: args.record.input.text,
2983
- author: {
2984
- ...RESOURCE_EVENT_MESSAGE_AUTHOR,
2985
- isMe: false
2986
- },
2987
- isMention: false,
2988
- attachments: [],
2989
- metadata: {
2990
- dateSent: new Date(args.record.createdAtMs),
2991
- edited: false
2992
- },
2993
- formatted: { type: "root", children: [] },
2994
- raw: {
2995
- channel: args.channelId,
2996
- event_type: "resource_event",
2997
- resource_event_type: event.eventType,
2998
- thread_ts: args.threadTs,
2999
- type: "message",
3000
- user: RESOURCE_EVENT_AUTHOR_ID
3001
- }
3002
- });
3003
- }
3004
- function buildResourceEventSlackThread(args) {
3005
- const threadId = normalizeIncomingSlackThreadId(
3006
- `slack:${args.channelId}:${args.threadTs}`,
3007
- args.message
3008
- );
3009
- const message = withNormalizedThreadId(args.message, threadId);
3010
- return new ThreadImpl({
3011
- adapter: args.adapter,
3012
- stateAdapter: args.state,
3013
- id: threadId,
3014
- channelId: args.channelId,
3015
- currentMessage: message,
3016
- initialMessage: message,
3017
- isDM: args.channelId.startsWith("D"),
3018
- isSubscribedContext: true
3019
- });
3020
- }
3021
-
3022
2935
  // src/chat/slack/message-control.ts
3023
2936
  var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
3024
2937
  function stripLeadingSteeringOverride(text) {
@@ -3253,9 +3166,6 @@ function compareInboundMessages(left, right) {
3253
3166
  }
3254
3167
  function routeForRecords(records) {
3255
3168
  return records.some((record) => {
3256
- if (isPlainResourceEventRecord(record)) {
3257
- return false;
3258
- }
3259
3169
  const metadata = parseSlackMetadata(record.input.metadata);
3260
3170
  if (!metadata) {
3261
3171
  throw new Error("Conversation mailbox record is not Slack metadata");
@@ -3264,23 +3174,11 @@ function routeForRecords(records) {
3264
3174
  }) ? "mention" : "subscribed";
3265
3175
  }
3266
3176
  function restoreMessage(args) {
3267
- if (isPlainResourceEventRecord(args.record)) {
3268
- if (!args.threadTs) {
3269
- throw new Error(
3270
- "Resource-event Slack turn requires a thread timestamp"
3271
- );
3272
- }
3273
- return buildResourceEventSlackMessage({
3274
- channelId: args.channelId,
3275
- record: args.record,
3276
- threadTs: args.threadTs
3277
- });
3278
- }
3279
3177
  const metadata = parseSlackMetadata(args.record.input.metadata);
3280
3178
  if (!metadata) {
3281
3179
  throw new Error("Conversation mailbox record is not a Slack message");
3282
3180
  }
3283
- const message = Message3.fromJSON(metadata.message);
3181
+ const message = Message2.fromJSON(metadata.message);
3284
3182
  message.attachments = message.attachments.map(
3285
3183
  (attachment) => args.adapter.rehydrateAttachment(attachment)
3286
3184
  );
@@ -3290,9 +3188,6 @@ function restoreMessage(args) {
3290
3188
  async function bindSlackActorIdentities(args) {
3291
3189
  const byAuthorId = /* @__PURE__ */ new Map();
3292
3190
  for (const message of args.messages) {
3293
- if (isResourceEventSlackMessage(message)) {
3294
- continue;
3295
- }
3296
3191
  const authorId = requireSlackAuthorId(message);
3297
3192
  byAuthorId.set(authorId, [...byAuthorId.get(authorId) ?? [], message]);
3298
3193
  }
@@ -3317,7 +3212,7 @@ function restoreThread(args) {
3317
3212
  args.message
3318
3213
  );
3319
3214
  const message = withNormalizedThreadId(args.message, threadId);
3320
- return new ThreadImpl2({
3215
+ return new ThreadImpl({
3321
3216
  adapter: args.adapter,
3322
3217
  stateAdapter: args.state,
3323
3218
  id: threadId,
@@ -3382,10 +3277,9 @@ function createSlackConversationWorker(options) {
3382
3277
  if (!latestRecord) {
3383
3278
  return { status: "completed" };
3384
3279
  }
3385
- const hasPlainResourceEvent = records.some(isPlainResourceEventRecord);
3386
- const publishExternally = hasPlainResourceEvent ? true : latestRecord.publishExternally ?? context.publishExternally;
3387
- const latestMetadata = isPlainResourceEventRecord(latestRecord) ? void 0 : parseSlackMetadata(latestRecord.input.metadata);
3388
- if (!isPlainResourceEventRecord(latestRecord) && !latestMetadata) {
3280
+ const publishExternally = latestRecord.publishExternally ?? context.publishExternally;
3281
+ const latestMetadata = parseSlackMetadata(latestRecord.input.metadata);
3282
+ if (!latestMetadata) {
3389
3283
  throw new Error(
3390
3284
  "Latest conversation mailbox record is not Slack metadata"
3391
3285
  );
@@ -3393,27 +3287,19 @@ function createSlackConversationWorker(options) {
3393
3287
  if (!await context.checkIn()) {
3394
3288
  return { status: "lost_lease" };
3395
3289
  }
3396
- const resourceEventThread = hasPlainResourceEvent ? await resolveSlackResourceEventThread({
3397
- conversationId: context.conversationId,
3398
- conversationStore: options.conversationStore,
3399
- destination: context.destination
3400
- }) : void 0;
3401
3290
  const turnResult = await runWithSlackInstallation({
3402
3291
  adapter,
3403
- installation: resourceEventThread ? { teamId: resourceEventThread.destination.teamId } : getInstallation(records),
3292
+ installation: getInstallation(records),
3404
3293
  state,
3405
3294
  task: async () => {
3406
- const destination = resourceEventThread?.destination ?? requireSlackDestination(
3295
+ const destination = requireSlackDestination(
3407
3296
  context.destination,
3408
3297
  "Slack conversation work"
3409
3298
  );
3410
- const threadTs = resourceEventThread?.threadTs;
3411
3299
  const messages = records.map(
3412
3300
  (record) => restoreMessage({
3413
3301
  adapter,
3414
- channelId: destination.channelId,
3415
- record,
3416
- ...threadTs ? { threadTs } : void 0
3302
+ record
3417
3303
  })
3418
3304
  );
3419
3305
  await bindSlackActorIdentities({
@@ -3426,13 +3312,7 @@ function createSlackConversationWorker(options) {
3426
3312
  return;
3427
3313
  }
3428
3314
  const route = routeForRecords(records);
3429
- const thread = isPlainResourceEventRecord(latestRecord) && threadTs ? buildResourceEventSlackThread({
3430
- adapter,
3431
- channelId: destination.channelId,
3432
- message: latestMessage,
3433
- state,
3434
- threadTs
3435
- }) : restoreThread({
3315
+ const thread = restoreThread({
3436
3316
  adapter,
3437
3317
  isSubscribedContext: route === "subscribed",
3438
3318
  message: latestMessage,
@@ -3444,7 +3324,7 @@ function createSlackConversationWorker(options) {
3444
3324
  skipped,
3445
3325
  totalSinceLastHandler: messages.length
3446
3326
  };
3447
- const activeAuthorId = isResourceEventSlackMessage(latestMessage) ? RESOURCE_EVENT_AUTHOR_ID : requireSlackAuthorId(latestMessage);
3327
+ const activeAuthorId = requireSlackAuthorId(latestMessage);
3448
3328
  let initialMessagesAcked = false;
3449
3329
  const ack = async () => {
3450
3330
  if (initialMessagesAcked) {
@@ -3462,17 +3342,15 @@ function createSlackConversationWorker(options) {
3462
3342
  const drainSteeringMessages = async (accept) => {
3463
3343
  await context.attempt.drain(async (pendingRecords) => {
3464
3344
  const candidates = pendingRecords.filter(
3465
- (record) => isPlainResourceEventRecord(record) ? publishExternally : record.publishExternally === publishExternally
3345
+ (record) => record.publishExternally === publishExternally
3466
3346
  ).map((record) => ({
3467
3347
  inboundMessageId: record.inboundMessageId,
3468
3348
  message: restoreMessage({
3469
3349
  adapter,
3470
- channelId: destination.channelId,
3471
- record,
3472
- ...threadTs ? { threadTs } : void 0
3350
+ record
3473
3351
  })
3474
3352
  })).filter(
3475
- (candidate) => crossActorMidRunMode === "steer" || isResourceEventSlackMessage(candidate.message) || requireSlackAuthorId(candidate.message) === activeAuthorId || hasSteeringOverride(candidate.message.text)
3353
+ (candidate) => crossActorMidRunMode === "steer" || requireSlackAuthorId(candidate.message) === activeAuthorId || hasSteeringOverride(candidate.message.text)
3476
3354
  );
3477
3355
  return candidates.length > 0 ? await accept(candidates) : [];
3478
3356
  });
@@ -3630,7 +3508,7 @@ function textMentionsBot(text, botUserId) {
3630
3508
  }
3631
3509
 
3632
3510
  // src/chat/ingress/message-changed.ts
3633
- import { Message as Message4 } from "chat";
3511
+ import { Message as Message3 } from "chat";
3634
3512
  function getEditedMentionMessageId(messageTs) {
3635
3513
  return `${messageTs}:message_changed_mention`;
3636
3514
  }
@@ -3697,7 +3575,7 @@ function extractMessageChangedMention(body, botUserId, adapter) {
3697
3575
  ...sourceTeam ? { source_team: sourceTeam } : void 0,
3698
3576
  ...botId ? { bot_id: botId } : void 0
3699
3577
  };
3700
- const message = new Message4({
3578
+ const message = new Message3({
3701
3579
  id: getEditedMentionMessageId(messageTs),
3702
3580
  threadId,
3703
3581
  text: newText,
@@ -3936,7 +3814,7 @@ function normalizeMessageThreadId(message) {
3936
3814
  }
3937
3815
  async function buildThread(args) {
3938
3816
  const normalized = normalizeMessageThreadId(args.message);
3939
- return new ThreadImpl3({
3817
+ return new ThreadImpl2({
3940
3818
  adapter: args.adapter,
3941
3819
  stateAdapter: args.state,
3942
3820
  id: normalized.threadId,
@@ -5526,8 +5404,7 @@ function createSlackTurnRuntime(deps) {
5526
5404
  const threadId = getThreadId(thread, message);
5527
5405
  const channelId = getChannelId(thread, message);
5528
5406
  const runId = getRunId(thread, message);
5529
- const isResourceEventNotification = isResourceEventSlackMessage(message);
5530
- const actorId = isResourceEventNotification ? void 0 : message.author.userId;
5407
+ const actorId = message.author.userId;
5531
5408
  const turnContext = logContext({
5532
5409
  threadId,
5533
5410
  actorId,
@@ -5560,7 +5437,7 @@ function createSlackTurnRuntime(deps) {
5560
5437
  });
5561
5438
  const combinedText = combineTurnText(queuedMessages, currentText);
5562
5439
  const turnIsExplicitMention = Boolean(message.isMention) || queuedMessages.some((queued) => queued.explicitMention);
5563
- const preflightDecision = isResourceEventNotification ? void 0 : getSubscribedReplyPreflightDecision({
5440
+ const preflightDecision = getSubscribedReplyPreflightDecision({
5564
5441
  botUserName: deps.assistantUserName,
5565
5442
  rawText: combinedText.rawText,
5566
5443
  text: combinedText.userText,
@@ -5578,7 +5455,7 @@ function createSlackTurnRuntime(deps) {
5578
5455
  });
5579
5456
  return;
5580
5457
  }
5581
- if (!isResourceEventNotification && !turnIsExplicitMention && !isExperimentalFeatureEnabled("passive-routing")) {
5458
+ if (!turnIsExplicitMention && !isExperimentalFeatureEnabled("passive-routing")) {
5582
5459
  const decision2 = await deps.decideSubscribedReply({
5583
5460
  rawText: combinedText.rawText,
5584
5461
  text: combinedText.userText,
@@ -5616,7 +5493,7 @@ function createSlackTurnRuntime(deps) {
5616
5493
  thread,
5617
5494
  preparedState
5618
5495
  });
5619
- const decision = isResourceEventNotification ? { shouldReply: true, reason: "resource_event" } : await deps.decideSubscribedReply({
5496
+ const decision = await deps.decideSubscribedReply({
5620
5497
  rawText: combinedText.rawText,
5621
5498
  text: combinedText.userText,
5622
5499
  conversationContext: deps.getPreparedConversationContext(preparedState),
@@ -6426,6 +6303,21 @@ async function maybeApplyProviderDefaultConfigRequest(args) {
6426
6303
  };
6427
6304
  }
6428
6305
 
6306
+ // src/chat/conversations/destination-visibility.ts
6307
+ async function resolveDestinationVisibility(args) {
6308
+ if (args.visibility) {
6309
+ return args.visibility;
6310
+ }
6311
+ if (args.destination.platform === "local") {
6312
+ return "private";
6313
+ }
6314
+ return await getConversationStore().getDestinationVisibility({
6315
+ provider: "slack",
6316
+ providerDestinationId: args.destination.channelId,
6317
+ providerTenantId: args.destination.teamId
6318
+ });
6319
+ }
6320
+
6429
6321
  // src/chat/providers/slack/input.ts
6430
6322
  function steeringMessageKey(message) {
6431
6323
  if (message.role !== "user") {
@@ -6483,9 +6375,6 @@ function inboundMessageActor(queued) {
6483
6375
  };
6484
6376
  }
6485
6377
  function inboundMessageProvenance(queued, teamId) {
6486
- if (isResourceEventSlackMessage(queued.message)) {
6487
- return contextProvenance;
6488
- }
6489
6378
  const identity = getMessageActorIdentity(queued.message);
6490
6379
  const author = identity && "platform" in identity ? identity : createActor(
6491
6380
  { userId: parseActorUserId(queued.message.author.userId) },
@@ -6645,6 +6534,15 @@ function createSlackTurn(deps) {
6645
6534
  modelId: defaultModelId(botConfig)
6646
6535
  },
6647
6536
  async () => {
6537
+ await getConversationStore().recordActivity({
6538
+ activityAtMs: message.metadata.dateSent.getTime(),
6539
+ channelName,
6540
+ conversationId,
6541
+ destination,
6542
+ sessionSource: source,
6543
+ source: "slack",
6544
+ visibility: destinationVisibility
6545
+ });
6648
6546
  const content = parseContent(message);
6649
6547
  const strippedUserText = stripLeadingBotMention(
6650
6548
  stripLeadingSteeringOverride(content.topLevelText),
@@ -6658,7 +6556,7 @@ function createSlackTurn(deps) {
6658
6556
  userText: replaceTopLevelText(content, strippedUserText)
6659
6557
  };
6660
6558
  await Promise.all(
6661
- (options.queuedMessages ?? []).filter((queued) => !isResourceEventSlackMessage(queued.message)).map(
6559
+ (options.queuedMessages ?? []).map(
6662
6560
  (queued) => ensureSlackMessageActorIdentity(
6663
6561
  queued.message,
6664
6562
  teamId,
@@ -6672,9 +6570,6 @@ function createSlackTurn(deps) {
6672
6570
  if (options.execution) {
6673
6571
  executionActor = options.execution.dispatch.actor;
6674
6572
  credentialContext = options.execution.credentialContext;
6675
- } else if (isResourceEventSlackMessage(message)) {
6676
- executionActor = RESOURCE_EVENT_SYSTEM_ACTOR;
6677
- credentialContext = credentialContextForActor(executionActor);
6678
6573
  } else {
6679
6574
  executionActor = await ensureSlackMessageActorIdentity(
6680
6575
  message,
@@ -6764,7 +6659,7 @@ function createSlackTurn(deps) {
6764
6659
  omittedImageAttachmentCount: !isVisionEnabled() && hasPotentialImageAttachment(attachments) ? countPotentialImageAttachments(attachments) : 0,
6765
6660
  attachments: await deps.resolveUserAttachments(attachments, {
6766
6661
  threadId,
6767
- actorId: isResourceEventSlackMessage(queued.message) ? void 0 : queued.message.author.userId,
6662
+ actorId: queued.message.author.userId,
6768
6663
  channelId,
6769
6664
  runId,
6770
6665
  conversation: preparedState.conversation,
@@ -6854,8 +6749,7 @@ function createSlackTurn(deps) {
6854
6749
  await abandonTurnRecord({
6855
6750
  conversationId,
6856
6751
  turnId: activeTurnId,
6857
- // TODO(dcramer): Rename this legacy text in Slack and Conversation API Turn records together.
6858
- errorMessage: "Auth-parked session superseded by a new user message"
6752
+ errorMessage: "Auth-paused Turn superseded by new input"
6859
6753
  });
6860
6754
  markTurnClosed({
6861
6755
  conversation: preparedState.conversation,
@@ -7272,8 +7166,7 @@ function createSlackTurn(deps) {
7272
7166
  },
7273
7167
  history: piMessages,
7274
7168
  credentialContext,
7275
- // Always set the execution actor when known. Resource-event turns
7276
- // carry the system principal; interactive turns carry the Slack user.
7169
+ // Always set the execution Actor when known.
7277
7170
  actor: executionActor,
7278
7171
  slackConversation,
7279
7172
  source,
@@ -7282,7 +7175,6 @@ function createSlackTurn(deps) {
7282
7175
  publishExternally: shouldPublishExternally2(
7283
7176
  options.publishExternally
7284
7177
  ),
7285
- ...destinationVisibility ? { destinationVisibility } : void 0,
7286
7178
  surface: options.execution?.surface ?? "slack",
7287
7179
  dispatch: options.execution?.dispatch,
7288
7180
  toolChannelId,
@@ -7731,11 +7623,6 @@ async function persistConversationVisionCache(conversationId, vision) {
7731
7623
 
7732
7624
  // src/chat/runtime/conversation-message.ts
7733
7625
  var NON_TEXT_MESSAGE_TEXT = "[non-text message]";
7734
- function resourceEventType(entry) {
7735
- if (!entry.raw || typeof entry.raw !== "object") return void 0;
7736
- const raw = entry.raw;
7737
- return raw.event_type === "resource_event" && typeof raw.resource_event_type === "string" ? raw.resource_event_type : void 0;
7738
- }
7739
7626
  function resolveMessageText(args) {
7740
7627
  const text = normalizeConversationText(args.text);
7741
7628
  return text || NON_TEXT_MESSAGE_TEXT;
@@ -7760,7 +7647,6 @@ function toConversationMessage(args) {
7760
7647
  },
7761
7648
  meta: {
7762
7649
  attachmentCount: args.entry.attachments.length,
7763
- eventType: resourceEventType(args.entry),
7764
7650
  explicitMention: args.explicitMention,
7765
7651
  imageAttachmentCount: imageAttachmentCount > 0 ? imageAttachmentCount : void 0,
7766
7652
  imagesHydrated: !messageHasPotentialImageAttachment,
@@ -7930,14 +7816,14 @@ function createPrepareTurnState(deps) {
7930
7816
  }
7931
7817
 
7932
7818
  // src/chat/slack/dispatch-turn.ts
7933
- import { Message as Message5, ThreadImpl as ThreadImpl4 } from "chat";
7819
+ import { Message as Message4, ThreadImpl as ThreadImpl3 } from "chat";
7934
7820
  function createSlackDispatchTurnRunner(options) {
7935
7821
  return async function runSlackDispatchTurn(dispatch2, hooks) {
7936
7822
  const state = getStateAdapter();
7937
7823
  await state.connect();
7938
7824
  const conversationId = getDispatchConversationId(dispatch2);
7939
7825
  const adapter = options.getSlackAdapter();
7940
- const message = new Message5({
7826
+ const message = new Message4({
7941
7827
  id: getDispatchInputMessageId(dispatch2.id),
7942
7828
  threadId: conversationId,
7943
7829
  text: dispatch2.input,
@@ -7960,7 +7846,7 @@ function createSlackDispatchTurnRunner(options) {
7960
7846
  }
7961
7847
  });
7962
7848
  message.isMention = true;
7963
- const thread = new ThreadImpl4({
7849
+ const thread = new ThreadImpl3({
7964
7850
  adapter,
7965
7851
  stateAdapter: state,
7966
7852
  id: conversationId,
@@ -8393,6 +8279,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8393
8279
  return false;
8394
8280
  }
8395
8281
  const activeTurn = turn;
8282
+ const { dispatch: dispatch2, surface } = options.routingContext ?? {};
8396
8283
  const currentState = await getPersistedThreadState(
8397
8284
  payload.conversationId
8398
8285
  );
@@ -8401,7 +8288,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8401
8288
  conversation,
8402
8289
  conversationId: payload.conversationId
8403
8290
  });
8404
- const dispatchId = activeTurn.dispatchId ?? options.routingContext?.dispatch?.id;
8291
+ const dispatchId = activeTurn.dispatchId ?? dispatch2?.id;
8405
8292
  const dispatchUserMessage = dispatchId ? conversation.messages.find(
8406
8293
  (message) => message.role === "user" && options.inputMessageIds?.includes(message.id)
8407
8294
  ) : void 0;
@@ -8444,21 +8331,19 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8444
8331
  const routingDestination = routing.destination;
8445
8332
  const turnMessages = activeTurn.turnStartMessageIndex === void 0 ? [] : activeTurn.piMessages.slice(activeTurn.turnStartMessageIndex);
8446
8333
  const recordDispatchOutcome = async (dispatchOutcome) => {
8447
- const dispatchId2 = options.routingContext?.dispatch?.id;
8448
- if (!dispatchId2) {
8334
+ if (!dispatch2) {
8449
8335
  return;
8450
8336
  }
8451
8337
  await recordTurnSummary({
8452
8338
  conversationId: payload.conversationId,
8453
8339
  destination: routingDestination,
8454
- destinationVisibility: options.routingContext?.destinationVisibility,
8455
- dispatchId: dispatchId2,
8340
+ dispatchId: dispatch2.id,
8456
8341
  dispatchOutcome,
8457
8342
  turnId: payload.turnId,
8458
8343
  sliceId: activeTurn.sliceId,
8459
8344
  source,
8460
8345
  state: "failed",
8461
- surface: options.routingContext?.surface ?? "slack"
8346
+ surface: surface ?? "slack"
8462
8347
  });
8463
8348
  };
8464
8349
  return {
@@ -8474,22 +8359,24 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8474
8359
  ...getTurnUserReplyAttachmentContext(userMessage),
8475
8360
  text: userMessage.text
8476
8361
  },
8477
- // Pi history is SQL-authoritative: the resumed run reads its
8478
- // exact dispatch session so unrelated conversation input cannot
8479
- // gain system authority. Interactive turns retain their merged
8480
- // projection so queued steering remains visible.
8362
+ // A dispatch reads only history saved for this Turn. Other input
8363
+ // must not become part of a system Turn. Other Turns read
8364
+ // Conversation history. This keeps queued steering visible.
8481
8365
  history: dispatchId ? activeTurn.piMessages : await loadProjection({
8482
8366
  conversationId: payload.conversationId
8483
8367
  }),
8484
- ...options.routingContext,
8485
- credentialContext,
8486
8368
  actor,
8369
+ credentialContext,
8487
8370
  destination: routingDestination,
8371
+ ...dispatch2 ? { dispatch: dispatch2 } : void 0,
8488
8372
  ...routing.location ? { location: routing.location } : void 0,
8489
8373
  // Slack resume publishes unless the checkpoint opted out.
8490
8374
  // Missing means legacy/in-flight Slack turns still post.
8375
+ // TODO(dcramer): Remove this missing-as-publish fallback after no
8376
+ // stored Turn checkpoint can omit publishExternally.
8491
8377
  publishExternally: activeTurn.publishExternally !== false,
8492
8378
  source,
8379
+ ...surface ? { surface } : void 0,
8493
8380
  toolChannelId: destination.channelId,
8494
8381
  environment: {
8495
8382
  locationConfiguration
@@ -8703,30 +8590,794 @@ async function runNextPausedTurnInContext(conversationId, options, runOptions) {
8703
8590
  return false;
8704
8591
  }
8705
8592
 
8593
+ // src/chat/task-execution/conversation-turn.ts
8594
+ import { createHash } from "crypto";
8595
+
8596
+ // src/chat/task-execution/assistant-message.ts
8597
+ async function commitAssistantMessage(args) {
8598
+ const conversationMessageId = recordDeliveredAssistantMessage({
8599
+ conversation: args.conversation,
8600
+ sessionId: args.sessionId,
8601
+ source: args.source,
8602
+ text: args.text,
8603
+ userMessageId: args.userMessageId
8604
+ });
8605
+ if (args.publishedMessage?.providerMessageId) {
8606
+ markConversationMessage(args.conversation, conversationMessageId, {
8607
+ slackTs: args.publishedMessage.providerMessageId
8608
+ });
8609
+ }
8610
+ try {
8611
+ await persistWithRetry(
8612
+ () => commitAcceptedReply({
8613
+ ...args.agentMessage ? { agentMessage: args.agentMessage } : void 0,
8614
+ conversation: args.conversation,
8615
+ conversationMessageId,
8616
+ conversationId: args.conversationId,
8617
+ providerConversationBindings: args.publishedMessage?.providerConversationBindings
8618
+ })
8619
+ );
8620
+ } catch (error) {
8621
+ logException(
8622
+ new Error("Assistant message persistence failed"),
8623
+ "conversation.assistant.message_persist.failed",
8624
+ {
8625
+ "error.type": error instanceof Error ? error.name : typeof error
8626
+ }
8627
+ );
8628
+ }
8629
+ }
8630
+
8631
+ // src/chat/task-execution/mailbox-turn.ts
8632
+ import {
8633
+ createLocalSource,
8634
+ createWebSource
8635
+ } from "@sentry/junior-plugin-api";
8636
+ function turnInputFactsFromConversationMessage(message) {
8637
+ if (isResourceEventConversationMessage(message)) {
8638
+ return {
8639
+ actor: RESOURCE_EVENT_SYSTEM_ACTOR,
8640
+ author: message.author ?? RESOURCE_EVENT_MESSAGE_AUTHOR,
8641
+ source: "resource_event"
8642
+ };
8643
+ }
8644
+ const actor = createActor(message.author, {
8645
+ platform: "web",
8646
+ userId: message.author?.userId
8647
+ });
8648
+ if (actor?.platform !== "web") {
8649
+ return void 0;
8650
+ }
8651
+ return {
8652
+ actor,
8653
+ author: message.author ?? { userId: actor.userId },
8654
+ source: "web"
8655
+ };
8656
+ }
8657
+ function sourceFromTurnInput(args) {
8658
+ switch (args.source) {
8659
+ case "resource_event":
8660
+ return args.location ? createWebSource(
8661
+ args.conversationId,
8662
+ args.visibility === "private" ? "private" : "public"
8663
+ ) : createLocalSource(args.conversationId);
8664
+ case "web":
8665
+ return createWebSource(
8666
+ args.conversationId,
8667
+ args.visibility === "private" ? "private" : "public"
8668
+ );
8669
+ }
8670
+ }
8671
+ function hasResourceEventActor(actors) {
8672
+ return Boolean(
8673
+ actors?.some(
8674
+ (actor) => actor.platform === "system" && actor.name === RESOURCE_EVENT_SYSTEM_ACTOR.name
8675
+ )
8676
+ );
8677
+ }
8678
+ async function getActiveConversationTurnId(conversationId) {
8679
+ const summaries = await listTurnSummaries(conversationId);
8680
+ const active = summaries.filter(
8681
+ (summary) => summary.surface === "api" && !summary.dispatchId && (summary.state === "paused" || summary.state === "running")
8682
+ );
8683
+ if (active.length > 1) {
8684
+ throw new Error(
8685
+ `Conversation ${conversationId} has multiple active web turns`
8686
+ );
8687
+ }
8688
+ const turnId = active[0]?.turnId;
8689
+ if (!turnId) return void 0;
8690
+ const record = await getTurnRecord(conversationId, turnId);
8691
+ return record && record.surface === "api" && !record.dispatchId && (record.state === "paused" || record.state === "running") ? turnId : void 0;
8692
+ }
8693
+ async function getActiveMailboxTurnId(conversationId) {
8694
+ const summaries = await listTurnSummaries(conversationId);
8695
+ const active = (await Promise.all(
8696
+ summaries.filter(
8697
+ (summary) => !summary.dispatchId && (summary.state === "paused" || summary.state === "running")
8698
+ ).map((summary) => getTurnRecord(conversationId, summary.turnId))
8699
+ )).filter(
8700
+ (record) => record && !record.dispatchId && (record.surface === "api" || hasResourceEventActor(record.actors)) && (record.state === "paused" || record.state === "running")
8701
+ );
8702
+ if (active.length > 1) {
8703
+ throw new Error(
8704
+ `Conversation ${conversationId} has multiple active mailbox Turns`
8705
+ );
8706
+ }
8707
+ return active[0]?.turnId;
8708
+ }
8709
+ async function getAuthPausedConversationTurnId(conversationId) {
8710
+ const turnId = await getActiveConversationTurnId(conversationId);
8711
+ if (!turnId) return void 0;
8712
+ const record = await getTurnRecord(conversationId, turnId);
8713
+ return record?.state === "paused" && record.resumeReason === "auth" ? turnId : void 0;
8714
+ }
8715
+ function parseWebMessages(messages) {
8716
+ if (messages.length === 0) {
8717
+ return [];
8718
+ }
8719
+ const parsed = messages.map((message) => ({
8720
+ message,
8721
+ metadata: legacyWebMailboxMetadataSchema.safeParse(message.input.metadata)
8722
+ }));
8723
+ if (parsed.every((entry) => !entry.metadata.success)) {
8724
+ return [];
8725
+ }
8726
+ if (parsed.some((entry) => !entry.metadata.success)) {
8727
+ throw new Error("A Turn cannot combine different kinds of input");
8728
+ }
8729
+ return parsed.map((entry) => {
8730
+ if (!entry.metadata.success) {
8731
+ throw new Error("User message has invalid metadata");
8732
+ }
8733
+ const metadata = entry.metadata.data;
8734
+ const actor = {
8735
+ platform: "web",
8736
+ userId: metadata.authorUserId,
8737
+ email: metadata.authorEmail.trim().toLowerCase(),
8738
+ ...metadata.authorFullName ? { fullName: metadata.authorFullName } : void 0,
8739
+ ...metadata.authorUserName ? { userName: metadata.authorUserName } : void 0
8740
+ };
8741
+ return {
8742
+ actor,
8743
+ author: {
8744
+ email: actor.email,
8745
+ ...actor.fullName ? { fullName: actor.fullName } : void 0,
8746
+ userId: actor.userId,
8747
+ ...actor.userName ? { userName: actor.userName } : void 0
8748
+ },
8749
+ message: entry.message,
8750
+ source: "web"
8751
+ };
8752
+ });
8753
+ }
8754
+ function parseResourceEventMessages(messages) {
8755
+ if (messages.length === 0) {
8756
+ return [];
8757
+ }
8758
+ if (!messages.every(
8759
+ (message) => message.source === "resource_event" && isResourceEventMailboxMetadata(message.input.metadata)
8760
+ )) {
8761
+ return [];
8762
+ }
8763
+ return messages.map((message) => {
8764
+ if (!isResourceEventMailboxMetadata(message.input.metadata)) {
8765
+ throw new Error("Resource event has invalid metadata");
8766
+ }
8767
+ return {
8768
+ actor: RESOURCE_EVENT_SYSTEM_ACTOR,
8769
+ author: RESOURCE_EVENT_MESSAGE_AUTHOR,
8770
+ message,
8771
+ source: "resource_event"
8772
+ };
8773
+ });
8774
+ }
8775
+ async function resolveMailboxTurnWork(context) {
8776
+ const batch = parseWebMessages(context.attempt.messages);
8777
+ if (batch.length > 0) {
8778
+ return { kind: "mailbox", batch };
8779
+ }
8780
+ const resourceBatch = parseResourceEventMessages(context.attempt.messages);
8781
+ if (resourceBatch.length > 0) {
8782
+ return { kind: "mailbox", batch: resourceBatch };
8783
+ }
8784
+ if (context.attempt.messages.length > 0) {
8785
+ return void 0;
8786
+ }
8787
+ const turnId = await getActiveMailboxTurnId(context.conversationId);
8788
+ return turnId ? { kind: "resume", turnId } : void 0;
8789
+ }
8790
+
8791
+ // src/chat/task-execution/mailbox-input.ts
8792
+ function joinMailboxText(messages) {
8793
+ return messages.map((message) => message.input.text.trim()).filter(Boolean).join("\n\n");
8794
+ }
8795
+
8796
+ // src/chat/task-execution/conversation-turn.ts
8797
+ function stableHex(...parts) {
8798
+ return createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 24);
8799
+ }
8800
+ function captureConversationTurnFailure(args) {
8801
+ const eventId = logException(
8802
+ args.error,
8803
+ `conversation.turn.${args.failureCode}`,
8804
+ {
8805
+ conversationId: args.conversationId,
8806
+ ...args.runId ? { runId: args.runId } : void 0,
8807
+ turnId: args.turnId
8808
+ }
8809
+ );
8810
+ return typeof eventId === "string" ? eventId : void 0;
8811
+ }
8812
+ function hasLostTurnInputCommit(error) {
8813
+ const cause = getConversationTurnBoundaryError(error)?.cause ?? error;
8814
+ return isTurnInputCommitLostError(error) || isTurnInputCommitLostError(cause);
8815
+ }
8816
+ async function completeCancelledConversationTurn(args) {
8817
+ const pendingAuthorization = args.conversation.processing.pendingAuth?.sessionId === args.turnId ? args.conversation.processing.pendingAuth : void 0;
8818
+ await abandonTurnRecord({
8819
+ conversationId: args.conversationId,
8820
+ turnId: args.turnId,
8821
+ errorMessage: "Turn cancelled"
8822
+ });
8823
+ clearPendingAuth(args.conversation, args.turnId);
8824
+ markConversationMessage(args.conversation, args.userMessageId, {
8825
+ replied: false,
8826
+ skippedReason: "turn cancelled"
8827
+ });
8828
+ markTurnClosed({
8829
+ conversation: args.conversation,
8830
+ nowMs: Date.now(),
8831
+ sessionId: args.turnId
8832
+ });
8833
+ if (pendingAuthorization) {
8834
+ await deleteWebAuthorization({
8835
+ actorId: pendingAuthorization.actorId,
8836
+ conversationId: args.conversationId
8837
+ });
8838
+ }
8839
+ await persistThreadStateById(args.conversationId, {
8840
+ conversation: args.conversation,
8841
+ sandboxRef: args.sandboxRef
8842
+ });
8843
+ await new ConversationTurnLifecycleService(
8844
+ getConversationEventStore()
8845
+ ).complete({
8846
+ conversationId: args.conversationId,
8847
+ createdAtMs: Date.now(),
8848
+ outcome: "cancelled",
8849
+ turnId: args.turnId
8850
+ });
8851
+ await args.acknowledge();
8852
+ }
8853
+ function createConversationTurnWorker(agentRunner, publishMessage) {
8854
+ return async (context, resolved) => {
8855
+ const lifecycle = new ConversationTurnLifecycleService(
8856
+ getConversationEventStore()
8857
+ );
8858
+ const isResume = resolved.kind === "resume";
8859
+ let turnInputFacts;
8860
+ let text = "";
8861
+ let turnId = "";
8862
+ let userMessageId = "";
8863
+ let startedAtMs = Date.now();
8864
+ let inputMessageIds = [];
8865
+ const storedConversation = await getConversationStore().get({
8866
+ conversationId: context.conversationId
8867
+ });
8868
+ const mailboxDestination = resolved.kind === "mailbox" ? resolved.batch[0]?.message.destination : void 0;
8869
+ const destination = resolveConversationDestination({
8870
+ conversationId: context.conversationId,
8871
+ existing: context.destination ?? mailboxDestination ?? storedConversation?.destination
8872
+ });
8873
+ if (resolved.kind === "mailbox") {
8874
+ const first = resolved.batch[0];
8875
+ text = joinMailboxText(resolved.batch.map((entry) => entry.message));
8876
+ startedAtMs = first.message.createdAtMs;
8877
+ userMessageId = first.message.inboundMessageId;
8878
+ turnId = buildDeterministicTurnId(userMessageId);
8879
+ inputMessageIds = resolved.batch.map(
8880
+ (entry) => entry.message.inboundMessageId
8881
+ );
8882
+ turnInputFacts = first;
8883
+ } else {
8884
+ turnId = resolved.turnId;
8885
+ }
8886
+ const persisted = await getPersistedThreadState(context.conversationId);
8887
+ const conversation = coerceThreadConversationState(persisted);
8888
+ await hydrateConversationMessages({
8889
+ conversation,
8890
+ conversationId: context.conversationId
8891
+ });
8892
+ if (isResume) {
8893
+ const userMessage = getTurnUserMessage(conversation, turnId);
8894
+ if (!userMessage) {
8895
+ throw new Error(
8896
+ `Unable to locate the persisted user message for Turn "${turnId}"`
8897
+ );
8898
+ }
8899
+ turnInputFacts = turnInputFactsFromConversationMessage(userMessage);
8900
+ userMessageId = userMessage.id;
8901
+ text = userMessage.text;
8902
+ startedAtMs = userMessage.createdAtMs;
8903
+ inputMessageIds = [userMessageId];
8904
+ }
8905
+ if (!turnInputFacts) {
8906
+ throw new Error(
8907
+ `Resumed Turn is missing an Actor for Conversation ${context.conversationId}`
8908
+ );
8909
+ }
8910
+ const { actor, author } = turnInputFacts;
8911
+ const source = sourceFromTurnInput({
8912
+ conversationId: context.conversationId,
8913
+ location: storedConversation?.location,
8914
+ source: turnInputFacts.source,
8915
+ visibility: storedConversation?.visibility
8916
+ });
8917
+ const webActor = actor.platform === "web" ? actor : void 0;
8918
+ const savedTurn = isResume ? await getTurnRecord(context.conversationId, turnId) : void 0;
8919
+ const publish = turnInputFacts.source === "resource_event" && storedConversation?.location ? savedTurn?.publishExternally ?? true : false;
8920
+ const surface = publish ? "slack" : "api";
8921
+ return await withLogContext(
8922
+ {
8923
+ conversationId: context.conversationId,
8924
+ platform: actor.platform,
8925
+ ...webActor ? {
8926
+ userId: webActor.userId,
8927
+ ...webActor.userName ? { userName: webActor.userName } : void 0
8928
+ } : void 0
8929
+ },
8930
+ async () => {
8931
+ let acknowledged = isResume || context.attempt.messages.length === 0;
8932
+ const acknowledge = async () => {
8933
+ if (acknowledged) {
8934
+ return;
8935
+ }
8936
+ try {
8937
+ await context.attempt.ack();
8938
+ } catch {
8939
+ throw new TurnInputCommitLostError(
8940
+ `Conversation work lease lost before mailbox Message acknowledgement for ${context.conversationId}`
8941
+ );
8942
+ }
8943
+ acknowledged = true;
8944
+ };
8945
+ let sandboxRef = getPersistedSandboxState(persisted);
8946
+ const initialSandboxRef = sandboxRef;
8947
+ const stopSignal = context.stopSignal?.();
8948
+ const completeCancelledTurn = async () => {
8949
+ try {
8950
+ await completeCancelledConversationTurn({
8951
+ acknowledge,
8952
+ conversation,
8953
+ conversationId: context.conversationId,
8954
+ sandboxRef,
8955
+ turnId,
8956
+ userMessageId
8957
+ });
8958
+ } catch (error) {
8959
+ if (hasLostTurnInputCommit(error)) {
8960
+ return { status: "lost_lease" };
8961
+ }
8962
+ throw error;
8963
+ }
8964
+ return { status: "completed" };
8965
+ };
8966
+ if (isResume) {
8967
+ if (stopSignal?.aborted) {
8968
+ return await completeCancelledTurn();
8969
+ }
8970
+ } else {
8971
+ upsertConversationMessage(conversation, {
8972
+ id: userMessageId,
8973
+ role: "user",
8974
+ text: normalizeConversationText(text),
8975
+ createdAtMs: startedAtMs,
8976
+ author,
8977
+ meta: {
8978
+ explicitMention: true,
8979
+ replied: false,
8980
+ ...turnInputFacts.source === "web" ? { source: "web" } : void 0
8981
+ }
8982
+ });
8983
+ await persistConversationMessages({
8984
+ conversation,
8985
+ conversationId: context.conversationId
8986
+ });
8987
+ await lifecycle.start({
8988
+ conversationId: context.conversationId,
8989
+ createdAtMs: Date.now(),
8990
+ inputMessageIds,
8991
+ surface,
8992
+ turnId
8993
+ });
8994
+ if (stopSignal?.aborted) {
8995
+ return await completeCancelledTurn();
8996
+ }
8997
+ startActiveTurn({
8998
+ conversation,
8999
+ nextTurnId: turnId
9000
+ });
9001
+ }
9002
+ let currentRunId;
9003
+ let assistantMessageDelivered = false;
9004
+ let failureCode = "persistence_failed";
9005
+ let modelFailureEventId;
9006
+ let modelFailureCaptureAttempted = false;
9007
+ let completedSuccessfully = false;
9008
+ const deliverAssistantMessage = async (value) => {
9009
+ const agentMessage = typeof value === "string" ? void 0 : value;
9010
+ const replyText = typeof value === "string" ? value : getAssistantReplyText(value);
9011
+ if (!replyText?.trim()) {
9012
+ return;
9013
+ }
9014
+ failureCode = "delivery_failed";
9015
+ const location = storedConversation?.location;
9016
+ if (publish && (!location || !publishMessage)) {
9017
+ throw new Error(
9018
+ `Conversation ${context.conversationId} cannot publish its system Turn`
9019
+ );
9020
+ }
9021
+ const publishedMessage = publish && location && publishMessage ? await publishMessage({
9022
+ conversationId: context.conversationId,
9023
+ location,
9024
+ text: replyText
9025
+ }) : void 0;
9026
+ await commitAssistantMessage({
9027
+ ...agentMessage ? { agentMessage } : void 0,
9028
+ conversation,
9029
+ conversationId: context.conversationId,
9030
+ ...publishedMessage ? { publishedMessage } : void 0,
9031
+ sessionId: turnId,
9032
+ ...publishedMessage ? { source: "slack" } : turnInputFacts.source === "web" ? { source: "web" } : void 0,
9033
+ text: replyText,
9034
+ userMessageId
9035
+ });
9036
+ assistantMessageDelivered = true;
9037
+ failureCode = "agent_run_failed";
9038
+ };
9039
+ try {
9040
+ if (stopSignal?.aborted) {
9041
+ return await completeCancelledTurn();
9042
+ }
9043
+ if (!isResume) {
9044
+ const pendingAuthorizationActorId = conversation.processing.pendingAuth?.actorId;
9045
+ const authParked = (await listTurnSummaries(context.conversationId)).filter(
9046
+ (summary) => summary.surface === "api" && !summary.dispatchId && summary.state === "paused" && summary.resumeReason === "auth"
9047
+ );
9048
+ for (const parked of authParked) {
9049
+ if (stopSignal?.aborted) {
9050
+ return await completeCancelledTurn();
9051
+ }
9052
+ await abandonTurnRecord({
9053
+ conversationId: context.conversationId,
9054
+ turnId: parked.turnId,
9055
+ errorMessage: "Auth-paused Turn superseded by new input"
9056
+ });
9057
+ markTurnClosed({
9058
+ conversation,
9059
+ nowMs: Date.now(),
9060
+ sessionId: parked.turnId
9061
+ });
9062
+ }
9063
+ if (authParked.length > 0 && pendingAuthorizationActorId) {
9064
+ await deleteWebAuthorization({
9065
+ actorId: pendingAuthorizationActorId,
9066
+ conversationId: context.conversationId
9067
+ });
9068
+ }
9069
+ }
9070
+ await persistThreadStateById(context.conversationId, {
9071
+ conversation
9072
+ });
9073
+ if (stopSignal?.aborted) {
9074
+ return await completeCancelledTurn();
9075
+ }
9076
+ const piMessages = await loadProjection({
9077
+ conversationId: context.conversationId
9078
+ });
9079
+ failureCode = "agent_run_failed";
9080
+ currentRunId = `conversation-run:${stableHex(turnId, String(startedAtMs))}`;
9081
+ setTags({ runId: currentRunId });
9082
+ const outcome = await executeTurn(
9083
+ agentRunner,
9084
+ {
9085
+ conversationId: context.conversationId,
9086
+ turnId,
9087
+ runId: currentRunId,
9088
+ instruction: {
9089
+ text,
9090
+ context: buildConversationContext(conversation, {
9091
+ excludeMessageId: userMessageId
9092
+ })
9093
+ },
9094
+ history: piMessages,
9095
+ actor,
9096
+ credentialContext: credentialContextForActor(actor),
9097
+ // TODO(dcramer): Remove AgentRun.destination after agent and tool
9098
+ // code reads AgentRun.location and no Run consumer needs it.
9099
+ destination,
9100
+ // TODO(dcramer): Remove AgentRun.publishExternally after the
9101
+ // saved Turn publish choice controls optional Delivery.
9102
+ publishExternally: publish,
9103
+ source,
9104
+ ...storedConversation?.location ? { location: storedConversation.location } : void 0,
9105
+ surface,
9106
+ ...stopSignal ? { signal: stopSignal } : void 0,
9107
+ ...webActor ? {
9108
+ authorization: createWebAuthorization({
9109
+ actorId: webActor.userId,
9110
+ conversationId: context.conversationId
9111
+ })
9112
+ } : { disabledFeatures: ["interactive-auth"] },
9113
+ state: {
9114
+ pendingAuth: conversation.processing.pendingAuth,
9115
+ sandboxRef
9116
+ },
9117
+ delivery: deliverAssistantMessage,
9118
+ durability: {
9119
+ onInputCommitted: acknowledge,
9120
+ shouldYield: context.shouldYield,
9121
+ onSandboxRefChanged: async (nextSandboxRef) => {
9122
+ sandboxRef = nextSandboxRef;
9123
+ await persistThreadStateById(context.conversationId, {
9124
+ conversation,
9125
+ sandboxRef
9126
+ });
9127
+ },
9128
+ recordPendingAuth: async (pendingAuth) => {
9129
+ conversation.processing.pendingAuth = pendingAuth;
9130
+ await persistThreadStateById(context.conversationId, {
9131
+ conversation,
9132
+ sandboxRef
9133
+ });
9134
+ }
9135
+ }
9136
+ },
9137
+ async (result) => {
9138
+ if (stopSignal?.aborted) {
9139
+ throw stopSignal.reason ?? new DOMException("Turn cancelled", "AbortError");
9140
+ }
9141
+ modelFailureCaptureAttempted = result.diagnostics.outcome !== "success";
9142
+ const finalized = finalizeFailedTurnReplyWithEvent({
9143
+ reply: result,
9144
+ logException
9145
+ });
9146
+ const modelFailureReason = finalized.failureReason;
9147
+ const reply = finalized.reply;
9148
+ modelFailureEventId = finalized.eventId;
9149
+ if (reply.diagnostics.outcome !== "success") {
9150
+ await deliverAssistantMessage(reply.text);
9151
+ }
9152
+ const completedState = buildDeliveredTurnStatePatch({
9153
+ conversation,
9154
+ reply,
9155
+ sessionId: turnId,
9156
+ userMessageId
9157
+ });
9158
+ await persistThreadStateById(context.conversationId, {
9159
+ conversation: completedState.conversation,
9160
+ sandboxRef: reply.sandboxRef ?? sandboxRef
9161
+ });
9162
+ if (reply.piMessages?.length) {
9163
+ const latest = await getTurnRecord(
9164
+ context.conversationId,
9165
+ turnId
9166
+ );
9167
+ await saveTurnCheckpoint({
9168
+ mode: "completed",
9169
+ conversationId: context.conversationId,
9170
+ turnId,
9171
+ sliceId: latest?.sliceId ?? 1,
9172
+ messages: reply.piMessages,
9173
+ durationMs: reply.diagnostics.durationMs,
9174
+ usage: reply.diagnostics.usage,
9175
+ // TODO(dcramer): Remove checkpoint Destination after resume
9176
+ // reads the Conversation Location.
9177
+ destination,
9178
+ publishExternally: publish,
9179
+ source,
9180
+ actor,
9181
+ surface
9182
+ });
9183
+ }
9184
+ completedSuccessfully = reply.diagnostics.outcome === "success";
9185
+ return completedSuccessfully ? {
9186
+ outcome: assistantMessageDelivered ? "success" : "no_reply"
9187
+ } : {
9188
+ ...modelFailureEventId ? { eventId: modelFailureEventId } : void 0,
9189
+ failureCode: "model_execution_failed",
9190
+ ...modelFailureReason ? { failureReason: modelFailureReason } : void 0,
9191
+ outcome: "failed"
9192
+ };
9193
+ }
9194
+ );
9195
+ if (outcome.status !== "completed" && stopSignal?.aborted) {
9196
+ return await completeCancelledTurn();
9197
+ }
9198
+ if (outcome.status === "suspended") {
9199
+ return { status: "yielded" };
9200
+ }
9201
+ if (outcome.status === "awaiting_auth") {
9202
+ completeAuthPauseTurn({
9203
+ conversation,
9204
+ sessionId: turnId
9205
+ });
9206
+ await persistThreadStateById(context.conversationId, {
9207
+ conversation,
9208
+ sandboxRef
9209
+ });
9210
+ await acknowledge();
9211
+ return { status: "paused" };
9212
+ }
9213
+ if (completedSuccessfully) {
9214
+ try {
9215
+ await scheduleSessionCompletedPluginTasks(
9216
+ {
9217
+ conversationId: context.conversationId,
9218
+ sessionId: turnId
9219
+ },
9220
+ {
9221
+ send: async (message) => {
9222
+ try {
9223
+ await processPluginTask(message);
9224
+ } catch (error) {
9225
+ logException(
9226
+ error,
9227
+ "conversation.plugin.session_completion_task.failed",
9228
+ {
9229
+ conversationId: context.conversationId,
9230
+ pluginName: message.plugin,
9231
+ taskName: message.name,
9232
+ turnId
9233
+ }
9234
+ );
9235
+ }
9236
+ }
9237
+ }
9238
+ );
9239
+ } catch (error) {
9240
+ logException(
9241
+ error,
9242
+ "conversation.plugin.session_completion_task.failed",
9243
+ {
9244
+ conversationId: context.conversationId,
9245
+ turnId
9246
+ }
9247
+ );
9248
+ }
9249
+ }
9250
+ await acknowledge();
9251
+ return { status: "completed" };
9252
+ } catch (error) {
9253
+ const failure = error instanceof AgentRunError ? error.cause : error;
9254
+ if (hasLostTurnInputCommit(failure)) {
9255
+ return { status: "lost_lease" };
9256
+ }
9257
+ if (stopSignal?.aborted) {
9258
+ return await completeCancelledTurn();
9259
+ }
9260
+ if (!context.attempt.isFinalAttempt) {
9261
+ throw failure;
9262
+ }
9263
+ const failureEventId = modelFailureCaptureAttempted && failureCode === "agent_run_failed" ? modelFailureEventId : captureConversationTurnFailure({
9264
+ conversationId: context.conversationId,
9265
+ error: failure,
9266
+ failureCode,
9267
+ runId: currentRunId,
9268
+ turnId
9269
+ });
9270
+ try {
9271
+ markTurnFailed({
9272
+ conversation,
9273
+ nowMs: Date.now(),
9274
+ sessionId: turnId,
9275
+ userMessageId,
9276
+ markConversationMessage
9277
+ });
9278
+ await persistThreadStateById(context.conversationId, {
9279
+ conversation,
9280
+ sandboxRef: initialSandboxRef ?? null
9281
+ });
9282
+ } catch (persistenceError) {
9283
+ captureConversationTurnFailure({
9284
+ conversationId: context.conversationId,
9285
+ error: persistenceError,
9286
+ failureCode: "persistence_failed",
9287
+ runId: currentRunId,
9288
+ turnId
9289
+ });
9290
+ }
9291
+ await lifecycle.fail({
9292
+ conversationId: context.conversationId,
9293
+ createdAtMs: Date.now(),
9294
+ ...failureEventId ? { eventId: failureEventId } : void 0,
9295
+ failureCode,
9296
+ turnId
9297
+ });
9298
+ await acknowledge();
9299
+ return { status: "completed" };
9300
+ }
9301
+ }
9302
+ );
9303
+ };
9304
+ }
9305
+
9306
+ // src/chat/providers/slack/system-turn.ts
9307
+ function createSlackSystemTurnPublisher(args) {
9308
+ return async ({ conversationId, location, text }) => {
9309
+ if (location.provider !== "slack") {
9310
+ throw new Error(
9311
+ `Slack system Turn cannot publish to ${location.provider} Location`
9312
+ );
9313
+ }
9314
+ let messageIds;
9315
+ try {
9316
+ messageIds = await runWithSlackInstallation({
9317
+ adapter: args.getSlackAdapter(),
9318
+ installation: { teamId: location.teamId },
9319
+ state: args.state,
9320
+ task: async () => await sendSlackReply({
9321
+ channelId: location.channelId,
9322
+ conversationId,
9323
+ text,
9324
+ ...location.threadTs ? { threadTs: location.threadTs } : void 0
9325
+ })
9326
+ });
9327
+ } catch (error) {
9328
+ if (isRetryableSlackPostError(error)) {
9329
+ throw new RetryableDeliveryError(error);
9330
+ }
9331
+ throw error;
9332
+ }
9333
+ const providerMessageId = messageIds.at(-1);
9334
+ const providerConversationId = location.threadTs ?? messageIds[0];
9335
+ return {
9336
+ ...providerMessageId ? { providerMessageId } : void 0,
9337
+ ...providerConversationId ? {
9338
+ providerConversationBindings: [
9339
+ {
9340
+ provider: "slack",
9341
+ providerDestinationId: location.channelId,
9342
+ providerTenantId: location.teamId,
9343
+ providerConversationId
9344
+ }
9345
+ ]
9346
+ } : void 0
9347
+ };
9348
+ };
9349
+ }
9350
+
8706
9351
  // src/chat/app/conversation-work.ts
8707
9352
  function createConversationWork(options) {
8708
- const apiTurnCancellation = createApiTurnCancellation();
8709
9353
  const pausedTurns = createPausedTurns({
8710
9354
  conversationStore: options.conversationStore,
8711
9355
  queue: options.queue,
8712
9356
  ...options.state ? { state: options.state } : void 0
8713
9357
  });
8714
- const runtime = createSlackRuntime({
9358
+ const baseRuntime = createSlackRuntime({
8715
9359
  getSlackAdapter: options.getSlackAdapter,
8716
9360
  pausedTurns,
9361
+ ...options.sendPluginTask ? { sendPluginTask: options.sendPluginTask } : void 0,
8717
9362
  services: {
8718
9363
  ...options.services,
8719
9364
  agentRunner: options.agentRunner
8720
9365
  }
8721
9366
  });
9367
+ const runtime = options.wrapRuntime?.(baseRuntime) ?? baseRuntime;
9368
+ const scheduleCompletedPluginTasks = options.sendPluginTask ? async (params) => await scheduleSessionCompletedPluginTasks(params, {
9369
+ send: options.sendPluginTask
9370
+ }) : void 0;
8722
9371
  const slackWorker = createSlackConversationWorker({
8723
9372
  getSlackAdapter: options.getSlackAdapter,
8724
- conversationStore: options.conversationStore,
8725
9373
  runNextPausedTurn: async (conversationId, runOptions) => await runNextPausedTurn(
8726
9374
  conversationId,
8727
9375
  {
8728
9376
  agentRunner: options.agentRunner,
8729
- wakePausedTurn: pausedTurns.wake
9377
+ wakePausedTurn: pausedTurns.wake,
9378
+ ...scheduleCompletedPluginTasks ? {
9379
+ scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
9380
+ } : void 0
8730
9381
  },
8731
9382
  runOptions
8732
9383
  ),
@@ -8741,13 +9392,24 @@ function createConversationWork(options) {
8741
9392
  agentRunner: options.agentRunner,
8742
9393
  inputMessageIds: [getDispatchInputMessageId(dispatch2.id)],
8743
9394
  routingContext: buildDispatchRoutingContext(dispatch2),
8744
- wakePausedTurn: pausedTurns.wake
9395
+ wakePausedTurn: pausedTurns.wake,
9396
+ ...scheduleCompletedPluginTasks ? {
9397
+ scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
9398
+ } : void 0
8745
9399
  },
8746
9400
  { shouldYield: hooks.shouldYield }
8747
9401
  );
8748
9402
  },
8749
9403
  runTurn: runtime.runDispatchTurn
8750
9404
  });
9405
+ const invocationWorker = createAgentInvocationWorker(options.agentRunner);
9406
+ const conversationTurnWorker = createConversationTurnWorker(
9407
+ options.agentRunner,
9408
+ createSlackSystemTurnPublisher({
9409
+ getSlackAdapter: options.getSlackAdapter,
9410
+ state: options.state
9411
+ })
9412
+ );
8751
9413
  const destinationWorker = async (context) => {
8752
9414
  const destination = context.destination;
8753
9415
  if (!destination) {
@@ -8762,24 +9424,25 @@ function createConversationWork(options) {
8762
9424
  `Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`
8763
9425
  );
8764
9426
  };
8765
- const providerWorker = createAgentDispatchWorkRouter({
8766
- dispatchWorker,
8767
- fallbackWorker: destinationWorker
8768
- });
9427
+ const run = async (context) => {
9428
+ const mailboxTurn = await resolveMailboxTurnWork(context);
9429
+ if (mailboxTurn) {
9430
+ return await conversationTurnWorker(context, mailboxTurn);
9431
+ }
9432
+ const invocationId = await resolveAgentInvocationId(context);
9433
+ if (invocationId) {
9434
+ return await invocationWorker(context, invocationId);
9435
+ }
9436
+ const dispatchId = await resolveAgentDispatchId(context);
9437
+ if (dispatchId) {
9438
+ return await dispatchWorker(context, dispatchId);
9439
+ }
9440
+ return await destinationWorker(context);
9441
+ };
8769
9442
  return {
8770
- apiTurnCancellation,
8771
9443
  conversationStore: options.conversationStore,
8772
9444
  queue: options.queue,
8773
- run: routeApiTurnWork({
8774
- apiTurnWorker: createApiTurnWorker(
8775
- options.agentRunner,
8776
- apiTurnCancellation
8777
- ),
8778
- fallbackWorker: routeAgentInvocationWork({
8779
- invocationWorker: createAgentInvocationWorker(options.agentRunner),
8780
- fallbackWorker: providerWorker
8781
- })
8782
- }),
9445
+ run,
8783
9446
  runtime,
8784
9447
  state: options.state
8785
9448
  };
@@ -8859,7 +9522,7 @@ async function publicArtifactGET(args) {
8859
9522
  }
8860
9523
 
8861
9524
  // src/chat/event-tasks/ingest.ts
8862
- import { createHash } from "crypto";
9525
+ import { createHash as createHash2 } from "crypto";
8863
9526
  import {
8864
9527
  createSlackSource as createSlackSource3,
8865
9528
  RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
@@ -8867,7 +9530,7 @@ import {
8867
9530
  resourceEventSchema
8868
9531
  } from "@sentry/junior-plugin-api";
8869
9532
  function eventTaskDispatchKey(taskId, namespace, eventKey) {
8870
- return `event-task:${createHash("sha256").update(`${taskId}\0${namespace}\0${eventKey}`).digest("hex").slice(0, 32)}`;
9533
+ return `event-task:${createHash2("sha256").update(`${taskId}\0${namespace}\0${eventKey}`).digest("hex").slice(0, 32)}`;
8871
9534
  }
8872
9535
  function oneLine(value) {
8873
9536
  return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 512);
@@ -9008,8 +9671,8 @@ function createResourceEventAppPublisher(args) {
9008
9671
  };
9009
9672
  }
9010
9673
 
9011
- // src/chat/api-turns/stop.ts
9012
- async function stopApiConversationTurn(args) {
9674
+ // src/chat/conversations/stop.ts
9675
+ async function stopConversationTurn(args) {
9013
9676
  const nowMs = args.nowMs ?? Date.now();
9014
9677
  const stop = async () => await stopConversationWork({
9015
9678
  conversationId: args.conversationId,
@@ -9018,7 +9681,7 @@ async function stopApiConversationTurn(args) {
9018
9681
  state: args.state
9019
9682
  });
9020
9683
  let result = await stop();
9021
- if (result.status === "no_work" && await getAuthPausedApiTurnId(args.conversationId)) {
9684
+ if (result.status === "no_work" && await getAuthPausedConversationTurnId(args.conversationId)) {
9022
9685
  const conversation = await getConversation({
9023
9686
  conversationId: args.conversationId,
9024
9687
  state: args.state
@@ -9036,7 +9699,7 @@ async function stopApiConversationTurn(args) {
9036
9699
  await ensureConversationWake({
9037
9700
  conversationId: args.conversationId,
9038
9701
  conversationStore: args.conversationStore,
9039
- idempotencyKey: `api-stop:${args.conversationId}:${result.runId}`,
9702
+ idempotencyKey: `conversation-stop:${args.conversationId}:${result.runId}`,
9040
9703
  nowMs,
9041
9704
  queue: args.queue,
9042
9705
  replaceExistingWake: true,
@@ -9090,7 +9753,7 @@ function createAcpConversations(options) {
9090
9753
  if (!await hasConversationAccess(conversationId, user)) {
9091
9754
  return "not_found";
9092
9755
  }
9093
- await stopApiConversationTurn({
9756
+ await stopConversationTurn({
9094
9757
  conversationId,
9095
9758
  conversationStore: options.conversationStore,
9096
9759
  queue: options.queue,
@@ -9099,7 +9762,7 @@ function createAcpConversations(options) {
9099
9762
  return "cancelled";
9100
9763
  },
9101
9764
  async create({ conversationId, user }) {
9102
- await recordApiConversationActivity({
9765
+ await recordWebConversationActivity({
9103
9766
  actor: actorFromUser(user),
9104
9767
  conversationId,
9105
9768
  conversationStore: options.conversationStore,
@@ -9118,10 +9781,10 @@ function createAcpConversations(options) {
9118
9781
  options.eventStore,
9119
9782
  conversationId
9120
9783
  );
9121
- if (await getAuthPausedApiTurnId(conversationId)) {
9784
+ if (await getAuthPausedConversationTurnId(conversationId)) {
9122
9785
  return { status: "active" };
9123
9786
  }
9124
- const admission = await appendAndEnqueueApiConversationMessage(
9787
+ const result = await appendAndEnqueueWebMessage(
9125
9788
  {
9126
9789
  actor: actorFromUser(user),
9127
9790
  conversationId,
@@ -9135,12 +9798,12 @@ function createAcpConversations(options) {
9135
9798
  state: options.state
9136
9799
  }
9137
9800
  );
9138
- if (admission.status === "active") return { status: "active" };
9801
+ if (result.status === "active") return { status: "active" };
9139
9802
  return {
9140
- afterCursor: admission.status === "duplicate" ? 0 : currentCursor,
9141
- messageId: admission.messageId,
9803
+ afterCursor: result.status === "duplicate" ? 0 : currentCursor,
9804
+ messageId: result.messageId,
9142
9805
  status: "accepted",
9143
- turnId: apiTurnIdForMessage(admission.messageId)
9806
+ turnId: conversationTurnIdForMessage(result.messageId)
9144
9807
  };
9145
9808
  },
9146
9809
  async readMessages(conversationId) {
@@ -9198,12 +9861,12 @@ function createAcpConversations(options) {
9198
9861
  }
9199
9862
 
9200
9863
  // src/api/acp/route.ts
9201
- import { createHash as createHash4 } from "crypto";
9864
+ import { createHash as createHash5 } from "crypto";
9202
9865
  import * as acp4 from "@agentclientprotocol/sdk";
9203
9866
 
9204
9867
  // src/api/acp/auth.ts
9205
9868
  import {
9206
- createHash as createHash3,
9869
+ createHash as createHash4,
9207
9870
  randomBytes,
9208
9871
  randomUUID as randomUUID2,
9209
9872
  timingSafeEqual as timingSafeEqual3
@@ -9248,7 +9911,7 @@ async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
9248
9911
  }
9249
9912
 
9250
9913
  // src/api/acp/transport.ts
9251
- import { createHash as createHash2, randomUUID } from "crypto";
9914
+ import { createHash as createHash3, randomUUID } from "crypto";
9252
9915
  import * as acp2 from "@agentclientprotocol/sdk";
9253
9916
  import { userSchema } from "@sentry/junior-plugin-api";
9254
9917
  import { z as z7 } from "zod";
@@ -9428,8 +10091,8 @@ var acpRequestReceiptSchema = z7.object({
9428
10091
  sessionId: z7.string().min(1).optional()
9429
10092
  }).strict();
9430
10093
  var acpStreamCursorSchema = z7.object({ itemId: z7.string().min(1) }).strict();
9431
- function stableHex(value) {
9432
- return createHash2("sha256").update(value).digest("hex").slice(0, 32);
10094
+ function stableHex2(value) {
10095
+ return createHash3("sha256").update(value).digest("hex").slice(0, 32);
9433
10096
  }
9434
10097
  function connectionKey(connectionId) {
9435
10098
  return `junior:acp:v1:connection:${connectionId}`;
@@ -9444,7 +10107,7 @@ function connectionLockKey(connectionId) {
9444
10107
  return `${connectionKey(connectionId)}:lock`;
9445
10108
  }
9446
10109
  function streamKey(route) {
9447
- const suffix = route.sessionId ? `session:${stableHex(route.sessionId)}` : "connection";
10110
+ const suffix = route.sessionId ? `session:${stableHex2(route.sessionId)}` : "connection";
9448
10111
  return `${connectionKey(route.connectionId)}:stream:${suffix}`;
9449
10112
  }
9450
10113
  function streamListKey(route) {
@@ -9460,7 +10123,7 @@ function streamAppendLockKey(route) {
9460
10123
  return `${streamKey(route)}:append`;
9461
10124
  }
9462
10125
  function requestStreamItemId(requestKey2, index) {
9463
- return `acp-item:${stableHex(`${requestKey2}:${index}`)}`;
10126
+ return `acp-item:${stableHex2(`${requestKey2}:${index}`)}`;
9464
10127
  }
9465
10128
  function parseStreamItem(value) {
9466
10129
  return storedAcpStreamItemSchema.parse(value);
@@ -10069,7 +10732,7 @@ function authorizationPointerLockKey(connectionId) {
10069
10732
  return `${authorizationPointerKey(connectionId)}:lock`;
10070
10733
  }
10071
10734
  function credentialHash(value) {
10072
- return createHash3("sha256").update(value).digest("hex");
10735
+ return createHash4("sha256").update(value).digest("hex");
10073
10736
  }
10074
10737
  function createUserCode() {
10075
10738
  const value = randomBytes(6).toString("hex").toUpperCase();
@@ -10533,8 +11196,8 @@ function promptText(prompt) {
10533
11196
  }
10534
11197
  return text;
10535
11198
  }
10536
- function stableHex2(value, length = 32) {
10537
- return createHash4("sha256").update(value).digest("hex").slice(0, length);
11199
+ function stableHex3(value, length = 32) {
11200
+ return createHash5("sha256").update(value).digest("hex").slice(0, length);
10538
11201
  }
10539
11202
  function canonicalJson(value) {
10540
11203
  if (Array.isArray(value)) return value.map(canonicalJson);
@@ -10544,11 +11207,11 @@ function canonicalJson(value) {
10544
11207
  );
10545
11208
  }
10546
11209
  function requestKey(call) {
10547
- const id = call.id === null ? "null" : `${typeof call.id}:${stableHex2(String(call.id))}`;
11210
+ const id = call.id === null ? "null" : `${typeof call.id}:${stableHex3(String(call.id))}`;
10548
11211
  const payload = JSON.stringify(
10549
11212
  canonicalJson({ method: call.method, params: call.params ?? null })
10550
11213
  );
10551
- return `${id}:${stableHex2(payload)}`;
11214
+ return `${id}:${stableHex3(payload)}`;
10552
11215
  }
10553
11216
  function sessionIdFromCall(call) {
10554
11217
  if (!call) return void 0;
@@ -10601,7 +11264,7 @@ async function createSession(args) {
10601
11264
  args.call.params
10602
11265
  );
10603
11266
  rejectUnsupportedMcpServers(params.mcpServers);
10604
- const sessionId = `${ACP_CONVERSATION_PREFIX}${stableHex2(
11267
+ const sessionId = `${ACP_CONVERSATION_PREFIX}${stableHex3(
10605
11268
  `${args.connection.nonce}:${args.requestKey}`
10606
11269
  )}`;
10607
11270
  await args.conversations.create({
@@ -10615,16 +11278,16 @@ async function acceptPrompt(args) {
10615
11278
  promptParamsSchema,
10616
11279
  args.call.params
10617
11280
  );
10618
- const admission = await args.conversations.prompt({
11281
+ const result = await args.conversations.prompt({
10619
11282
  conversationId: params.sessionId,
10620
11283
  idempotencyKey: `${args.connection.nonce}:${args.requestKey}`,
10621
11284
  text: promptText(params.prompt),
10622
11285
  user: args.user
10623
11286
  });
10624
- if (admission.status === "not_found") {
11287
+ if (result.status === "not_found") {
10625
11288
  throw acp4.RequestError.resourceNotFound(params.sessionId);
10626
11289
  }
10627
- if (admission.status === "active") {
11290
+ if (result.status === "active") {
10628
11291
  throw acp4.RequestError.invalidParams(
10629
11292
  { field: "sessionId" },
10630
11293
  "This ACP session already has an active prompt"
@@ -10632,11 +11295,11 @@ async function acceptPrompt(args) {
10632
11295
  }
10633
11296
  return {
10634
11297
  output: {
10635
- afterSeq: admission.afterCursor,
11298
+ afterSeq: result.afterCursor,
10636
11299
  kind: "prompt",
10637
- messageId: admission.messageId,
11300
+ messageId: result.messageId,
10638
11301
  requestId: args.requestId,
10639
- turnId: admission.turnId
11302
+ turnId: result.turnId
10640
11303
  },
10641
11304
  sessionId: params.sessionId
10642
11305
  };