@sentry/junior 0.188.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 (109) hide show
  1. package/dist/{agent-hooks-5RQEVLQD.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 +1003 -346
  8. package/dist/{catalog-runtime-L4A6BJ3U.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 +8 -9
  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 -96
  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/projection.d.ts +2 -2
  18. package/dist/chat/conversations/sql/location.d.ts +13 -4
  19. package/dist/chat/{api-turns → conversations}/stop.d.ts +2 -2
  20. package/dist/chat/conversations/store.d.ts +4 -4
  21. package/dist/chat/conversations/structured-events.d.ts +1 -1
  22. package/dist/chat/{api-turns/authorization.d.ts → conversations/web-authorization.d.ts} +1 -0
  23. package/dist/chat/conversations/web-input.d.ts +98 -0
  24. package/dist/chat/conversations/web-mailbox.d.ts +12 -0
  25. package/dist/chat/event-tasks/tool-support.d.ts +0 -6
  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 +2 -2
  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-AW77HH54.js → chunk-4RHJ3CXR.js} +14 -295
  39. package/dist/{chunk-ZX7RSBQ6.js → chunk-5CXCGDIL.js} +1 -1
  40. package/dist/{chunk-QVH6FW3T.js → chunk-5VWAY27R.js} +7 -3
  41. package/dist/{chunk-XJIPMHKI.js → chunk-6AUR6PWR.js} +3 -3
  42. package/dist/{chunk-QDHJTKPE.js → chunk-7R5JRPCY.js} +8 -6
  43. package/dist/{chunk-6JZGXLL2.js → chunk-AC7MDOJW.js} +5 -7
  44. package/dist/{chunk-Q7O74WOO.js → chunk-BYBSI5TI.js} +2 -2
  45. package/dist/{chunk-VFZAUQ5V.js → chunk-CMWIMFM6.js} +4 -182
  46. package/dist/{chunk-IUUQWIG2.js → chunk-CUYFCI4G.js} +59 -11
  47. package/dist/chunk-DA2KGZZI.js +13 -0
  48. package/dist/{chunk-FIUCHYT6.js → chunk-DYXVAO2E.js} +1 -1
  49. package/dist/{chunk-NZLZ4KYZ.js → chunk-E3PDZPGV.js} +1 -1
  50. package/dist/{chunk-Z5SKZE5B.js → chunk-GP32KD2J.js} +4 -12
  51. package/dist/{chunk-XI4PVY2T.js → chunk-KN32OWL2.js} +5 -5
  52. package/dist/chunk-LHKZKAZ4.js +285 -0
  53. package/dist/{chunk-6YGFBU3A.js → chunk-MFSET7Q7.js} +44 -334
  54. package/dist/{chunk-QCGNHSMA.js → chunk-MI6ZBDTS.js} +6 -6
  55. package/dist/{chunk-CIG6WI7Q.js → chunk-MRXMFB4L.js} +5 -5
  56. package/dist/{chunk-CVBDVIF4.js → chunk-MVPLEPSI.js} +1 -1
  57. package/dist/{chunk-32XSSFZV.js → chunk-NY2F7BZA.js} +1 -1
  58. package/dist/chunk-O35GZCKL.js +311 -0
  59. package/dist/{chunk-HCIVBCP5.js → chunk-OEIITG5F.js} +1 -1
  60. package/dist/{chunk-UVUXFRYN.js → chunk-PCPSX4ES.js} +209 -7
  61. package/dist/{chunk-QIMN3FXL.js → chunk-PY3EIEAF.js} +1 -1
  62. package/dist/{chunk-RMB7CERI.js → chunk-QNIOBNOY.js} +282 -121
  63. package/dist/{chunk-WGZJ5SU4.js → chunk-S3SGZUOI.js} +1 -1
  64. package/dist/chunk-SR6OMO5C.js +703 -0
  65. package/dist/{chunk-CDSLOYOR.js → chunk-UCWO5MKP.js} +6 -6
  66. package/dist/{chunk-PSHMPRIU.js → chunk-VKQWU4PO.js} +2 -2
  67. package/dist/{chunk-X55FOVZO.js → chunk-WDHPN2GH.js} +3 -3
  68. package/dist/{chunk-WW2Y7JIA.js → chunk-WMUAKAIF.js} +43 -44
  69. package/dist/{chunk-MQDIIFZM.js → chunk-WN6VLHOU.js} +12 -5
  70. package/dist/{chunk-W42ENMJW.js → chunk-WWYUYKKV.js} +1 -1
  71. package/dist/{chunk-ERZMACYA.js → chunk-WYDF6PGK.js} +3 -3
  72. package/dist/{chunk-SC67CH3C.js → chunk-YNZPOFF3.js} +14 -17
  73. package/dist/{chunk-3HEZWDS5.js → chunk-YYSEH2WC.js} +2 -2
  74. package/dist/{chunk-W2DDJCPS.js → chunk-YYZNESC3.js} +8 -8
  75. package/dist/{chunk-CZRWU4ZM.js → chunk-ZUPDSJUE.js} +2 -5
  76. package/dist/{chunk-QIOUTXTZ.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/agent-invocations.d.ts +0 -36
  83. package/dist/db/schema/conversations.d.ts +62 -0
  84. package/dist/db/schema.d.ts +31 -36
  85. package/dist/{db-YPRZAA2T.js → db-LPJKR2EO.js} +6 -6
  86. package/dist/instrumentation.js +3 -3
  87. package/dist/nitro.js +6 -6
  88. package/dist/{oauth-callback-server-DBBIR3XG.js → oauth-callback-server-DMXF4TTQ.js} +30 -28
  89. package/dist/{runner-FKVFFPLO.js → runner-L5DPVYCN.js} +25 -21
  90. package/dist/{skills-4RBAZEMV.js → skills-NXG3LBCK.js} +5 -5
  91. package/dist/spawn-VRUIGKWW.js +42 -0
  92. package/dist/task-runner-7YTBSPXW.js +36 -0
  93. package/dist/{validation-E6Z5LHZM.js → validation-CH36LTOS.js} +5 -5
  94. package/dist/version.js +1 -1
  95. package/dist/{work-OFTXWOK4.js → work-HBC5Y5VZ.js} +22 -21
  96. package/dist/{worker-OMWNOKTJ.js → worker-5RDZHLXH.js} +10 -10
  97. package/migrations/0037_conversation_location.sql +23 -0
  98. package/migrations/meta/0037_snapshot.json +3192 -0
  99. package/migrations/meta/_journal.json +7 -0
  100. package/package.json +5 -5
  101. package/dist/chat/api-turns/assistant-message.d.ts +0 -12
  102. package/dist/chat/api-turns/cancellation.d.ts +0 -24
  103. package/dist/chat/api-turns/routing.d.ts +0 -51
  104. package/dist/chat/api-turns/work.d.ts +0 -99
  105. package/dist/chat/task-execution/slack-resource-event.d.ts +0 -55
  106. package/dist/chunk-6FGN7ZEG.js +0 -221
  107. package/dist/chunk-LODJKINF.js +0 -1502
  108. package/dist/spawn-CO7QFCNJ.js +0 -41
  109. package/dist/task-runner-DUGZGI7V.js +0 -34
package/dist/app.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-CDSLOYOR.js";
3
+ } from "./chunk-UCWO5MKP.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-CZRWU4ZM.js";
6
+ } from "./chunk-ZUPDSJUE.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
- routeAgentInvocationWork
12
- } from "./chunk-SC67CH3C.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-WW2Y7JIA.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-LODJKINF.js";
59
- import "./chunk-PSHMPRIU.js";
60
42
  import {
61
43
  AgentRunError,
62
44
  executeTurn
63
- } from "./chunk-ERZMACYA.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-QDHJTKPE.js";
56
+ } from "./chunk-7R5JRPCY.js";
75
57
  import {
76
58
  claimDispatchMailboxAppend,
77
59
  confirmDispatchMailboxAppend,
@@ -88,14 +70,14 @@ import {
88
70
  markDispatchCompleted,
89
71
  markDispatchFailed,
90
72
  markDispatchRunning,
91
- recordTaskExecution,
92
- resolveConversationRouting,
73
+ processPluginTask,
93
74
  resolveTurnSessionRouting,
94
75
  scheduleSessionCompletedPluginTasks
95
- } from "./chunk-AW77HH54.js";
76
+ } from "./chunk-4RHJ3CXR.js";
96
77
  import {
78
+ ConversationTurnLifecycleService,
97
79
  getTurnLifecycle
98
- } from "./chunk-W42ENMJW.js";
80
+ } from "./chunk-WWYUYKKV.js";
99
81
  import {
100
82
  coerceThreadConversationState,
101
83
  getLocationConfigurationService,
@@ -104,17 +86,39 @@ import {
104
86
  persistThreadRuntimeState,
105
87
  persistThreadState,
106
88
  persistThreadStateById
107
- } from "./chunk-CIG6WI7Q.js";
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-XI4PVY2T.js";
117
+ } from "./chunk-KN32OWL2.js";
114
118
  import {
115
119
  validatePluginEgressCredentialHooks,
116
120
  validatePluginRegistrations
117
- } from "./chunk-HCIVBCP5.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-RMB7CERI.js";
161
+ } from "./chunk-QNIOBNOY.js";
154
162
  import {
155
163
  AuthorizationFlowDisabledError,
156
164
  PluginCredentialFailureError
157
- } from "./chunk-6JZGXLL2.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-W2DDJCPS.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-UVUXFRYN.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-VFZAUQ5V.js";
193
- import {
194
- parseSlackThreadId
195
- } from "./chunk-CVBDVIF4.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-MQDIIFZM.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-Z5SKZE5B.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-6YGFBU3A.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-XJIPMHKI.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-WGZJ5SU4.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-QCGNHSMA.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-IUUQWIG2.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-QVH6FW3T.js";
343
- import "./chunk-X55FOVZO.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-ZX7RSBQ6.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-Q7O74WOO.js";
372
+ } from "./chunk-BYBSI5TI.js";
372
373
  import {
373
374
  defaultModelId,
374
375
  modelIdForProfile
375
376
  } from "./chunk-D4YV5TDV.js";
376
- import "./chunk-FIUCHYT6.js";
377
- import "./chunk-3HEZWDS5.js";
377
+ import "./chunk-DYXVAO2E.js";
378
+ import "./chunk-YYSEH2WC.js";
378
379
  import {
379
380
  pluginCatalogRuntime
380
- } from "./chunk-NZLZ4KYZ.js";
381
- import "./chunk-QIOUTXTZ.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-QIMN3FXL.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-32XSSFZV.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,85 +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
- return void 0;
2955
- }
2956
- return { destination, threadTs };
2957
- }
2958
- function isPlainResourceEventRecord(record) {
2959
- return record.source === "resource_event" && isResourceEventMailboxMetadata(record.input.metadata) && !hasSlackConversationMetadata(record.input.metadata);
2960
- }
2961
- function hasSlackConversationMetadata(value) {
2962
- if (!value || typeof value !== "object" || Array.isArray(value)) {
2963
- return false;
2964
- }
2965
- const record = value;
2966
- return record.platform === "slack" && typeof record.thread === "object" && record.thread !== null && typeof record.message === "object" && record.message !== null;
2967
- }
2968
- function buildResourceEventSlackMessage(args) {
2969
- if (!isResourceEventMailboxMetadata(args.record.input.metadata)) {
2970
- throw new Error(
2971
- "Resource-event Slack turn requires resource-event metadata"
2972
- );
2973
- }
2974
- const event = args.record.input.metadata.resourceEvent;
2975
- const messageId = `resource-event-${event.subscriptionId}-${event.eventKey}`;
2976
- const threadId = `slack:${args.channelId}:${args.threadTs}`;
2977
- return new Message2({
2978
- id: messageId,
2979
- threadId,
2980
- text: args.record.input.text,
2981
- author: {
2982
- ...RESOURCE_EVENT_MESSAGE_AUTHOR,
2983
- isMe: false
2984
- },
2985
- isMention: false,
2986
- attachments: [],
2987
- metadata: {
2988
- dateSent: new Date(args.record.createdAtMs),
2989
- edited: false
2990
- },
2991
- formatted: { type: "root", children: [] },
2992
- raw: {
2993
- channel: args.channelId,
2994
- event_type: "resource_event",
2995
- resource_event_type: event.eventType,
2996
- thread_ts: args.threadTs,
2997
- type: "message",
2998
- user: RESOURCE_EVENT_AUTHOR_ID
2999
- }
3000
- });
3001
- }
3002
- function buildResourceEventSlackThread(args) {
3003
- const threadId = normalizeIncomingSlackThreadId(
3004
- `slack:${args.channelId}:${args.threadTs}`,
3005
- args.message
3006
- );
3007
- const message = withNormalizedThreadId(args.message, threadId);
3008
- return new ThreadImpl({
3009
- adapter: args.adapter,
3010
- stateAdapter: args.state,
3011
- id: threadId,
3012
- channelId: args.channelId,
3013
- currentMessage: message,
3014
- initialMessage: message,
3015
- isDM: args.channelId.startsWith("D"),
3016
- isSubscribedContext: true
3017
- });
3018
- }
3019
-
3020
2935
  // src/chat/slack/message-control.ts
3021
2936
  var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
3022
2937
  function stripLeadingSteeringOverride(text) {
@@ -3251,9 +3166,6 @@ function compareInboundMessages(left, right) {
3251
3166
  }
3252
3167
  function routeForRecords(records) {
3253
3168
  return records.some((record) => {
3254
- if (isPlainResourceEventRecord(record)) {
3255
- return false;
3256
- }
3257
3169
  const metadata = parseSlackMetadata(record.input.metadata);
3258
3170
  if (!metadata) {
3259
3171
  throw new Error("Conversation mailbox record is not Slack metadata");
@@ -3262,23 +3174,11 @@ function routeForRecords(records) {
3262
3174
  }) ? "mention" : "subscribed";
3263
3175
  }
3264
3176
  function restoreMessage(args) {
3265
- if (isPlainResourceEventRecord(args.record)) {
3266
- if (!args.threadTs) {
3267
- throw new Error(
3268
- "Resource-event Slack turn requires a thread timestamp"
3269
- );
3270
- }
3271
- return buildResourceEventSlackMessage({
3272
- channelId: args.channelId,
3273
- record: args.record,
3274
- threadTs: args.threadTs
3275
- });
3276
- }
3277
3177
  const metadata = parseSlackMetadata(args.record.input.metadata);
3278
3178
  if (!metadata) {
3279
3179
  throw new Error("Conversation mailbox record is not a Slack message");
3280
3180
  }
3281
- const message = Message3.fromJSON(metadata.message);
3181
+ const message = Message2.fromJSON(metadata.message);
3282
3182
  message.attachments = message.attachments.map(
3283
3183
  (attachment) => args.adapter.rehydrateAttachment(attachment)
3284
3184
  );
@@ -3288,9 +3188,6 @@ function restoreMessage(args) {
3288
3188
  async function bindSlackActorIdentities(args) {
3289
3189
  const byAuthorId = /* @__PURE__ */ new Map();
3290
3190
  for (const message of args.messages) {
3291
- if (isResourceEventSlackMessage(message)) {
3292
- continue;
3293
- }
3294
3191
  const authorId = requireSlackAuthorId(message);
3295
3192
  byAuthorId.set(authorId, [...byAuthorId.get(authorId) ?? [], message]);
3296
3193
  }
@@ -3315,7 +3212,7 @@ function restoreThread(args) {
3315
3212
  args.message
3316
3213
  );
3317
3214
  const message = withNormalizedThreadId(args.message, threadId);
3318
- return new ThreadImpl2({
3215
+ return new ThreadImpl({
3319
3216
  adapter: args.adapter,
3320
3217
  stateAdapter: args.state,
3321
3218
  id: threadId,
@@ -3380,10 +3277,9 @@ function createSlackConversationWorker(options) {
3380
3277
  if (!latestRecord) {
3381
3278
  return { status: "completed" };
3382
3279
  }
3383
- const hasPlainResourceEvent = records.some(isPlainResourceEventRecord);
3384
- const publishExternally = hasPlainResourceEvent ? true : latestRecord.publishExternally ?? context.publishExternally;
3385
- const latestMetadata = isPlainResourceEventRecord(latestRecord) ? void 0 : parseSlackMetadata(latestRecord.input.metadata);
3386
- if (!isPlainResourceEventRecord(latestRecord) && !latestMetadata) {
3280
+ const publishExternally = latestRecord.publishExternally ?? context.publishExternally;
3281
+ const latestMetadata = parseSlackMetadata(latestRecord.input.metadata);
3282
+ if (!latestMetadata) {
3387
3283
  throw new Error(
3388
3284
  "Latest conversation mailbox record is not Slack metadata"
3389
3285
  );
@@ -3391,34 +3287,19 @@ function createSlackConversationWorker(options) {
3391
3287
  if (!await context.checkIn()) {
3392
3288
  return { status: "lost_lease" };
3393
3289
  }
3394
- const resourceEventThread = hasPlainResourceEvent ? await resolveSlackResourceEventThread({
3395
- conversationId: context.conversationId,
3396
- conversationStore: options.conversationStore,
3397
- destination: context.destination
3398
- }) : void 0;
3399
- if (hasPlainResourceEvent && !resourceEventThread) {
3400
- logWarn("conversation.work.resource_event.missing_thread", {
3401
- "app.inbound.message_count": records.length
3402
- });
3403
- await context.attempt.ack();
3404
- return { status: "completed" };
3405
- }
3406
3290
  const turnResult = await runWithSlackInstallation({
3407
3291
  adapter,
3408
- installation: resourceEventThread ? { teamId: resourceEventThread.destination.teamId } : getInstallation(records),
3292
+ installation: getInstallation(records),
3409
3293
  state,
3410
3294
  task: async () => {
3411
- const destination = resourceEventThread?.destination ?? requireSlackDestination(
3295
+ const destination = requireSlackDestination(
3412
3296
  context.destination,
3413
3297
  "Slack conversation work"
3414
3298
  );
3415
- const threadTs = resourceEventThread?.threadTs;
3416
3299
  const messages = records.map(
3417
3300
  (record) => restoreMessage({
3418
3301
  adapter,
3419
- channelId: destination.channelId,
3420
- record,
3421
- ...threadTs ? { threadTs } : void 0
3302
+ record
3422
3303
  })
3423
3304
  );
3424
3305
  await bindSlackActorIdentities({
@@ -3431,13 +3312,7 @@ function createSlackConversationWorker(options) {
3431
3312
  return;
3432
3313
  }
3433
3314
  const route = routeForRecords(records);
3434
- const thread = isPlainResourceEventRecord(latestRecord) && threadTs ? buildResourceEventSlackThread({
3435
- adapter,
3436
- channelId: destination.channelId,
3437
- message: latestMessage,
3438
- state,
3439
- threadTs
3440
- }) : restoreThread({
3315
+ const thread = restoreThread({
3441
3316
  adapter,
3442
3317
  isSubscribedContext: route === "subscribed",
3443
3318
  message: latestMessage,
@@ -3449,7 +3324,7 @@ function createSlackConversationWorker(options) {
3449
3324
  skipped,
3450
3325
  totalSinceLastHandler: messages.length
3451
3326
  };
3452
- const activeAuthorId = isResourceEventSlackMessage(latestMessage) ? RESOURCE_EVENT_AUTHOR_ID : requireSlackAuthorId(latestMessage);
3327
+ const activeAuthorId = requireSlackAuthorId(latestMessage);
3453
3328
  let initialMessagesAcked = false;
3454
3329
  const ack = async () => {
3455
3330
  if (initialMessagesAcked) {
@@ -3467,17 +3342,15 @@ function createSlackConversationWorker(options) {
3467
3342
  const drainSteeringMessages = async (accept) => {
3468
3343
  await context.attempt.drain(async (pendingRecords) => {
3469
3344
  const candidates = pendingRecords.filter(
3470
- (record) => isPlainResourceEventRecord(record) ? publishExternally : record.publishExternally === publishExternally
3345
+ (record) => record.publishExternally === publishExternally
3471
3346
  ).map((record) => ({
3472
3347
  inboundMessageId: record.inboundMessageId,
3473
3348
  message: restoreMessage({
3474
3349
  adapter,
3475
- channelId: destination.channelId,
3476
- record,
3477
- ...threadTs ? { threadTs } : void 0
3350
+ record
3478
3351
  })
3479
3352
  })).filter(
3480
- (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)
3481
3354
  );
3482
3355
  return candidates.length > 0 ? await accept(candidates) : [];
3483
3356
  });
@@ -3635,7 +3508,7 @@ function textMentionsBot(text, botUserId) {
3635
3508
  }
3636
3509
 
3637
3510
  // src/chat/ingress/message-changed.ts
3638
- import { Message as Message4 } from "chat";
3511
+ import { Message as Message3 } from "chat";
3639
3512
  function getEditedMentionMessageId(messageTs) {
3640
3513
  return `${messageTs}:message_changed_mention`;
3641
3514
  }
@@ -3702,7 +3575,7 @@ function extractMessageChangedMention(body, botUserId, adapter) {
3702
3575
  ...sourceTeam ? { source_team: sourceTeam } : void 0,
3703
3576
  ...botId ? { bot_id: botId } : void 0
3704
3577
  };
3705
- const message = new Message4({
3578
+ const message = new Message3({
3706
3579
  id: getEditedMentionMessageId(messageTs),
3707
3580
  threadId,
3708
3581
  text: newText,
@@ -3941,7 +3814,7 @@ function normalizeMessageThreadId(message) {
3941
3814
  }
3942
3815
  async function buildThread(args) {
3943
3816
  const normalized = normalizeMessageThreadId(args.message);
3944
- return new ThreadImpl3({
3817
+ return new ThreadImpl2({
3945
3818
  adapter: args.adapter,
3946
3819
  stateAdapter: args.state,
3947
3820
  id: normalized.threadId,
@@ -5531,8 +5404,7 @@ function createSlackTurnRuntime(deps) {
5531
5404
  const threadId = getThreadId(thread, message);
5532
5405
  const channelId = getChannelId(thread, message);
5533
5406
  const runId = getRunId(thread, message);
5534
- const isResourceEventNotification = isResourceEventSlackMessage(message);
5535
- const actorId = isResourceEventNotification ? void 0 : message.author.userId;
5407
+ const actorId = message.author.userId;
5536
5408
  const turnContext = logContext({
5537
5409
  threadId,
5538
5410
  actorId,
@@ -5565,7 +5437,7 @@ function createSlackTurnRuntime(deps) {
5565
5437
  });
5566
5438
  const combinedText = combineTurnText(queuedMessages, currentText);
5567
5439
  const turnIsExplicitMention = Boolean(message.isMention) || queuedMessages.some((queued) => queued.explicitMention);
5568
- const preflightDecision = isResourceEventNotification ? void 0 : getSubscribedReplyPreflightDecision({
5440
+ const preflightDecision = getSubscribedReplyPreflightDecision({
5569
5441
  botUserName: deps.assistantUserName,
5570
5442
  rawText: combinedText.rawText,
5571
5443
  text: combinedText.userText,
@@ -5583,7 +5455,7 @@ function createSlackTurnRuntime(deps) {
5583
5455
  });
5584
5456
  return;
5585
5457
  }
5586
- if (!isResourceEventNotification && !turnIsExplicitMention && !isExperimentalFeatureEnabled("passive-routing")) {
5458
+ if (!turnIsExplicitMention && !isExperimentalFeatureEnabled("passive-routing")) {
5587
5459
  const decision2 = await deps.decideSubscribedReply({
5588
5460
  rawText: combinedText.rawText,
5589
5461
  text: combinedText.userText,
@@ -5621,7 +5493,7 @@ function createSlackTurnRuntime(deps) {
5621
5493
  thread,
5622
5494
  preparedState
5623
5495
  });
5624
- const decision = isResourceEventNotification ? { shouldReply: true, reason: "resource_event" } : await deps.decideSubscribedReply({
5496
+ const decision = await deps.decideSubscribedReply({
5625
5497
  rawText: combinedText.rawText,
5626
5498
  text: combinedText.userText,
5627
5499
  conversationContext: deps.getPreparedConversationContext(preparedState),
@@ -6431,6 +6303,21 @@ async function maybeApplyProviderDefaultConfigRequest(args) {
6431
6303
  };
6432
6304
  }
6433
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
+
6434
6321
  // src/chat/providers/slack/input.ts
6435
6322
  function steeringMessageKey(message) {
6436
6323
  if (message.role !== "user") {
@@ -6488,9 +6375,6 @@ function inboundMessageActor(queued) {
6488
6375
  };
6489
6376
  }
6490
6377
  function inboundMessageProvenance(queued, teamId) {
6491
- if (isResourceEventSlackMessage(queued.message)) {
6492
- return contextProvenance;
6493
- }
6494
6378
  const identity = getMessageActorIdentity(queued.message);
6495
6379
  const author = identity && "platform" in identity ? identity : createActor(
6496
6380
  { userId: parseActorUserId(queued.message.author.userId) },
@@ -6650,6 +6534,15 @@ function createSlackTurn(deps) {
6650
6534
  modelId: defaultModelId(botConfig)
6651
6535
  },
6652
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
+ });
6653
6546
  const content = parseContent(message);
6654
6547
  const strippedUserText = stripLeadingBotMention(
6655
6548
  stripLeadingSteeringOverride(content.topLevelText),
@@ -6663,7 +6556,7 @@ function createSlackTurn(deps) {
6663
6556
  userText: replaceTopLevelText(content, strippedUserText)
6664
6557
  };
6665
6558
  await Promise.all(
6666
- (options.queuedMessages ?? []).filter((queued) => !isResourceEventSlackMessage(queued.message)).map(
6559
+ (options.queuedMessages ?? []).map(
6667
6560
  (queued) => ensureSlackMessageActorIdentity(
6668
6561
  queued.message,
6669
6562
  teamId,
@@ -6677,9 +6570,6 @@ function createSlackTurn(deps) {
6677
6570
  if (options.execution) {
6678
6571
  executionActor = options.execution.dispatch.actor;
6679
6572
  credentialContext = options.execution.credentialContext;
6680
- } else if (isResourceEventSlackMessage(message)) {
6681
- executionActor = RESOURCE_EVENT_SYSTEM_ACTOR;
6682
- credentialContext = credentialContextForActor(executionActor);
6683
6573
  } else {
6684
6574
  executionActor = await ensureSlackMessageActorIdentity(
6685
6575
  message,
@@ -6769,7 +6659,7 @@ function createSlackTurn(deps) {
6769
6659
  omittedImageAttachmentCount: !isVisionEnabled() && hasPotentialImageAttachment(attachments) ? countPotentialImageAttachments(attachments) : 0,
6770
6660
  attachments: await deps.resolveUserAttachments(attachments, {
6771
6661
  threadId,
6772
- actorId: isResourceEventSlackMessage(queued.message) ? void 0 : queued.message.author.userId,
6662
+ actorId: queued.message.author.userId,
6773
6663
  channelId,
6774
6664
  runId,
6775
6665
  conversation: preparedState.conversation,
@@ -6859,8 +6749,7 @@ function createSlackTurn(deps) {
6859
6749
  await abandonTurnRecord({
6860
6750
  conversationId,
6861
6751
  turnId: activeTurnId,
6862
- // TODO(dcramer): Rename this legacy text in Slack and Conversation API Turn records together.
6863
- errorMessage: "Auth-parked session superseded by a new user message"
6752
+ errorMessage: "Auth-paused Turn superseded by new input"
6864
6753
  });
6865
6754
  markTurnClosed({
6866
6755
  conversation: preparedState.conversation,
@@ -7277,16 +7166,15 @@ function createSlackTurn(deps) {
7277
7166
  },
7278
7167
  history: piMessages,
7279
7168
  credentialContext,
7280
- // Always set the execution actor when known. Resource-event turns
7281
- // carry the system principal; interactive turns carry the Slack user.
7169
+ // Always set the execution Actor when known.
7282
7170
  actor: executionActor,
7283
7171
  slackConversation,
7284
- source: location ? { ...source, location } : source,
7172
+ source,
7173
+ ...location ? { location } : void 0,
7285
7174
  destination,
7286
7175
  publishExternally: shouldPublishExternally2(
7287
7176
  options.publishExternally
7288
7177
  ),
7289
- ...destinationVisibility ? { destinationVisibility } : void 0,
7290
7178
  surface: options.execution?.surface ?? "slack",
7291
7179
  dispatch: options.execution?.dispatch,
7292
7180
  toolChannelId,
@@ -7313,10 +7201,7 @@ function createSlackTurn(deps) {
7313
7201
  });
7314
7202
  }
7315
7203
  },
7316
- delivery: {
7317
- ...location && shouldPublishExternally2(options.publishExternally) ? { location } : void 0,
7318
- send: deliverAssistantMessage
7319
- },
7204
+ delivery: deliverAssistantMessage,
7320
7205
  durability: {
7321
7206
  onInputCommitted: options.ack,
7322
7207
  drainSteeringMessages,
@@ -7738,11 +7623,6 @@ async function persistConversationVisionCache(conversationId, vision) {
7738
7623
 
7739
7624
  // src/chat/runtime/conversation-message.ts
7740
7625
  var NON_TEXT_MESSAGE_TEXT = "[non-text message]";
7741
- function resourceEventType(entry) {
7742
- if (!entry.raw || typeof entry.raw !== "object") return void 0;
7743
- const raw = entry.raw;
7744
- return raw.event_type === "resource_event" && typeof raw.resource_event_type === "string" ? raw.resource_event_type : void 0;
7745
- }
7746
7626
  function resolveMessageText(args) {
7747
7627
  const text = normalizeConversationText(args.text);
7748
7628
  return text || NON_TEXT_MESSAGE_TEXT;
@@ -7767,7 +7647,6 @@ function toConversationMessage(args) {
7767
7647
  },
7768
7648
  meta: {
7769
7649
  attachmentCount: args.entry.attachments.length,
7770
- eventType: resourceEventType(args.entry),
7771
7650
  explicitMention: args.explicitMention,
7772
7651
  imageAttachmentCount: imageAttachmentCount > 0 ? imageAttachmentCount : void 0,
7773
7652
  imagesHydrated: !messageHasPotentialImageAttachment,
@@ -7937,14 +7816,14 @@ function createPrepareTurnState(deps) {
7937
7816
  }
7938
7817
 
7939
7818
  // src/chat/slack/dispatch-turn.ts
7940
- import { Message as Message5, ThreadImpl as ThreadImpl4 } from "chat";
7819
+ import { Message as Message4, ThreadImpl as ThreadImpl3 } from "chat";
7941
7820
  function createSlackDispatchTurnRunner(options) {
7942
7821
  return async function runSlackDispatchTurn(dispatch2, hooks) {
7943
7822
  const state = getStateAdapter();
7944
7823
  await state.connect();
7945
7824
  const conversationId = getDispatchConversationId(dispatch2);
7946
7825
  const adapter = options.getSlackAdapter();
7947
- const message = new Message5({
7826
+ const message = new Message4({
7948
7827
  id: getDispatchInputMessageId(dispatch2.id),
7949
7828
  threadId: conversationId,
7950
7829
  text: dispatch2.input,
@@ -7967,7 +7846,7 @@ function createSlackDispatchTurnRunner(options) {
7967
7846
  }
7968
7847
  });
7969
7848
  message.isMention = true;
7970
- const thread = new ThreadImpl4({
7849
+ const thread = new ThreadImpl3({
7971
7850
  adapter,
7972
7851
  stateAdapter: state,
7973
7852
  id: conversationId,
@@ -8400,6 +8279,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8400
8279
  return false;
8401
8280
  }
8402
8281
  const activeTurn = turn;
8282
+ const { dispatch: dispatch2, surface } = options.routingContext ?? {};
8403
8283
  const currentState = await getPersistedThreadState(
8404
8284
  payload.conversationId
8405
8285
  );
@@ -8408,7 +8288,7 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8408
8288
  conversation,
8409
8289
  conversationId: payload.conversationId
8410
8290
  });
8411
- const dispatchId = activeTurn.dispatchId ?? options.routingContext?.dispatch?.id;
8291
+ const dispatchId = activeTurn.dispatchId ?? dispatch2?.id;
8412
8292
  const dispatchUserMessage = dispatchId ? conversation.messages.find(
8413
8293
  (message) => message.role === "user" && options.inputMessageIds?.includes(message.id)
8414
8294
  ) : void 0;
@@ -8451,21 +8331,19 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8451
8331
  const routingDestination = routing.destination;
8452
8332
  const turnMessages = activeTurn.turnStartMessageIndex === void 0 ? [] : activeTurn.piMessages.slice(activeTurn.turnStartMessageIndex);
8453
8333
  const recordDispatchOutcome = async (dispatchOutcome) => {
8454
- const dispatchId2 = options.routingContext?.dispatch?.id;
8455
- if (!dispatchId2) {
8334
+ if (!dispatch2) {
8456
8335
  return;
8457
8336
  }
8458
8337
  await recordTurnSummary({
8459
8338
  conversationId: payload.conversationId,
8460
8339
  destination: routingDestination,
8461
- destinationVisibility: options.routingContext?.destinationVisibility,
8462
- dispatchId: dispatchId2,
8340
+ dispatchId: dispatch2.id,
8463
8341
  dispatchOutcome,
8464
8342
  turnId: payload.turnId,
8465
8343
  sliceId: activeTurn.sliceId,
8466
8344
  source,
8467
8345
  state: "failed",
8468
- surface: options.routingContext?.surface ?? "slack"
8346
+ surface: surface ?? "slack"
8469
8347
  });
8470
8348
  };
8471
8349
  return {
@@ -8481,21 +8359,24 @@ async function runPausedTurnInContext(payload, options, runOptions) {
8481
8359
  ...getTurnUserReplyAttachmentContext(userMessage),
8482
8360
  text: userMessage.text
8483
8361
  },
8484
- // Pi history is SQL-authoritative: the resumed run reads its
8485
- // exact dispatch session so unrelated conversation input cannot
8486
- // gain system authority. Interactive turns retain their merged
8487
- // 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.
8488
8365
  history: dispatchId ? activeTurn.piMessages : await loadProjection({
8489
8366
  conversationId: payload.conversationId
8490
8367
  }),
8491
- ...options.routingContext,
8492
- credentialContext,
8493
8368
  actor,
8369
+ credentialContext,
8494
8370
  destination: routingDestination,
8371
+ ...dispatch2 ? { dispatch: dispatch2 } : void 0,
8372
+ ...routing.location ? { location: routing.location } : void 0,
8495
8373
  // Slack resume publishes unless the checkpoint opted out.
8496
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.
8497
8377
  publishExternally: activeTurn.publishExternally !== false,
8498
8378
  source,
8379
+ ...surface ? { surface } : void 0,
8499
8380
  toolChannelId: destination.channelId,
8500
8381
  environment: {
8501
8382
  locationConfiguration
@@ -8709,30 +8590,794 @@ async function runNextPausedTurnInContext(conversationId, options, runOptions) {
8709
8590
  return false;
8710
8591
  }
8711
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
+
8712
9351
  // src/chat/app/conversation-work.ts
8713
9352
  function createConversationWork(options) {
8714
- const apiTurnCancellation = createApiTurnCancellation();
8715
9353
  const pausedTurns = createPausedTurns({
8716
9354
  conversationStore: options.conversationStore,
8717
9355
  queue: options.queue,
8718
9356
  ...options.state ? { state: options.state } : void 0
8719
9357
  });
8720
- const runtime = createSlackRuntime({
9358
+ const baseRuntime = createSlackRuntime({
8721
9359
  getSlackAdapter: options.getSlackAdapter,
8722
9360
  pausedTurns,
9361
+ ...options.sendPluginTask ? { sendPluginTask: options.sendPluginTask } : void 0,
8723
9362
  services: {
8724
9363
  ...options.services,
8725
9364
  agentRunner: options.agentRunner
8726
9365
  }
8727
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;
8728
9371
  const slackWorker = createSlackConversationWorker({
8729
9372
  getSlackAdapter: options.getSlackAdapter,
8730
- conversationStore: options.conversationStore,
8731
9373
  runNextPausedTurn: async (conversationId, runOptions) => await runNextPausedTurn(
8732
9374
  conversationId,
8733
9375
  {
8734
9376
  agentRunner: options.agentRunner,
8735
- wakePausedTurn: pausedTurns.wake
9377
+ wakePausedTurn: pausedTurns.wake,
9378
+ ...scheduleCompletedPluginTasks ? {
9379
+ scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
9380
+ } : void 0
8736
9381
  },
8737
9382
  runOptions
8738
9383
  ),
@@ -8747,13 +9392,24 @@ function createConversationWork(options) {
8747
9392
  agentRunner: options.agentRunner,
8748
9393
  inputMessageIds: [getDispatchInputMessageId(dispatch2.id)],
8749
9394
  routingContext: buildDispatchRoutingContext(dispatch2),
8750
- wakePausedTurn: pausedTurns.wake
9395
+ wakePausedTurn: pausedTurns.wake,
9396
+ ...scheduleCompletedPluginTasks ? {
9397
+ scheduleSessionCompletedPluginTasks: scheduleCompletedPluginTasks
9398
+ } : void 0
8751
9399
  },
8752
9400
  { shouldYield: hooks.shouldYield }
8753
9401
  );
8754
9402
  },
8755
9403
  runTurn: runtime.runDispatchTurn
8756
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
+ );
8757
9413
  const destinationWorker = async (context) => {
8758
9414
  const destination = context.destination;
8759
9415
  if (!destination) {
@@ -8768,24 +9424,25 @@ function createConversationWork(options) {
8768
9424
  `Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`
8769
9425
  );
8770
9426
  };
8771
- const providerWorker = createAgentDispatchWorkRouter({
8772
- dispatchWorker,
8773
- fallbackWorker: destinationWorker
8774
- });
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
+ };
8775
9442
  return {
8776
- apiTurnCancellation,
8777
9443
  conversationStore: options.conversationStore,
8778
9444
  queue: options.queue,
8779
- run: routeApiTurnWork({
8780
- apiTurnWorker: createApiTurnWorker(
8781
- options.agentRunner,
8782
- apiTurnCancellation
8783
- ),
8784
- fallbackWorker: routeAgentInvocationWork({
8785
- invocationWorker: createAgentInvocationWorker(options.agentRunner),
8786
- fallbackWorker: providerWorker
8787
- })
8788
- }),
9445
+ run,
8789
9446
  runtime,
8790
9447
  state: options.state
8791
9448
  };
@@ -8865,7 +9522,7 @@ async function publicArtifactGET(args) {
8865
9522
  }
8866
9523
 
8867
9524
  // src/chat/event-tasks/ingest.ts
8868
- import { createHash } from "crypto";
9525
+ import { createHash as createHash2 } from "crypto";
8869
9526
  import {
8870
9527
  createSlackSource as createSlackSource3,
8871
9528
  RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
@@ -8873,7 +9530,7 @@ import {
8873
9530
  resourceEventSchema
8874
9531
  } from "@sentry/junior-plugin-api";
8875
9532
  function eventTaskDispatchKey(taskId, namespace, eventKey) {
8876
- 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)}`;
8877
9534
  }
8878
9535
  function oneLine(value) {
8879
9536
  return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 512);
@@ -9014,8 +9671,8 @@ function createResourceEventAppPublisher(args) {
9014
9671
  };
9015
9672
  }
9016
9673
 
9017
- // src/chat/api-turns/stop.ts
9018
- async function stopApiConversationTurn(args) {
9674
+ // src/chat/conversations/stop.ts
9675
+ async function stopConversationTurn(args) {
9019
9676
  const nowMs = args.nowMs ?? Date.now();
9020
9677
  const stop = async () => await stopConversationWork({
9021
9678
  conversationId: args.conversationId,
@@ -9024,7 +9681,7 @@ async function stopApiConversationTurn(args) {
9024
9681
  state: args.state
9025
9682
  });
9026
9683
  let result = await stop();
9027
- if (result.status === "no_work" && await getAuthPausedApiTurnId(args.conversationId)) {
9684
+ if (result.status === "no_work" && await getAuthPausedConversationTurnId(args.conversationId)) {
9028
9685
  const conversation = await getConversation({
9029
9686
  conversationId: args.conversationId,
9030
9687
  state: args.state
@@ -9042,7 +9699,7 @@ async function stopApiConversationTurn(args) {
9042
9699
  await ensureConversationWake({
9043
9700
  conversationId: args.conversationId,
9044
9701
  conversationStore: args.conversationStore,
9045
- idempotencyKey: `api-stop:${args.conversationId}:${result.runId}`,
9702
+ idempotencyKey: `conversation-stop:${args.conversationId}:${result.runId}`,
9046
9703
  nowMs,
9047
9704
  queue: args.queue,
9048
9705
  replaceExistingWake: true,
@@ -9096,7 +9753,7 @@ function createAcpConversations(options) {
9096
9753
  if (!await hasConversationAccess(conversationId, user)) {
9097
9754
  return "not_found";
9098
9755
  }
9099
- await stopApiConversationTurn({
9756
+ await stopConversationTurn({
9100
9757
  conversationId,
9101
9758
  conversationStore: options.conversationStore,
9102
9759
  queue: options.queue,
@@ -9105,7 +9762,7 @@ function createAcpConversations(options) {
9105
9762
  return "cancelled";
9106
9763
  },
9107
9764
  async create({ conversationId, user }) {
9108
- await recordApiConversationActivity({
9765
+ await recordWebConversationActivity({
9109
9766
  actor: actorFromUser(user),
9110
9767
  conversationId,
9111
9768
  conversationStore: options.conversationStore,
@@ -9124,10 +9781,10 @@ function createAcpConversations(options) {
9124
9781
  options.eventStore,
9125
9782
  conversationId
9126
9783
  );
9127
- if (await getAuthPausedApiTurnId(conversationId)) {
9784
+ if (await getAuthPausedConversationTurnId(conversationId)) {
9128
9785
  return { status: "active" };
9129
9786
  }
9130
- const admission = await appendAndEnqueueApiConversationMessage(
9787
+ const result = await appendAndEnqueueWebMessage(
9131
9788
  {
9132
9789
  actor: actorFromUser(user),
9133
9790
  conversationId,
@@ -9141,12 +9798,12 @@ function createAcpConversations(options) {
9141
9798
  state: options.state
9142
9799
  }
9143
9800
  );
9144
- if (admission.status === "active") return { status: "active" };
9801
+ if (result.status === "active") return { status: "active" };
9145
9802
  return {
9146
- afterCursor: admission.status === "duplicate" ? 0 : currentCursor,
9147
- messageId: admission.messageId,
9803
+ afterCursor: result.status === "duplicate" ? 0 : currentCursor,
9804
+ messageId: result.messageId,
9148
9805
  status: "accepted",
9149
- turnId: apiTurnIdForMessage(admission.messageId)
9806
+ turnId: conversationTurnIdForMessage(result.messageId)
9150
9807
  };
9151
9808
  },
9152
9809
  async readMessages(conversationId) {
@@ -9204,12 +9861,12 @@ function createAcpConversations(options) {
9204
9861
  }
9205
9862
 
9206
9863
  // src/api/acp/route.ts
9207
- import { createHash as createHash4 } from "crypto";
9864
+ import { createHash as createHash5 } from "crypto";
9208
9865
  import * as acp4 from "@agentclientprotocol/sdk";
9209
9866
 
9210
9867
  // src/api/acp/auth.ts
9211
9868
  import {
9212
- createHash as createHash3,
9869
+ createHash as createHash4,
9213
9870
  randomBytes,
9214
9871
  randomUUID as randomUUID2,
9215
9872
  timingSafeEqual as timingSafeEqual3
@@ -9254,7 +9911,7 @@ async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
9254
9911
  }
9255
9912
 
9256
9913
  // src/api/acp/transport.ts
9257
- import { createHash as createHash2, randomUUID } from "crypto";
9914
+ import { createHash as createHash3, randomUUID } from "crypto";
9258
9915
  import * as acp2 from "@agentclientprotocol/sdk";
9259
9916
  import { userSchema } from "@sentry/junior-plugin-api";
9260
9917
  import { z as z7 } from "zod";
@@ -9434,8 +10091,8 @@ var acpRequestReceiptSchema = z7.object({
9434
10091
  sessionId: z7.string().min(1).optional()
9435
10092
  }).strict();
9436
10093
  var acpStreamCursorSchema = z7.object({ itemId: z7.string().min(1) }).strict();
9437
- function stableHex(value) {
9438
- 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);
9439
10096
  }
9440
10097
  function connectionKey(connectionId) {
9441
10098
  return `junior:acp:v1:connection:${connectionId}`;
@@ -9450,7 +10107,7 @@ function connectionLockKey(connectionId) {
9450
10107
  return `${connectionKey(connectionId)}:lock`;
9451
10108
  }
9452
10109
  function streamKey(route) {
9453
- const suffix = route.sessionId ? `session:${stableHex(route.sessionId)}` : "connection";
10110
+ const suffix = route.sessionId ? `session:${stableHex2(route.sessionId)}` : "connection";
9454
10111
  return `${connectionKey(route.connectionId)}:stream:${suffix}`;
9455
10112
  }
9456
10113
  function streamListKey(route) {
@@ -9466,7 +10123,7 @@ function streamAppendLockKey(route) {
9466
10123
  return `${streamKey(route)}:append`;
9467
10124
  }
9468
10125
  function requestStreamItemId(requestKey2, index) {
9469
- return `acp-item:${stableHex(`${requestKey2}:${index}`)}`;
10126
+ return `acp-item:${stableHex2(`${requestKey2}:${index}`)}`;
9470
10127
  }
9471
10128
  function parseStreamItem(value) {
9472
10129
  return storedAcpStreamItemSchema.parse(value);
@@ -10075,7 +10732,7 @@ function authorizationPointerLockKey(connectionId) {
10075
10732
  return `${authorizationPointerKey(connectionId)}:lock`;
10076
10733
  }
10077
10734
  function credentialHash(value) {
10078
- return createHash3("sha256").update(value).digest("hex");
10735
+ return createHash4("sha256").update(value).digest("hex");
10079
10736
  }
10080
10737
  function createUserCode() {
10081
10738
  const value = randomBytes(6).toString("hex").toUpperCase();
@@ -10539,8 +11196,8 @@ function promptText(prompt) {
10539
11196
  }
10540
11197
  return text;
10541
11198
  }
10542
- function stableHex2(value, length = 32) {
10543
- 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);
10544
11201
  }
10545
11202
  function canonicalJson(value) {
10546
11203
  if (Array.isArray(value)) return value.map(canonicalJson);
@@ -10550,11 +11207,11 @@ function canonicalJson(value) {
10550
11207
  );
10551
11208
  }
10552
11209
  function requestKey(call) {
10553
- 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))}`;
10554
11211
  const payload = JSON.stringify(
10555
11212
  canonicalJson({ method: call.method, params: call.params ?? null })
10556
11213
  );
10557
- return `${id}:${stableHex2(payload)}`;
11214
+ return `${id}:${stableHex3(payload)}`;
10558
11215
  }
10559
11216
  function sessionIdFromCall(call) {
10560
11217
  if (!call) return void 0;
@@ -10607,7 +11264,7 @@ async function createSession(args) {
10607
11264
  args.call.params
10608
11265
  );
10609
11266
  rejectUnsupportedMcpServers(params.mcpServers);
10610
- const sessionId = `${ACP_CONVERSATION_PREFIX}${stableHex2(
11267
+ const sessionId = `${ACP_CONVERSATION_PREFIX}${stableHex3(
10611
11268
  `${args.connection.nonce}:${args.requestKey}`
10612
11269
  )}`;
10613
11270
  await args.conversations.create({
@@ -10621,16 +11278,16 @@ async function acceptPrompt(args) {
10621
11278
  promptParamsSchema,
10622
11279
  args.call.params
10623
11280
  );
10624
- const admission = await args.conversations.prompt({
11281
+ const result = await args.conversations.prompt({
10625
11282
  conversationId: params.sessionId,
10626
11283
  idempotencyKey: `${args.connection.nonce}:${args.requestKey}`,
10627
11284
  text: promptText(params.prompt),
10628
11285
  user: args.user
10629
11286
  });
10630
- if (admission.status === "not_found") {
11287
+ if (result.status === "not_found") {
10631
11288
  throw acp4.RequestError.resourceNotFound(params.sessionId);
10632
11289
  }
10633
- if (admission.status === "active") {
11290
+ if (result.status === "active") {
10634
11291
  throw acp4.RequestError.invalidParams(
10635
11292
  { field: "sessionId" },
10636
11293
  "This ACP session already has an active prompt"
@@ -10638,11 +11295,11 @@ async function acceptPrompt(args) {
10638
11295
  }
10639
11296
  return {
10640
11297
  output: {
10641
- afterSeq: admission.afterCursor,
11298
+ afterSeq: result.afterCursor,
10642
11299
  kind: "prompt",
10643
- messageId: admission.messageId,
11300
+ messageId: result.messageId,
10644
11301
  requestId: args.requestId,
10645
- turnId: admission.turnId
11302
+ turnId: result.turnId
10646
11303
  },
10647
11304
  sessionId: params.sessionId
10648
11305
  };