@sentry/junior 0.137.0 → 0.138.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.
- package/dist/{agent-hooks-MZOKEP3J.js → agent-hooks-SCR74Q3E.js} +11 -9
- package/dist/api.js +21 -18
- package/dist/app.d.ts +7 -0
- package/dist/app.js +248 -689
- package/dist/{catalog-runtime-MD66YLFV.js → catalog-runtime-IU3QF4GG.js} +5 -5
- package/dist/chat/agent/request.d.ts +32 -2
- package/dist/chat/agent-dispatch/heartbeat.d.ts +5 -0
- package/dist/chat/agent-dispatch/types.d.ts +1 -1
- package/dist/chat/agent-invocations/errors.d.ts +8 -0
- package/dist/chat/agent-invocations/spawn.d.ts +12 -0
- package/dist/chat/agent-invocations/store.d.ts +44 -0
- package/dist/chat/agent-invocations/types.d.ts +449 -0
- package/dist/chat/agent-invocations/work.d.ts +31 -0
- package/dist/chat/config.d.ts +1 -0
- package/dist/chat/conversations/sql/store.d.ts +8 -0
- package/dist/chat/conversations/store.d.ts +7 -0
- package/dist/chat/experimental.d.ts +16 -0
- package/dist/chat/runtime/agent-runner.d.ts +2 -1
- package/dist/chat/services/auth-pause.d.ts +0 -1
- package/dist/chat/services/mcp-auth-orchestration.d.ts +3 -2
- package/dist/chat/services/plugin-auth-orchestration.d.ts +3 -2
- package/dist/chat/state/turn-session.d.ts +0 -2
- package/dist/chat/task-execution/state.d.ts +23 -11
- package/dist/chat/task-execution/store.d.ts +20 -11
- package/dist/chat/task-execution/worker.d.ts +2 -2
- package/dist/chat/tools/runtime/spawn-agent.d.ts +31 -0
- package/dist/chat/tools/types.d.ts +2 -0
- package/dist/chunk-3Y47VMHV.js +6 -0
- package/dist/chunk-5IDFPCON.js +46 -0
- package/dist/chunk-5LTJ4ITU.js +1523 -0
- package/dist/{chunk-WPPXIAFB.js → chunk-5MXWHTCK.js} +17 -434
- package/dist/{chunk-UOXATPSI.js → chunk-A7WCHXZV.js} +7 -5
- package/dist/{chunk-5G34IEK2.js → chunk-BOLJOV5T.js} +2 -56
- package/dist/{chunk-UG6ZYPBI.js → chunk-BYW4B4PR.js} +73 -60
- package/dist/{chunk-XZ7NPXAB.js → chunk-C7ZVPO4Z.js} +1 -1
- package/dist/{chunk-RB4NJKEX.js → chunk-DCLLQGS6.js} +119 -50
- package/dist/{chunk-DQXAAVTR.js → chunk-E5UYAIKJ.js} +44 -1467
- package/dist/{chunk-6QW2RRQT.js → chunk-ELKW5FIB.js} +5 -5
- package/dist/chunk-EM225ITJ.js +56 -0
- package/dist/{chunk-SYCX4DOK.js → chunk-FEUNPTGV.js} +7 -60
- package/dist/{chunk-YRPC6MJY.js → chunk-FNLBTB4K.js} +1 -1
- package/dist/chunk-HIWJWWMT.js +668 -0
- package/dist/chunk-IUFM5JWV.js +24 -0
- package/dist/{chunk-T6Z5S6PQ.js → chunk-JNNJZURV.js} +1 -1
- package/dist/{chunk-6ZK6FZIV.js → chunk-KCBZSJRU.js} +6 -27
- package/dist/{chunk-5PNJMOY5.js → chunk-KDCHVT25.js} +1 -1
- package/dist/{chunk-BZAMASJP.js → chunk-KFRHRSCJ.js} +1 -1
- package/dist/chunk-LPVUNO2W.js +320 -0
- package/dist/{chunk-EWDSB24B.js → chunk-N7WARMC6.js} +16 -776
- package/dist/chunk-PB3CXNVL.js +41 -0
- package/dist/chunk-Q6QZTTLS.js +55 -0
- package/dist/{chunk-36EG34YI.js → chunk-QS527AV5.js} +1 -1
- package/dist/chunk-R776HKPK.js +81 -0
- package/dist/{chunk-KJ4HGRHN.js → chunk-RZIBSCYC.js} +507 -596
- package/dist/chunk-SD3OFRWY.js +714 -0
- package/dist/{chunk-ZFS67WIR.js → chunk-SIPKWSXK.js} +57 -6
- package/dist/chunk-TCS76X5D.js +441 -0
- package/dist/{chunk-K2NCQJKH.js → chunk-TDJCLNDH.js} +3 -3
- package/dist/{chunk-POBSY47Q.js → chunk-TUUDXEXU.js} +336 -302
- package/dist/{chunk-YNFERGKP.js → chunk-VPZFVJND.js} +1 -1
- package/dist/{chunk-UZQ4VY3M.js → chunk-YU5QUF67.js} +1 -1
- package/dist/chunk-ZBSMCXKV.js +710 -0
- package/dist/{chunk-3Q342EJJ.js → chunk-ZXNTJJIE.js} +2 -2
- package/dist/cli/chat.js +65 -26
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +14 -12
- package/dist/cli/snapshot-create.js +10 -9
- package/dist/cli/upgrade.js +7 -7
- package/dist/conversation-work-KATFHLG3.js +56 -0
- package/dist/db/schema/agent-invocations.d.ts +544 -0
- package/dist/db/schema.d.ts +543 -1
- package/dist/{db-66E7VDNC.js → db-UO2IWXGA.js} +7 -7
- package/dist/experimental-HH6OM6UH.js +13 -0
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +4 -3
- package/dist/{oauth-callback-server-7QPD4Q7P.js → oauth-callback-server-MAQI43LX.js} +26 -18
- package/dist/{runner-L2BKJKOD.js → runner-PIUQEXKE.js} +26 -14
- package/dist/{skills-HOQ2NSPW.js → skills-4ARJADHQ.js} +6 -6
- package/dist/spawn-G2AWPMCT.js +38 -0
- package/dist/{validation-ENHI7S2C.js → validation-S3EE3HWL.js} +6 -6
- package/dist/version.js +1 -1
- package/dist/work-UARRUAW3.js +46 -0
- package/dist/worker-DOCIRVD3.js +24 -0
- package/migrations/0021_first_warhawk.sql +35 -0
- package/migrations/meta/0021_snapshot.json +2176 -0
- package/migrations/meta/_journal.json +8 -1
- package/package.json +5 -5
package/dist/app.js
CHANGED
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
processConversationWork
|
|
3
|
+
} from "./chunk-HIWJWWMT.js";
|
|
4
|
+
import {
|
|
5
|
+
bindSpawnAgent
|
|
6
|
+
} from "./chunk-PB3CXNVL.js";
|
|
7
|
+
import {
|
|
8
|
+
createAgentInvocationWorker,
|
|
9
|
+
enqueueAgentInvocation,
|
|
10
|
+
listPendingAgentInvocationMailboxAppends,
|
|
11
|
+
routeAgentInvocationWork
|
|
12
|
+
} from "./chunk-ZBSMCXKV.js";
|
|
13
|
+
import {
|
|
4
14
|
GET as GET2,
|
|
5
15
|
GET2 as GET3,
|
|
6
16
|
ResumeTurnBusyError,
|
|
7
|
-
ackMessages,
|
|
8
|
-
appendAndEnqueueInboundMessage,
|
|
9
|
-
beginConversationResume,
|
|
10
17
|
buildAuthPauseResponse,
|
|
11
18
|
buildSlackOutputMessage,
|
|
12
|
-
checkInConversationWork,
|
|
13
|
-
clearConsumedConversationWake,
|
|
14
|
-
clearExpiredConversationLease,
|
|
15
|
-
completeConversationWork,
|
|
16
|
-
countPendingConversationMessages,
|
|
17
19
|
createSlackAdapterAssistantStatusSession,
|
|
18
|
-
deadLetterAttempt,
|
|
19
|
-
drainConversationMailbox,
|
|
20
|
-
ensureConversationWake,
|
|
21
20
|
getAssistantThreadContext,
|
|
22
21
|
getAwaitingAgentContinueRequest,
|
|
23
22
|
getChannelId,
|
|
24
|
-
getConversationWorkState,
|
|
25
23
|
getMessageTs,
|
|
26
24
|
getRunId,
|
|
27
25
|
getSlackApiErrorCode,
|
|
@@ -29,31 +27,32 @@ import {
|
|
|
29
27
|
getThreadId,
|
|
30
28
|
getThreadTs,
|
|
31
29
|
getTurnRequestDeadline,
|
|
32
|
-
hasRunnableConversationWork,
|
|
33
|
-
isFinalAttempt,
|
|
34
|
-
isInvalidConversationRecordError,
|
|
35
30
|
isRetryableSlackPostError,
|
|
36
31
|
isSlackTitlePermissionError,
|
|
37
|
-
listActiveConversationIds,
|
|
38
32
|
publishAppHomeView,
|
|
39
33
|
receiveLocalOAuthCredential,
|
|
40
|
-
recordAttemptFailure,
|
|
41
|
-
releaseConversationWork,
|
|
42
|
-
removeActiveConversation,
|
|
43
|
-
requestConversationContinuation,
|
|
44
34
|
resumeSlackTurn,
|
|
45
35
|
runWithTurnRequestDeadline,
|
|
46
36
|
scheduleAgentContinue,
|
|
47
37
|
sendSlackReply,
|
|
48
38
|
shouldKeepProcessingReactionForToolInvocation,
|
|
49
39
|
splitSlackReplyText,
|
|
50
|
-
startConversationWork,
|
|
51
40
|
startSlackProcessingReaction,
|
|
52
41
|
stripLeadingBotMention
|
|
53
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-E5UYAIKJ.js";
|
|
54
43
|
import "./chunk-FA6POGLH.js";
|
|
55
44
|
import {
|
|
56
|
-
|
|
45
|
+
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
46
|
+
appendAndEnqueueInboundMessage,
|
|
47
|
+
clearExpiredConversationLease,
|
|
48
|
+
ensureConversationWake,
|
|
49
|
+
getConversationWorkState,
|
|
50
|
+
hasRunnableConversationWork,
|
|
51
|
+
isInvalidConversationRecordError,
|
|
52
|
+
listActiveConversationIds,
|
|
53
|
+
removeActiveConversation
|
|
54
|
+
} from "./chunk-5LTJ4ITU.js";
|
|
55
|
+
import {
|
|
57
56
|
buildDeliveredTurnStatePatch,
|
|
58
57
|
completeAuthPauseTurn,
|
|
59
58
|
finalizeFailedTurnReplyWithEvent,
|
|
@@ -66,24 +65,28 @@ import {
|
|
|
66
65
|
requireTurnFailureEventId,
|
|
67
66
|
resolveTurnSessionRouting,
|
|
68
67
|
scheduleSessionCompletedPluginTasks
|
|
69
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-FEUNPTGV.js";
|
|
69
|
+
import {
|
|
70
|
+
ConversationTurnLifecycleService
|
|
71
|
+
} from "./chunk-Q6QZTTLS.js";
|
|
70
72
|
import {
|
|
71
73
|
GET,
|
|
72
74
|
conversationVisibilityFromSlackChannelType,
|
|
73
75
|
recordTaskExecution,
|
|
74
76
|
resolveSlackChannelTypeFromMessage,
|
|
75
77
|
resolveSlackConversationContext
|
|
76
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-ELKW5FIB.js";
|
|
77
79
|
import "./chunk-4CODA7P5.js";
|
|
78
80
|
import "./chunk-UTL3MHPC.js";
|
|
79
81
|
import {
|
|
80
|
-
ConversationQueueMessageRejectedError,
|
|
81
|
-
conversationQueueMessageSchema,
|
|
82
82
|
getVercelConversationWorkQueue,
|
|
83
|
-
isConversationQueueMessageRejectedError,
|
|
84
83
|
resolveConversationWorkQueueTopic,
|
|
85
84
|
verifyConversationQueueMessage
|
|
86
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-KCBZSJRU.js";
|
|
86
|
+
import {
|
|
87
|
+
conversationQueueMessageSchema,
|
|
88
|
+
isConversationQueueMessageRejectedError
|
|
89
|
+
} from "./chunk-IUFM5JWV.js";
|
|
87
90
|
import {
|
|
88
91
|
PLUGIN_TASK_QUEUE_TOPIC,
|
|
89
92
|
createVercelQueueClient,
|
|
@@ -92,7 +95,7 @@ import {
|
|
|
92
95
|
import {
|
|
93
96
|
validatePluginEgressCredentialHooks,
|
|
94
97
|
validatePluginRegistrations
|
|
95
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-YU5QUF67.js";
|
|
96
99
|
import {
|
|
97
100
|
defineJuniorPlugins,
|
|
98
101
|
pluginCatalogConfigFromEnv,
|
|
@@ -100,8 +103,6 @@ import {
|
|
|
100
103
|
pluginRuntimeRegistrationsFromPluginSet
|
|
101
104
|
} from "./chunk-FIANEE7Z.js";
|
|
102
105
|
import {
|
|
103
|
-
AuthorizationFlowDisabledError,
|
|
104
|
-
PluginCredentialFailureError,
|
|
105
106
|
SANDBOX_EGRESS_PROXY_PATH,
|
|
106
107
|
appendSlackLegacyAttachmentText,
|
|
107
108
|
buildSteeringPiMessage,
|
|
@@ -127,22 +128,29 @@ import {
|
|
|
127
128
|
setConfigDefaults,
|
|
128
129
|
shouldEmitDevAgentTrace,
|
|
129
130
|
shouldPropagateSandboxEgressTrace
|
|
130
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-RZIBSCYC.js";
|
|
132
|
+
import {
|
|
133
|
+
AuthorizationFlowDisabledError,
|
|
134
|
+
PluginCredentialFailureError
|
|
135
|
+
} from "./chunk-LPVUNO2W.js";
|
|
131
136
|
import "./chunk-DIB4GX3G.js";
|
|
132
137
|
import {
|
|
133
|
-
RetryableDeliveryError,
|
|
134
138
|
createUserTokenStore,
|
|
135
139
|
deleteMcpAuthSessionsForUserProvider,
|
|
136
140
|
deleteMcpServerSessionId,
|
|
137
|
-
deleteMcpStoredOAuthCredentials
|
|
141
|
+
deleteMcpStoredOAuthCredentials
|
|
142
|
+
} from "./chunk-N7WARMC6.js";
|
|
143
|
+
import {
|
|
144
|
+
RetryableDeliveryError
|
|
145
|
+
} from "./chunk-R776HKPK.js";
|
|
146
|
+
import {
|
|
138
147
|
formatProviderLabel,
|
|
139
148
|
postSlackMessage,
|
|
140
149
|
startOAuthFlow
|
|
141
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-SD3OFRWY.js";
|
|
142
151
|
import {
|
|
143
152
|
ConversationTurnBoundaryError,
|
|
144
153
|
CooperativeTurnYieldError,
|
|
145
|
-
JUNIOR_THREAD_STATE_TTL_MS,
|
|
146
154
|
TurnInputCommitLostError,
|
|
147
155
|
TurnInputDeferredError,
|
|
148
156
|
abandonAgentTurnSessionRecord,
|
|
@@ -195,47 +203,56 @@ import {
|
|
|
195
203
|
trimTrailingAssistantMessages,
|
|
196
204
|
updateConversationStats,
|
|
197
205
|
upsertConversationMessage
|
|
198
|
-
} from "./chunk-
|
|
206
|
+
} from "./chunk-TUUDXEXU.js";
|
|
207
|
+
import {
|
|
208
|
+
JUNIOR_THREAD_STATE_TTL_MS
|
|
209
|
+
} from "./chunk-3Y47VMHV.js";
|
|
199
210
|
import "./chunk-EPBBYMNE.js";
|
|
211
|
+
import {
|
|
212
|
+
getExperimentalFeatures,
|
|
213
|
+
setExperimentalFeatures
|
|
214
|
+
} from "./chunk-5IDFPCON.js";
|
|
200
215
|
import {
|
|
201
216
|
getSandboxResourceConfig,
|
|
202
217
|
setSandboxResourceConfig
|
|
203
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-A7WCHXZV.js";
|
|
204
219
|
import {
|
|
205
220
|
createSchedulerSqlStore,
|
|
206
221
|
findMatchingEventTasks
|
|
207
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-TDJCLNDH.js";
|
|
208
223
|
import {
|
|
209
224
|
parseSlackThreadId
|
|
210
|
-
} from "./chunk-
|
|
225
|
+
} from "./chunk-FNLBTB4K.js";
|
|
211
226
|
import "./chunk-CDQ4YIZM.js";
|
|
212
227
|
import "./chunk-PDO5BLNM.js";
|
|
213
228
|
import "./chunk-UIE3R5XU.js";
|
|
214
229
|
import {
|
|
215
|
-
SlackActionError,
|
|
216
230
|
bindEventTaskCredentialSubject,
|
|
217
231
|
bindScheduledTaskCredentialSubject,
|
|
218
232
|
bindSlackDirectCredentialSubject,
|
|
219
233
|
createPluginLogger,
|
|
220
234
|
createPluginState,
|
|
221
235
|
createResourceEventTeamIdResolver,
|
|
222
|
-
downloadPrivateSlackFile,
|
|
223
236
|
getPluginApiRoutes,
|
|
224
237
|
getPluginRoutes,
|
|
225
238
|
getPlugins,
|
|
226
|
-
getSlackClient,
|
|
227
|
-
getWorkspaceTeamId,
|
|
228
|
-
isDmChannel,
|
|
229
|
-
normalizeSlackConversationId,
|
|
230
|
-
runWithSlackInstallationToken,
|
|
231
|
-
runWithWorkspaceTeamId,
|
|
232
239
|
setDashboardConversationLinkOptions,
|
|
233
240
|
setPlugins,
|
|
234
241
|
validatePlugins,
|
|
235
242
|
verifyEventTaskCredentialSubject,
|
|
236
243
|
verifyScheduledTaskCredentialSubject,
|
|
237
244
|
verifySlackDirectCredentialSubject
|
|
238
|
-
} from "./chunk-
|
|
245
|
+
} from "./chunk-5MXWHTCK.js";
|
|
246
|
+
import {
|
|
247
|
+
SlackActionError,
|
|
248
|
+
downloadPrivateSlackFile,
|
|
249
|
+
getSlackClient,
|
|
250
|
+
getWorkspaceTeamId,
|
|
251
|
+
isDmChannel,
|
|
252
|
+
normalizeSlackConversationId,
|
|
253
|
+
runWithSlackInstallationToken,
|
|
254
|
+
runWithWorkspaceTeamId
|
|
255
|
+
} from "./chunk-TCS76X5D.js";
|
|
239
256
|
import {
|
|
240
257
|
contextProvenance,
|
|
241
258
|
createSlackDestination,
|
|
@@ -245,17 +262,22 @@ import {
|
|
|
245
262
|
getSqlExecutor,
|
|
246
263
|
instructionProvenanceFor,
|
|
247
264
|
requireSlackDestination,
|
|
248
|
-
withConversationEventLock
|
|
249
|
-
|
|
265
|
+
withConversationEventLock,
|
|
266
|
+
withConversationMutationLock
|
|
267
|
+
} from "./chunk-SIPKWSXK.js";
|
|
250
268
|
import {
|
|
269
|
+
juniorAgentBindings,
|
|
270
|
+
juniorAgentInvocations,
|
|
251
271
|
juniorConversationEvents,
|
|
252
272
|
juniorConversations
|
|
253
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-DCLLQGS6.js";
|
|
254
274
|
import {
|
|
255
|
-
acquireActiveLock,
|
|
256
|
-
getStateAdapter,
|
|
257
275
|
sleep
|
|
258
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-EM225ITJ.js";
|
|
277
|
+
import {
|
|
278
|
+
acquireActiveLock,
|
|
279
|
+
getStateAdapter
|
|
280
|
+
} from "./chunk-BOLJOV5T.js";
|
|
259
281
|
import {
|
|
260
282
|
STANDARD_MODEL_PROFILE,
|
|
261
283
|
botConfig,
|
|
@@ -273,16 +295,16 @@ import {
|
|
|
273
295
|
modelIdForProfile,
|
|
274
296
|
setSlackReactionConfig,
|
|
275
297
|
standardModelId
|
|
276
|
-
} from "./chunk-
|
|
298
|
+
} from "./chunk-BYW4B4PR.js";
|
|
277
299
|
import {
|
|
278
300
|
juniorDestinations
|
|
279
301
|
} from "./chunk-VFUK3X5B.js";
|
|
280
|
-
import "./chunk-
|
|
281
|
-
import "./chunk-
|
|
302
|
+
import "./chunk-VPZFVJND.js";
|
|
303
|
+
import "./chunk-ZXNTJJIE.js";
|
|
282
304
|
import {
|
|
283
305
|
pluginCatalogRuntime
|
|
284
|
-
} from "./chunk-
|
|
285
|
-
import "./chunk-
|
|
306
|
+
} from "./chunk-QS527AV5.js";
|
|
307
|
+
import "./chunk-KFRHRSCJ.js";
|
|
286
308
|
import {
|
|
287
309
|
credentialSubjectSchema
|
|
288
310
|
} from "./chunk-77VDLF3Z.js";
|
|
@@ -314,7 +336,7 @@ import {
|
|
|
314
336
|
withContext,
|
|
315
337
|
withLogContext,
|
|
316
338
|
withSpan
|
|
317
|
-
} from "./chunk-
|
|
339
|
+
} from "./chunk-JNNJZURV.js";
|
|
318
340
|
import {
|
|
319
341
|
continueTrace
|
|
320
342
|
} from "./chunk-6GWA276C.js";
|
|
@@ -322,10 +344,10 @@ import "./chunk-OOUNJNMR.js";
|
|
|
322
344
|
import "./chunk-H4HBKISO.js";
|
|
323
345
|
import {
|
|
324
346
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
|
|
325
|
-
} from "./chunk-
|
|
347
|
+
} from "./chunk-KDCHVT25.js";
|
|
326
348
|
import {
|
|
327
349
|
JUNIOR_VERSION
|
|
328
|
-
} from "./chunk-
|
|
350
|
+
} from "./chunk-C7ZVPO4Z.js";
|
|
329
351
|
import "./chunk-MLKGABMK.js";
|
|
330
352
|
|
|
331
353
|
// src/app.ts
|
|
@@ -1020,7 +1042,7 @@ function createAgentDispatchConversationWorker(options) {
|
|
|
1020
1042
|
`Dispatch ${dispatch2.id} belongs to ${expectedConversationId}, not ${context.conversationId}`
|
|
1021
1043
|
);
|
|
1022
1044
|
}
|
|
1023
|
-
if (context.destination.platform !== dispatch2.destination.platform || context.destination.teamId !== dispatch2.destination.teamId || context.destination.channelId !== dispatch2.destination.channelId) {
|
|
1045
|
+
if (!context.destination || context.destination.platform !== dispatch2.destination.platform || context.destination.teamId !== dispatch2.destination.teamId || context.destination.channelId !== dispatch2.destination.channelId) {
|
|
1024
1046
|
throw new Error(
|
|
1025
1047
|
`Dispatch ${dispatch2.id} destination does not match its conversation lease`
|
|
1026
1048
|
);
|
|
@@ -1159,6 +1181,10 @@ function heartbeatIdempotencyKey(reason, conversationId, nowMs) {
|
|
|
1159
1181
|
return `heartbeat:${reason}:${conversationId}:${nowMs}`;
|
|
1160
1182
|
}
|
|
1161
1183
|
async function recoverConversationWork(args) {
|
|
1184
|
+
if (!getChatConfig().conversationWorkEnabled) {
|
|
1185
|
+
logWarn("conversation.work.recovery.disabled");
|
|
1186
|
+
return { expiredLeaseCount: 0, pendingCount: 0 };
|
|
1187
|
+
}
|
|
1162
1188
|
const result = {
|
|
1163
1189
|
expiredLeaseCount: 0,
|
|
1164
1190
|
pendingCount: 0
|
|
@@ -1203,12 +1229,24 @@ async function recoverConversationWork(args) {
|
|
|
1203
1229
|
return;
|
|
1204
1230
|
}
|
|
1205
1231
|
if (work.execution.lease && work.execution.lease.expiresAtMs <= args.nowMs) {
|
|
1206
|
-
const
|
|
1232
|
+
const recovery = await clearExpiredConversationLease({
|
|
1207
1233
|
conversationId,
|
|
1208
1234
|
nowMs: args.nowMs,
|
|
1209
1235
|
state: args.state
|
|
1210
1236
|
});
|
|
1211
|
-
if (
|
|
1237
|
+
if (recovery === "not_expired") {
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
if (recovery === "stopped") {
|
|
1241
|
+
logException(
|
|
1242
|
+
new Error("Conversation work stopped after repeated failed attempts"),
|
|
1243
|
+
"conversation.work.retry.exhausted",
|
|
1244
|
+
{
|
|
1245
|
+
"app.run.id": work.execution.runId ?? "unknown",
|
|
1246
|
+
"app.worker.last_progress_at_ms": work.execution.lastProgressAtMs ?? work.createdAtMs,
|
|
1247
|
+
"app.worker.retry_count": (work.execution.retryCount ?? 0) + 1
|
|
1248
|
+
}
|
|
1249
|
+
);
|
|
1212
1250
|
return;
|
|
1213
1251
|
}
|
|
1214
1252
|
const wake2 = await ensureConversationWake({
|
|
@@ -1765,6 +1803,7 @@ async function runScheduledTaskHeartbeat(args) {
|
|
|
1765
1803
|
var DEFAULT_PLUGIN_LIMIT = 25;
|
|
1766
1804
|
var PLUGIN_HEARTBEAT_TIMEOUT_MS = 25e3;
|
|
1767
1805
|
var DISPATCH_MAILBOX_APPEND_LIMIT = 100;
|
|
1806
|
+
var AGENT_INVOCATION_MAILBOX_APPEND_LIMIT = 100;
|
|
1768
1807
|
async function runWithTimeout(promise, timeoutMs) {
|
|
1769
1808
|
let timeout;
|
|
1770
1809
|
try {
|
|
@@ -1851,6 +1890,23 @@ async function recoverPendingDispatchMailboxAppends(args) {
|
|
|
1851
1890
|
}
|
|
1852
1891
|
}
|
|
1853
1892
|
}
|
|
1893
|
+
async function recoverPendingAgentInvocationMailboxAppends(args) {
|
|
1894
|
+
const invocations = await listPendingAgentInvocationMailboxAppends(
|
|
1895
|
+
AGENT_INVOCATION_MAILBOX_APPEND_LIMIT
|
|
1896
|
+
);
|
|
1897
|
+
for (const invocation of invocations) {
|
|
1898
|
+
try {
|
|
1899
|
+
await enqueueAgentInvocation(invocation, {
|
|
1900
|
+
nowMs: args.nowMs,
|
|
1901
|
+
queue: args.conversationWorkQueue
|
|
1902
|
+
});
|
|
1903
|
+
} catch (error) {
|
|
1904
|
+
logException(error, "agent.invocation.mailbox.append_recovery.failed", {
|
|
1905
|
+
"app.agent.invocation_id": invocation.invocationId
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1854
1910
|
async function runHeartbeat(args) {
|
|
1855
1911
|
const queue = args.conversationWorkQueue ?? getVercelConversationWorkQueue();
|
|
1856
1912
|
await recoverConversationWork({
|
|
@@ -1861,6 +1917,10 @@ async function runHeartbeat(args) {
|
|
|
1861
1917
|
conversationWorkQueue: queue,
|
|
1862
1918
|
nowMs: args.nowMs
|
|
1863
1919
|
});
|
|
1920
|
+
await recoverPendingAgentInvocationMailboxAppends({
|
|
1921
|
+
conversationWorkQueue: queue,
|
|
1922
|
+
nowMs: args.nowMs
|
|
1923
|
+
});
|
|
1864
1924
|
try {
|
|
1865
1925
|
const dispatchCount = await runScheduledTaskHeartbeat({
|
|
1866
1926
|
conversationWorkQueue: queue,
|
|
@@ -1919,7 +1979,7 @@ async function GET4(request, waitUntil, options = {}) {
|
|
|
1919
1979
|
import { timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
1920
1980
|
|
|
1921
1981
|
// src/chat/conversations/sql/purge.ts
|
|
1922
|
-
import { and, asc, eq as eq2, inArray, isNull, sql } from "drizzle-orm";
|
|
1982
|
+
import { and, asc, eq as eq2, inArray, isNull, or, sql } from "drizzle-orm";
|
|
1923
1983
|
|
|
1924
1984
|
// src/chat/conversations/sql/privacy.ts
|
|
1925
1985
|
import { eq } from "drizzle-orm";
|
|
@@ -2010,6 +2070,16 @@ async function selectExpiredRoots(executor, args) {
|
|
|
2010
2070
|
select 1 from junior_conversation_events events
|
|
2011
2071
|
where events.conversation_id = tree.conversation_id
|
|
2012
2072
|
)
|
|
2073
|
+
or exists (
|
|
2074
|
+
select 1 from junior_agent_invocations invocations
|
|
2075
|
+
where invocations.parent_conversation_id = tree.conversation_id
|
|
2076
|
+
or invocations.child_conversation_id = tree.conversation_id
|
|
2077
|
+
)
|
|
2078
|
+
or exists (
|
|
2079
|
+
select 1 from junior_agent_bindings bindings
|
|
2080
|
+
where bindings.parent_conversation_id = tree.conversation_id
|
|
2081
|
+
or bindings.child_conversation_id = tree.conversation_id
|
|
2082
|
+
)
|
|
2013
2083
|
or (
|
|
2014
2084
|
${juniorDestinations.visibility} is distinct from 'public'
|
|
2015
2085
|
and exists (
|
|
@@ -2045,69 +2115,85 @@ async function selectExpiredRoots(executor, args) {
|
|
|
2045
2115
|
}));
|
|
2046
2116
|
}
|
|
2047
2117
|
async function purgeConversationTree(executor, args) {
|
|
2048
|
-
return await
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
}).from(juniorConversations).where(
|
|
2074
|
-
eq2(juniorConversations.conversationId, args.rootConversationId)
|
|
2075
|
-
).for("update");
|
|
2076
|
-
const root = roots[0];
|
|
2077
|
-
if (!root || args.retention && root.parentConversationId !== null) {
|
|
2078
|
-
return { purged: false, conversations: 0 };
|
|
2079
|
-
}
|
|
2080
|
-
const resolvedScrubMetadata = args.scrubMetadataFromRootVisibility ? (await resolveRootVisibility(executor, args.rootConversationId)).visibility !== "public" : args.scrubMetadata;
|
|
2081
|
-
const destinations = root.destinationId ? await executor.db().select({ visibility: juniorDestinations.visibility }).from(juniorDestinations).where(eq2(juniorDestinations.id, root.destinationId)).for("share") : [];
|
|
2082
|
-
const isPublic = destinations[0]?.visibility === "public";
|
|
2083
|
-
const ids = tree.map((conversation) => conversation.conversationId);
|
|
2084
|
-
if (args.retention) {
|
|
2085
|
-
const currentActivity = await executor.db().select({
|
|
2118
|
+
return await withConversationMutationLock(
|
|
2119
|
+
executor,
|
|
2120
|
+
args.rootConversationId,
|
|
2121
|
+
async () => {
|
|
2122
|
+
const initialRoots = await executor.db().select({
|
|
2123
|
+
conversationId: juniorConversations.conversationId,
|
|
2124
|
+
parentConversationId: juniorConversations.parentConversationId
|
|
2125
|
+
}).from(juniorConversations).where(eq2(juniorConversations.conversationId, args.rootConversationId));
|
|
2126
|
+
const initialRoot = initialRoots[0];
|
|
2127
|
+
if (!initialRoot || args.retention && initialRoot.parentConversationId !== null) {
|
|
2128
|
+
return { purged: false, conversations: 0 };
|
|
2129
|
+
}
|
|
2130
|
+
const tree = await discoverConversationTree(executor, initialRoot);
|
|
2131
|
+
return await withConversationEventLock(
|
|
2132
|
+
executor,
|
|
2133
|
+
args.rootConversationId,
|
|
2134
|
+
async () => {
|
|
2135
|
+
for (const conversation of tree.slice(1)) {
|
|
2136
|
+
await withConversationEventLock(
|
|
2137
|
+
executor,
|
|
2138
|
+
conversation.conversationId,
|
|
2139
|
+
async () => void 0
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
const roots = await executor.db().select({
|
|
2086
2143
|
conversationId: juniorConversations.conversationId,
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2144
|
+
destinationId: juniorConversations.destinationId,
|
|
2145
|
+
parentConversationId: juniorConversations.parentConversationId
|
|
2146
|
+
}).from(juniorConversations).where(
|
|
2147
|
+
eq2(juniorConversations.conversationId, args.rootConversationId)
|
|
2148
|
+
).for("update");
|
|
2149
|
+
const root = roots[0];
|
|
2150
|
+
if (!root || args.retention && root.parentConversationId !== null) {
|
|
2090
2151
|
return { purged: false, conversations: 0 };
|
|
2091
2152
|
}
|
|
2092
|
-
const
|
|
2093
|
-
const
|
|
2094
|
-
|
|
2095
|
-
|
|
2153
|
+
const resolvedScrubMetadata = args.scrubMetadataFromRootVisibility ? (await resolveRootVisibility(executor, args.rootConversationId)).visibility !== "public" : args.scrubMetadata;
|
|
2154
|
+
const destinations = root.destinationId ? await executor.db().select({ visibility: juniorDestinations.visibility }).from(juniorDestinations).where(eq2(juniorDestinations.id, root.destinationId)).for("share") : [];
|
|
2155
|
+
const isPublic = destinations[0]?.visibility === "public";
|
|
2156
|
+
const ids = tree.map((conversation) => conversation.conversationId);
|
|
2157
|
+
if (args.retention) {
|
|
2158
|
+
const currentActivity = await executor.db().select({
|
|
2159
|
+
conversationId: juniorConversations.conversationId,
|
|
2160
|
+
lastActivityAt: juniorConversations.lastActivityAt
|
|
2161
|
+
}).from(juniorConversations).where(inArray(juniorConversations.conversationId, ids));
|
|
2162
|
+
if (currentActivity.length !== ids.length) {
|
|
2163
|
+
return { purged: false, conversations: 0 };
|
|
2164
|
+
}
|
|
2165
|
+
const windowMs = isPublic ? args.retention.publicWindowMs : args.retention.privateWindowMs;
|
|
2166
|
+
const effectiveLastActivityAt = Math.max(
|
|
2167
|
+
...currentActivity.map(
|
|
2168
|
+
(conversation) => conversation.lastActivityAt.getTime()
|
|
2169
|
+
)
|
|
2170
|
+
);
|
|
2171
|
+
if (effectiveLastActivityAt >= args.nowMs - windowMs) {
|
|
2172
|
+
return { purged: false, conversations: 0 };
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
await executor.db().delete(juniorConversationEvents).where(inArray(juniorConversationEvents.conversationId, ids));
|
|
2176
|
+
await executor.db().delete(juniorAgentInvocations).where(
|
|
2177
|
+
or(
|
|
2178
|
+
inArray(juniorAgentInvocations.parentConversationId, ids),
|
|
2179
|
+
inArray(juniorAgentInvocations.childConversationId, ids)
|
|
2096
2180
|
)
|
|
2097
2181
|
);
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2182
|
+
await executor.db().delete(juniorAgentBindings).where(
|
|
2183
|
+
or(
|
|
2184
|
+
inArray(juniorAgentBindings.parentConversationId, ids),
|
|
2185
|
+
inArray(juniorAgentBindings.childConversationId, ids)
|
|
2186
|
+
)
|
|
2187
|
+
);
|
|
2188
|
+
await executor.db().update(juniorConversations).set({
|
|
2189
|
+
transcriptPurgedAt: new Date(args.nowMs),
|
|
2190
|
+
...(args.retention ? !isPublic : resolvedScrubMetadata) ? { title: null, channelName: null, actor: null } : {}
|
|
2191
|
+
}).where(inArray(juniorConversations.conversationId, ids));
|
|
2192
|
+
return { purged: true, conversations: ids.length };
|
|
2101
2193
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
...(args.retention ? !isPublic : resolvedScrubMetadata) ? { title: null, channelName: null, actor: null } : {}
|
|
2106
|
-
}).where(inArray(juniorConversations.conversationId, ids));
|
|
2107
|
-
return { purged: true, conversations: ids.length };
|
|
2108
|
-
}
|
|
2109
|
-
);
|
|
2110
|
-
});
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
);
|
|
2111
2197
|
}
|
|
2112
2198
|
|
|
2113
2199
|
// src/chat/conversations/retention.ts
|
|
@@ -2219,9 +2305,9 @@ function buildJwksUrl(value) {
|
|
|
2219
2305
|
return url;
|
|
2220
2306
|
}
|
|
2221
2307
|
async function getJwks(issuer) {
|
|
2222
|
-
const
|
|
2308
|
+
const now = Date.now();
|
|
2223
2309
|
const cached = jwksByIssuer.get(issuer);
|
|
2224
|
-
if (cached && cached.expiresAtMs >
|
|
2310
|
+
if (cached && cached.expiresAtMs > now) {
|
|
2225
2311
|
return cached.jwks;
|
|
2226
2312
|
}
|
|
2227
2313
|
if (cached) {
|
|
@@ -2246,7 +2332,7 @@ async function getJwks(issuer) {
|
|
|
2246
2332
|
}
|
|
2247
2333
|
jwksByIssuer.set(issuer, {
|
|
2248
2334
|
jwks,
|
|
2249
|
-
expiresAtMs:
|
|
2335
|
+
expiresAtMs: now + OIDC_DISCOVERY_CACHE_TTL_MS
|
|
2250
2336
|
});
|
|
2251
2337
|
return jwks;
|
|
2252
2338
|
}
|
|
@@ -3352,7 +3438,7 @@ function createSlackConversationWorker(options) {
|
|
|
3352
3438
|
if (route === "mention") {
|
|
3353
3439
|
await options.runtime.handleNewMention(thread, latestMessage, {
|
|
3354
3440
|
conversationId: context.conversationId,
|
|
3355
|
-
destination
|
|
3441
|
+
destination,
|
|
3356
3442
|
messageContext,
|
|
3357
3443
|
drainSteeringMessages,
|
|
3358
3444
|
ack,
|
|
@@ -3365,7 +3451,7 @@ function createSlackConversationWorker(options) {
|
|
|
3365
3451
|
latestMessage,
|
|
3366
3452
|
{
|
|
3367
3453
|
conversationId: context.conversationId,
|
|
3368
|
-
destination
|
|
3454
|
+
destination,
|
|
3369
3455
|
messageContext,
|
|
3370
3456
|
drainSteeringMessages,
|
|
3371
3457
|
ack,
|
|
@@ -4251,555 +4337,6 @@ import {
|
|
|
4251
4337
|
handleCallback,
|
|
4252
4338
|
registerDevConsumer
|
|
4253
4339
|
} from "@vercel/queue";
|
|
4254
|
-
|
|
4255
|
-
// src/chat/task-execution/worker.ts
|
|
4256
|
-
var CONVERSATION_WORK_DEFER_DELAY_MS = 15e3;
|
|
4257
|
-
function now(options) {
|
|
4258
|
-
return options.nowMs?.() ?? Date.now();
|
|
4259
|
-
}
|
|
4260
|
-
function selectContiguousActorBatch(messages) {
|
|
4261
|
-
const first = messages[0];
|
|
4262
|
-
if (!first) {
|
|
4263
|
-
return [];
|
|
4264
|
-
}
|
|
4265
|
-
const nextActorIndex = messages.findIndex(
|
|
4266
|
-
(message) => message.input.authorId !== first.input.authorId
|
|
4267
|
-
);
|
|
4268
|
-
return messages.slice(
|
|
4269
|
-
0,
|
|
4270
|
-
nextActorIndex === -1 ? messages.length : nextActorIndex
|
|
4271
|
-
);
|
|
4272
|
-
}
|
|
4273
|
-
function selectAttemptMessages(work) {
|
|
4274
|
-
const messages = work.messages;
|
|
4275
|
-
const interrupts = messages.filter(
|
|
4276
|
-
(message) => message.delivery === "interrupt"
|
|
4277
|
-
);
|
|
4278
|
-
if (interrupts.length > 0) {
|
|
4279
|
-
return selectContiguousActorBatch(interrupts);
|
|
4280
|
-
}
|
|
4281
|
-
return work.execution.status === "awaiting_resume" ? [] : selectContiguousActorBatch(messages);
|
|
4282
|
-
}
|
|
4283
|
-
function nudgeIdempotencyKey(reason, conversationId, nowMs) {
|
|
4284
|
-
return `${reason}:${conversationId}:${nowMs}`;
|
|
4285
|
-
}
|
|
4286
|
-
async function requestLostLeaseRecovery(args) {
|
|
4287
|
-
const resumeRequested = await requestConversationContinuation({
|
|
4288
|
-
conversationId: args.conversationId,
|
|
4289
|
-
destination: args.destination,
|
|
4290
|
-
leaseToken: args.leaseToken,
|
|
4291
|
-
conversationStore: args.options.conversationStore,
|
|
4292
|
-
nowMs: args.nowMs,
|
|
4293
|
-
state: args.options.state
|
|
4294
|
-
});
|
|
4295
|
-
if (!resumeRequested) {
|
|
4296
|
-
return;
|
|
4297
|
-
}
|
|
4298
|
-
const released = await releaseConversationWork({
|
|
4299
|
-
conversationId: args.conversationId,
|
|
4300
|
-
leaseToken: args.leaseToken,
|
|
4301
|
-
conversationStore: args.options.conversationStore,
|
|
4302
|
-
nowMs: args.nowMs,
|
|
4303
|
-
state: args.options.state
|
|
4304
|
-
});
|
|
4305
|
-
if (!released) {
|
|
4306
|
-
return;
|
|
4307
|
-
}
|
|
4308
|
-
await ensureConversationWake({
|
|
4309
|
-
conversationId: args.conversationId,
|
|
4310
|
-
conversationStore: args.options.conversationStore,
|
|
4311
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
4312
|
-
"lost_lease",
|
|
4313
|
-
args.conversationId,
|
|
4314
|
-
args.nowMs
|
|
4315
|
-
),
|
|
4316
|
-
nowMs: args.nowMs,
|
|
4317
|
-
queue: args.options.queue,
|
|
4318
|
-
replaceExistingWake: true,
|
|
4319
|
-
state: args.options.state
|
|
4320
|
-
});
|
|
4321
|
-
}
|
|
4322
|
-
async function recordFailedDeliveryAttempt(args) {
|
|
4323
|
-
const failure = await recordAttemptFailure({
|
|
4324
|
-
conversationId: args.conversationId,
|
|
4325
|
-
inboundMessageIds: args.messageIds,
|
|
4326
|
-
leaseToken: args.leaseToken,
|
|
4327
|
-
conversationStore: args.options.conversationStore,
|
|
4328
|
-
nowMs: args.nowMs,
|
|
4329
|
-
state: args.options.state
|
|
4330
|
-
});
|
|
4331
|
-
for (const message of failure.deadLetteredMessages) {
|
|
4332
|
-
logWarn("conversation.work.dead_lettered", {
|
|
4333
|
-
"app.conversation.source": message.source,
|
|
4334
|
-
"app.inbound.attempt_count": message.attemptCount ?? 0,
|
|
4335
|
-
"app.inbound.message_id": message.inboundMessageId,
|
|
4336
|
-
"app.inbound.pending_count": failure.pendingCount
|
|
4337
|
-
});
|
|
4338
|
-
}
|
|
4339
|
-
return failure;
|
|
4340
|
-
}
|
|
4341
|
-
function isTerminalFailure(failure) {
|
|
4342
|
-
return failure.status === "recorded" && failure.deadLetteredMessages.length > 0 && failure.pendingCount === 0;
|
|
4343
|
-
}
|
|
4344
|
-
function startLeaseCheckIn(args) {
|
|
4345
|
-
const timer = setInterval(() => {
|
|
4346
|
-
const nowMs = now(args.options);
|
|
4347
|
-
void checkInConversationWork({
|
|
4348
|
-
conversationId: args.conversationId,
|
|
4349
|
-
leaseToken: args.leaseToken,
|
|
4350
|
-
conversationStore: args.options.conversationStore,
|
|
4351
|
-
nowMs,
|
|
4352
|
-
state: args.options.state
|
|
4353
|
-
}).then(
|
|
4354
|
-
(checkedIn) => {
|
|
4355
|
-
if (!checkedIn) {
|
|
4356
|
-
args.onLostLease();
|
|
4357
|
-
logWarn("conversation.work.check_in.failed");
|
|
4358
|
-
}
|
|
4359
|
-
},
|
|
4360
|
-
(error) => {
|
|
4361
|
-
logException(error, "conversation.work.check_in.failed");
|
|
4362
|
-
}
|
|
4363
|
-
);
|
|
4364
|
-
}, args.options.checkInIntervalMs ?? CONVERSATION_WORK_CHECK_IN_INTERVAL_MS);
|
|
4365
|
-
timer.unref?.();
|
|
4366
|
-
return timer;
|
|
4367
|
-
}
|
|
4368
|
-
async function processConversationWork(message, options) {
|
|
4369
|
-
return withLogContext(
|
|
4370
|
-
{ conversationId: message.conversationId },
|
|
4371
|
-
() => processConversationWorkInContext(message, options)
|
|
4372
|
-
);
|
|
4373
|
-
}
|
|
4374
|
-
async function processConversationWorkInContext(message, options) {
|
|
4375
|
-
const conversationId = message.conversationId;
|
|
4376
|
-
let initial;
|
|
4377
|
-
try {
|
|
4378
|
-
initial = await getConversationWorkState({
|
|
4379
|
-
conversationId,
|
|
4380
|
-
state: options.state
|
|
4381
|
-
});
|
|
4382
|
-
} catch (error) {
|
|
4383
|
-
if (isInvalidConversationRecordError(error)) {
|
|
4384
|
-
throw new ConversationQueueMessageRejectedError(
|
|
4385
|
-
"invalid_record",
|
|
4386
|
-
`Conversation record failed validation for ${conversationId}`,
|
|
4387
|
-
{ conversationId }
|
|
4388
|
-
);
|
|
4389
|
-
}
|
|
4390
|
-
throw error;
|
|
4391
|
-
}
|
|
4392
|
-
if (!initial || countPendingConversationMessages(initial) === 0 && initial.execution.status === "idle" && !initial.execution.lease) {
|
|
4393
|
-
if (initial) {
|
|
4394
|
-
await clearConsumedConversationWake({
|
|
4395
|
-
conversationId,
|
|
4396
|
-
conversationStore: options.conversationStore,
|
|
4397
|
-
nowMs: now(options),
|
|
4398
|
-
state: options.state
|
|
4399
|
-
});
|
|
4400
|
-
}
|
|
4401
|
-
return { status: "no_work" };
|
|
4402
|
-
}
|
|
4403
|
-
if (!initial.destination) {
|
|
4404
|
-
throw new ConversationQueueMessageRejectedError(
|
|
4405
|
-
"invalid_record",
|
|
4406
|
-
`Conversation work is missing destination context for ${conversationId}`,
|
|
4407
|
-
{ conversationId }
|
|
4408
|
-
);
|
|
4409
|
-
}
|
|
4410
|
-
const destination = initial.destination;
|
|
4411
|
-
const lease = await startConversationWork({
|
|
4412
|
-
conversationId,
|
|
4413
|
-
conversationStore: options.conversationStore,
|
|
4414
|
-
nowMs: now(options),
|
|
4415
|
-
state: options.state
|
|
4416
|
-
});
|
|
4417
|
-
if (lease.status === "no_work") {
|
|
4418
|
-
await clearConsumedConversationWake({
|
|
4419
|
-
conversationId,
|
|
4420
|
-
conversationStore: options.conversationStore,
|
|
4421
|
-
nowMs: now(options),
|
|
4422
|
-
state: options.state
|
|
4423
|
-
});
|
|
4424
|
-
return { status: "no_work" };
|
|
4425
|
-
}
|
|
4426
|
-
if (lease.status === "active") {
|
|
4427
|
-
const nudgeNowMs = now(options);
|
|
4428
|
-
await ensureConversationWake({
|
|
4429
|
-
conversationId,
|
|
4430
|
-
conversationStore: options.conversationStore,
|
|
4431
|
-
delayMs: CONVERSATION_WORK_DEFER_DELAY_MS,
|
|
4432
|
-
idempotencyKey: nudgeIdempotencyKey("active", conversationId, nudgeNowMs),
|
|
4433
|
-
nowMs: nudgeNowMs,
|
|
4434
|
-
queue: options.queue,
|
|
4435
|
-
replaceExistingWake: true,
|
|
4436
|
-
state: options.state
|
|
4437
|
-
});
|
|
4438
|
-
logInfo("conversation.work.nudge.deferred", {
|
|
4439
|
-
"app.lease.expires_at_ms": lease.leaseExpiresAtMs
|
|
4440
|
-
});
|
|
4441
|
-
return { status: "active" };
|
|
4442
|
-
}
|
|
4443
|
-
const startedAtMs = now(options);
|
|
4444
|
-
const softYieldDeadlineMs = startedAtMs + (options.softYieldAfterMs ?? getChatConfig().conversationWorkSoftYieldAfterMs);
|
|
4445
|
-
let attemptMessageIds = [];
|
|
4446
|
-
let attemptSelectedMessageIds = /* @__PURE__ */ new Set();
|
|
4447
|
-
let attemptStartMessageIds = /* @__PURE__ */ new Set();
|
|
4448
|
-
let leaseLost = false;
|
|
4449
|
-
const markLeaseLost = () => {
|
|
4450
|
-
leaseLost = true;
|
|
4451
|
-
};
|
|
4452
|
-
const timer = startLeaseCheckIn({
|
|
4453
|
-
conversationId,
|
|
4454
|
-
leaseToken: lease.leaseToken,
|
|
4455
|
-
onLostLease: markLeaseLost,
|
|
4456
|
-
options
|
|
4457
|
-
});
|
|
4458
|
-
logInfo("conversation.work.lease.acquired", {
|
|
4459
|
-
"app.lease.expires_at_ms": lease.leaseExpiresAtMs,
|
|
4460
|
-
"app.worker.soft_yield_deadline_ms": softYieldDeadlineMs
|
|
4461
|
-
});
|
|
4462
|
-
const drain = (handle) => drainConversationMailbox({
|
|
4463
|
-
conversationId,
|
|
4464
|
-
leaseToken: lease.leaseToken,
|
|
4465
|
-
conversationStore: options.conversationStore,
|
|
4466
|
-
handle: async (messages) => {
|
|
4467
|
-
const candidates = messages.filter(
|
|
4468
|
-
(message2) => message2.delivery === "interrupt" && (attemptSelectedMessageIds.has(message2.inboundMessageId) || !attemptStartMessageIds.has(message2.inboundMessageId))
|
|
4469
|
-
);
|
|
4470
|
-
if (candidates.length === 0) {
|
|
4471
|
-
return [];
|
|
4472
|
-
}
|
|
4473
|
-
return await handle(candidates) ?? candidates.map((message2) => message2.inboundMessageId);
|
|
4474
|
-
},
|
|
4475
|
-
nowMs: now(options),
|
|
4476
|
-
state: options.state
|
|
4477
|
-
});
|
|
4478
|
-
const shouldYield = () => leaseLost || now(options) >= softYieldDeadlineMs;
|
|
4479
|
-
const checkIn = async () => {
|
|
4480
|
-
const checkedIn = await checkInConversationWork({
|
|
4481
|
-
conversationId,
|
|
4482
|
-
leaseToken: lease.leaseToken,
|
|
4483
|
-
conversationStore: options.conversationStore,
|
|
4484
|
-
nowMs: now(options),
|
|
4485
|
-
state: options.state
|
|
4486
|
-
});
|
|
4487
|
-
if (!checkedIn) {
|
|
4488
|
-
markLeaseLost();
|
|
4489
|
-
}
|
|
4490
|
-
return checkedIn;
|
|
4491
|
-
};
|
|
4492
|
-
const yieldWork = async () => {
|
|
4493
|
-
const yieldNowMs = now(options);
|
|
4494
|
-
await ensureConversationWake({
|
|
4495
|
-
conversationId,
|
|
4496
|
-
conversationStore: options.conversationStore,
|
|
4497
|
-
idempotencyKey: nudgeIdempotencyKey("yield", conversationId, yieldNowMs),
|
|
4498
|
-
nowMs: yieldNowMs,
|
|
4499
|
-
queue: options.queue,
|
|
4500
|
-
replaceExistingWake: true,
|
|
4501
|
-
state: options.state
|
|
4502
|
-
});
|
|
4503
|
-
const released = await releaseConversationWork({
|
|
4504
|
-
conversationId,
|
|
4505
|
-
leaseToken: lease.leaseToken,
|
|
4506
|
-
conversationStore: options.conversationStore,
|
|
4507
|
-
nowMs: yieldNowMs,
|
|
4508
|
-
state: options.state
|
|
4509
|
-
});
|
|
4510
|
-
if (!released) {
|
|
4511
|
-
return { status: "lost_lease" };
|
|
4512
|
-
}
|
|
4513
|
-
logInfo("conversation.work.yielded", {
|
|
4514
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs,
|
|
4515
|
-
"app.worker.soft_yield_deadline_ms": softYieldDeadlineMs
|
|
4516
|
-
});
|
|
4517
|
-
return { status: "yielded" };
|
|
4518
|
-
};
|
|
4519
|
-
try {
|
|
4520
|
-
let hasRun = false;
|
|
4521
|
-
while (true) {
|
|
4522
|
-
attemptMessageIds = [];
|
|
4523
|
-
const leasedWork = await getConversationWorkState({
|
|
4524
|
-
conversationId,
|
|
4525
|
-
state: options.state
|
|
4526
|
-
});
|
|
4527
|
-
if (!leasedWork || leasedWork.lease?.leaseToken !== lease.leaseToken || leaseLost) {
|
|
4528
|
-
markLeaseLost();
|
|
4529
|
-
await requestLostLeaseRecovery({
|
|
4530
|
-
conversationId,
|
|
4531
|
-
destination,
|
|
4532
|
-
leaseToken: lease.leaseToken,
|
|
4533
|
-
nowMs: now(options),
|
|
4534
|
-
options
|
|
4535
|
-
});
|
|
4536
|
-
return { status: "lost_lease" };
|
|
4537
|
-
}
|
|
4538
|
-
const resumePending = leasedWork.execution.status === "awaiting_resume";
|
|
4539
|
-
const attemptMessages = selectAttemptMessages(leasedWork);
|
|
4540
|
-
attemptStartMessageIds = new Set(
|
|
4541
|
-
leasedWork.messages.map((message2) => message2.inboundMessageId)
|
|
4542
|
-
);
|
|
4543
|
-
if (hasRun && shouldYield()) {
|
|
4544
|
-
if (resumePending) {
|
|
4545
|
-
return await yieldWork();
|
|
4546
|
-
}
|
|
4547
|
-
break;
|
|
4548
|
-
}
|
|
4549
|
-
if (resumePending && attemptMessages.length === 0) {
|
|
4550
|
-
const resumeStarted = await beginConversationResume({
|
|
4551
|
-
conversationId,
|
|
4552
|
-
leaseToken: lease.leaseToken,
|
|
4553
|
-
conversationStore: options.conversationStore,
|
|
4554
|
-
nowMs: now(options),
|
|
4555
|
-
state: options.state
|
|
4556
|
-
});
|
|
4557
|
-
if (!resumeStarted) {
|
|
4558
|
-
markLeaseLost();
|
|
4559
|
-
await requestLostLeaseRecovery({
|
|
4560
|
-
conversationId,
|
|
4561
|
-
destination,
|
|
4562
|
-
leaseToken: lease.leaseToken,
|
|
4563
|
-
nowMs: now(options),
|
|
4564
|
-
options
|
|
4565
|
-
});
|
|
4566
|
-
return { status: "lost_lease" };
|
|
4567
|
-
}
|
|
4568
|
-
}
|
|
4569
|
-
attemptMessageIds = attemptMessages.map(
|
|
4570
|
-
(message2) => message2.inboundMessageId
|
|
4571
|
-
);
|
|
4572
|
-
attemptSelectedMessageIds = new Set(attemptMessageIds);
|
|
4573
|
-
const ack = async () => {
|
|
4574
|
-
const acknowledged = await ackMessages({
|
|
4575
|
-
conversationId,
|
|
4576
|
-
inboundMessageIds: attemptMessageIds,
|
|
4577
|
-
leaseToken: lease.leaseToken,
|
|
4578
|
-
conversationStore: options.conversationStore,
|
|
4579
|
-
nowMs: now(options),
|
|
4580
|
-
state: options.state
|
|
4581
|
-
});
|
|
4582
|
-
if (!acknowledged) {
|
|
4583
|
-
markLeaseLost();
|
|
4584
|
-
throw new Error(
|
|
4585
|
-
`Conversation work lease lost before inbox ack for ${conversationId}`
|
|
4586
|
-
);
|
|
4587
|
-
}
|
|
4588
|
-
};
|
|
4589
|
-
const workerContext = {
|
|
4590
|
-
attempt: {
|
|
4591
|
-
ack,
|
|
4592
|
-
conversationId,
|
|
4593
|
-
destination,
|
|
4594
|
-
drain,
|
|
4595
|
-
isFinalAttempt: attemptMessages.some(
|
|
4596
|
-
(message2) => isFinalAttempt(message2)
|
|
4597
|
-
),
|
|
4598
|
-
messages: attemptMessages
|
|
4599
|
-
},
|
|
4600
|
-
conversationId,
|
|
4601
|
-
destination,
|
|
4602
|
-
shouldYield,
|
|
4603
|
-
checkIn
|
|
4604
|
-
};
|
|
4605
|
-
const result = await options.run(workerContext);
|
|
4606
|
-
hasRun = true;
|
|
4607
|
-
if (result.status === "lost_lease") {
|
|
4608
|
-
await requestLostLeaseRecovery({
|
|
4609
|
-
conversationId,
|
|
4610
|
-
destination,
|
|
4611
|
-
leaseToken: lease.leaseToken,
|
|
4612
|
-
nowMs: now(options),
|
|
4613
|
-
options
|
|
4614
|
-
});
|
|
4615
|
-
return { status: "lost_lease" };
|
|
4616
|
-
}
|
|
4617
|
-
if (leaseLost) {
|
|
4618
|
-
await requestLostLeaseRecovery({
|
|
4619
|
-
conversationId,
|
|
4620
|
-
destination,
|
|
4621
|
-
leaseToken: lease.leaseToken,
|
|
4622
|
-
nowMs: now(options),
|
|
4623
|
-
options
|
|
4624
|
-
});
|
|
4625
|
-
return { status: "lost_lease" };
|
|
4626
|
-
}
|
|
4627
|
-
if (result.status === "yielded") {
|
|
4628
|
-
const resumeRequested = await requestConversationContinuation({
|
|
4629
|
-
conversationId,
|
|
4630
|
-
destination,
|
|
4631
|
-
leaseToken: lease.leaseToken,
|
|
4632
|
-
conversationStore: options.conversationStore,
|
|
4633
|
-
nowMs: now(options),
|
|
4634
|
-
state: options.state
|
|
4635
|
-
});
|
|
4636
|
-
if (!resumeRequested) {
|
|
4637
|
-
return { status: "lost_lease" };
|
|
4638
|
-
}
|
|
4639
|
-
return await yieldWork();
|
|
4640
|
-
}
|
|
4641
|
-
if (result.status === "deferred") {
|
|
4642
|
-
const deferredNowMs = now(options);
|
|
4643
|
-
const released = await releaseConversationWork({
|
|
4644
|
-
conversationId,
|
|
4645
|
-
leaseToken: lease.leaseToken,
|
|
4646
|
-
conversationStore: options.conversationStore,
|
|
4647
|
-
nowMs: deferredNowMs,
|
|
4648
|
-
state: options.state
|
|
4649
|
-
});
|
|
4650
|
-
if (!released) {
|
|
4651
|
-
return { status: "lost_lease" };
|
|
4652
|
-
}
|
|
4653
|
-
const wake = await ensureConversationWake({
|
|
4654
|
-
conversationId,
|
|
4655
|
-
conversationStore: options.conversationStore,
|
|
4656
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
4657
|
-
"deferred",
|
|
4658
|
-
conversationId,
|
|
4659
|
-
deferredNowMs
|
|
4660
|
-
),
|
|
4661
|
-
nowMs: deferredNowMs,
|
|
4662
|
-
queue: options.queue,
|
|
4663
|
-
state: options.state
|
|
4664
|
-
});
|
|
4665
|
-
return wake.status === "enqueued" ? { status: "pending_requeued" } : { status: "completed" };
|
|
4666
|
-
}
|
|
4667
|
-
if (attemptMessageIds.length > 0) {
|
|
4668
|
-
const failure = await recordFailedDeliveryAttempt({
|
|
4669
|
-
conversationId,
|
|
4670
|
-
leaseToken: lease.leaseToken,
|
|
4671
|
-
nowMs: now(options),
|
|
4672
|
-
messageIds: attemptMessageIds,
|
|
4673
|
-
options
|
|
4674
|
-
});
|
|
4675
|
-
if (isTerminalFailure(failure)) {
|
|
4676
|
-
await deadLetterAttempt({
|
|
4677
|
-
conversationId,
|
|
4678
|
-
leaseToken: lease.leaseToken,
|
|
4679
|
-
conversationStore: options.conversationStore,
|
|
4680
|
-
nowMs: now(options),
|
|
4681
|
-
state: options.state
|
|
4682
|
-
});
|
|
4683
|
-
return { status: "failed" };
|
|
4684
|
-
}
|
|
4685
|
-
if (failure.status === "lost_lease") {
|
|
4686
|
-
return { status: "lost_lease" };
|
|
4687
|
-
}
|
|
4688
|
-
if (failure.status === "recorded") {
|
|
4689
|
-
break;
|
|
4690
|
-
}
|
|
4691
|
-
}
|
|
4692
|
-
const next = await getConversationWorkState({
|
|
4693
|
-
conversationId,
|
|
4694
|
-
state: options.state
|
|
4695
|
-
});
|
|
4696
|
-
if (!next || next.lease?.leaseToken !== lease.leaseToken) {
|
|
4697
|
-
return { status: "lost_lease" };
|
|
4698
|
-
}
|
|
4699
|
-
if (next.execution.status !== "awaiting_resume" && countPendingConversationMessages(next) === 0) {
|
|
4700
|
-
break;
|
|
4701
|
-
}
|
|
4702
|
-
}
|
|
4703
|
-
const completion = await completeConversationWork({
|
|
4704
|
-
conversationId,
|
|
4705
|
-
leaseToken: lease.leaseToken,
|
|
4706
|
-
conversationStore: options.conversationStore,
|
|
4707
|
-
nowMs: now(options),
|
|
4708
|
-
state: options.state
|
|
4709
|
-
});
|
|
4710
|
-
if (completion === "lost_lease") {
|
|
4711
|
-
return { status: "lost_lease" };
|
|
4712
|
-
}
|
|
4713
|
-
if (completion === "pending") {
|
|
4714
|
-
const nudgeNowMs = now(options);
|
|
4715
|
-
const wake = await ensureConversationWake({
|
|
4716
|
-
conversationId,
|
|
4717
|
-
conversationStore: options.conversationStore,
|
|
4718
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
4719
|
-
"pending",
|
|
4720
|
-
conversationId,
|
|
4721
|
-
nudgeNowMs
|
|
4722
|
-
),
|
|
4723
|
-
nowMs: nudgeNowMs,
|
|
4724
|
-
queue: options.queue,
|
|
4725
|
-
state: options.state
|
|
4726
|
-
});
|
|
4727
|
-
return wake.status === "enqueued" ? { status: "pending_requeued" } : { status: "completed" };
|
|
4728
|
-
}
|
|
4729
|
-
logInfo("conversation.work.completed", {
|
|
4730
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs
|
|
4731
|
-
});
|
|
4732
|
-
return { status: "completed" };
|
|
4733
|
-
} catch (error) {
|
|
4734
|
-
const errorNowMs = now(options);
|
|
4735
|
-
let recoveryRecorded = false;
|
|
4736
|
-
try {
|
|
4737
|
-
const failure = attemptMessageIds.length > 0 ? await recordFailedDeliveryAttempt({
|
|
4738
|
-
conversationId,
|
|
4739
|
-
leaseToken: lease.leaseToken,
|
|
4740
|
-
nowMs: errorNowMs,
|
|
4741
|
-
messageIds: attemptMessageIds,
|
|
4742
|
-
options
|
|
4743
|
-
}) : void 0;
|
|
4744
|
-
if (failure && isTerminalFailure(failure)) {
|
|
4745
|
-
await deadLetterAttempt({
|
|
4746
|
-
conversationId,
|
|
4747
|
-
leaseToken: lease.leaseToken,
|
|
4748
|
-
conversationStore: options.conversationStore,
|
|
4749
|
-
nowMs: errorNowMs,
|
|
4750
|
-
state: options.state
|
|
4751
|
-
});
|
|
4752
|
-
} else {
|
|
4753
|
-
const resumeRequested = await requestConversationContinuation({
|
|
4754
|
-
conversationId,
|
|
4755
|
-
destination,
|
|
4756
|
-
leaseToken: lease.leaseToken,
|
|
4757
|
-
conversationStore: options.conversationStore,
|
|
4758
|
-
nowMs: errorNowMs,
|
|
4759
|
-
state: options.state
|
|
4760
|
-
});
|
|
4761
|
-
if (resumeRequested) {
|
|
4762
|
-
await ensureConversationWake({
|
|
4763
|
-
conversationId,
|
|
4764
|
-
conversationStore: options.conversationStore,
|
|
4765
|
-
idempotencyKey: nudgeIdempotencyKey(
|
|
4766
|
-
"error",
|
|
4767
|
-
conversationId,
|
|
4768
|
-
errorNowMs
|
|
4769
|
-
),
|
|
4770
|
-
nowMs: errorNowMs,
|
|
4771
|
-
queue: options.queue,
|
|
4772
|
-
replaceExistingWake: true,
|
|
4773
|
-
state: options.state
|
|
4774
|
-
});
|
|
4775
|
-
}
|
|
4776
|
-
await releaseConversationWork({
|
|
4777
|
-
conversationId,
|
|
4778
|
-
leaseToken: lease.leaseToken,
|
|
4779
|
-
conversationStore: options.conversationStore,
|
|
4780
|
-
nowMs: errorNowMs,
|
|
4781
|
-
state: options.state
|
|
4782
|
-
});
|
|
4783
|
-
}
|
|
4784
|
-
recoveryRecorded = true;
|
|
4785
|
-
} catch (recoveryError) {
|
|
4786
|
-
logException(recoveryError, "conversation.work.requeue.failed");
|
|
4787
|
-
}
|
|
4788
|
-
if (!isProviderRetryError(error)) {
|
|
4789
|
-
logException(error, "conversation.work.failed", {
|
|
4790
|
-
"app.worker.elapsed_ms": now(options) - startedAtMs
|
|
4791
|
-
});
|
|
4792
|
-
}
|
|
4793
|
-
if (!recoveryRecorded) {
|
|
4794
|
-
throw error;
|
|
4795
|
-
}
|
|
4796
|
-
return { status: "failed" };
|
|
4797
|
-
} finally {
|
|
4798
|
-
clearInterval(timer);
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
|
|
4802
|
-
// src/chat/task-execution/vercel-callback.ts
|
|
4803
4340
|
var CONVERSATION_WORK_VISIBILITY_TIMEOUT_BUFFER_SECONDS = 30;
|
|
4804
4341
|
var CONVERSATION_WORK_DEV_CONSUMER_GROUP = "junior_conversation_work_dev";
|
|
4805
4342
|
function parseConversationQueueMessage(message) {
|
|
@@ -4825,6 +4362,15 @@ async function processConversationQueueMessage(message, options) {
|
|
|
4825
4362
|
});
|
|
4826
4363
|
}
|
|
4827
4364
|
async function handleConversationQueueMessage(message, metadata, options) {
|
|
4365
|
+
if (!getChatConfig().conversationWorkEnabled) {
|
|
4366
|
+
logWarn("conversation.work.processing.disabled", {
|
|
4367
|
+
"app.queue.consumer_group": metadata.consumerGroup,
|
|
4368
|
+
"app.queue.delivery_count": metadata.deliveryCount,
|
|
4369
|
+
"app.queue.message_id": metadata.messageId,
|
|
4370
|
+
"app.queue.topic_name": metadata.topicName
|
|
4371
|
+
});
|
|
4372
|
+
return;
|
|
4373
|
+
}
|
|
4828
4374
|
const verification = verifyConversationQueueMessage(message);
|
|
4829
4375
|
if (verification.status === "rejected") {
|
|
4830
4376
|
logConversationQueueMessageRejected(verification.reason, metadata);
|
|
@@ -6649,14 +6195,16 @@ function createJuniorRuntimeServices(overrides = {}) {
|
|
|
6649
6195
|
listThreadReplies: overrides.visionContext?.listThreadReplies ?? listThreadReplies,
|
|
6650
6196
|
downloadFile: overrides.visionContext?.downloadFile ?? downloadPrivateSlackFile
|
|
6651
6197
|
});
|
|
6198
|
+
const agentRunner = overrides.replyExecutor?.agentRunner ?? createAgentRunner(executeAgentRun, {
|
|
6199
|
+
bindSpawnAgent: (request) => bindSpawnAgent(request, { queue: getVercelConversationWorkQueue }),
|
|
6200
|
+
tracePropagation: overrides.sandbox?.tracePropagation
|
|
6201
|
+
});
|
|
6652
6202
|
return {
|
|
6653
6203
|
conversationMemory,
|
|
6654
6204
|
contextCompactor,
|
|
6655
6205
|
replyExecutor: {
|
|
6656
6206
|
contextCompactor: overrides.replyExecutor?.contextCompactor ?? contextCompactor,
|
|
6657
|
-
agentRunner
|
|
6658
|
-
tracePropagation: overrides.sandbox?.tracePropagation
|
|
6659
|
-
}),
|
|
6207
|
+
agentRunner,
|
|
6660
6208
|
getAwaitingAgentContinueRequest: overrides.replyExecutor?.getAwaitingAgentContinueRequest ?? getAwaitingAgentContinueRequest,
|
|
6661
6209
|
lookupSlackUser: overrides.replyExecutor?.lookupSlackUser ?? lookupSlackUser,
|
|
6662
6210
|
scheduleAgentContinue: overrides.replyExecutor?.scheduleAgentContinue ?? scheduleAgentContinue,
|
|
@@ -7673,7 +7221,7 @@ function createReplyToThread(deps) {
|
|
|
7673
7221
|
policy: {
|
|
7674
7222
|
configuration: preparedState.configuration,
|
|
7675
7223
|
channelConfiguration: preparedState.channelConfiguration,
|
|
7676
|
-
|
|
7224
|
+
disabledFeatures: options.execution?.disabledFeatures ?? (message.author.isBot === true ? ["interactive-auth"] : void 0),
|
|
7677
7225
|
turnDeadlineAtMs: getTurnRequestDeadline()?.deadlineAtMs
|
|
7678
7226
|
},
|
|
7679
7227
|
state: {
|
|
@@ -8387,7 +7935,7 @@ function createSlackDispatchTurnRunner(options) {
|
|
|
8387
7935
|
conversationId,
|
|
8388
7936
|
destination: dispatch2.destination,
|
|
8389
7937
|
execution: {
|
|
8390
|
-
|
|
7938
|
+
disabledFeatures: ["interactive-auth"],
|
|
8391
7939
|
channelConfiguration: options.getChannelConfiguration(
|
|
8392
7940
|
dispatch2.destination.channelId
|
|
8393
7941
|
),
|
|
@@ -9279,12 +8827,18 @@ function createProductionConversationWorkOptions(options) {
|
|
|
9279
8827
|
},
|
|
9280
8828
|
runTurn: runtime.runDispatchTurn
|
|
9281
8829
|
});
|
|
8830
|
+
const providerWorker = createAgentDispatchWorkRouter({
|
|
8831
|
+
dispatchWorker,
|
|
8832
|
+
fallbackWorker: slackWorker
|
|
8833
|
+
});
|
|
9282
8834
|
return {
|
|
9283
8835
|
conversationStore,
|
|
9284
8836
|
queue,
|
|
9285
|
-
run:
|
|
9286
|
-
|
|
9287
|
-
|
|
8837
|
+
run: routeAgentInvocationWork({
|
|
8838
|
+
invocationWorker: createAgentInvocationWorker({
|
|
8839
|
+
agentRunner
|
|
8840
|
+
}),
|
|
8841
|
+
fallbackWorker: providerWorker
|
|
9288
8842
|
})
|
|
9289
8843
|
};
|
|
9290
8844
|
}
|
|
@@ -9815,6 +9369,7 @@ async function createApp(options) {
|
|
|
9815
9369
|
const previousConfigDefaults = getConfigDefaults();
|
|
9816
9370
|
const previousSlackReactionConfig = getSlackReactionConfig();
|
|
9817
9371
|
const previousSandboxResources = getSandboxResourceConfig();
|
|
9372
|
+
const previousExperimentalFeatures = getExperimentalFeatures();
|
|
9818
9373
|
const previousDashboardLinkOptions = setDashboardConversationLinkOptions(dashboard);
|
|
9819
9374
|
let pluginRoutes = [];
|
|
9820
9375
|
let pluginApiRoutes = [];
|
|
@@ -9850,6 +9405,7 @@ async function createApp(options) {
|
|
|
9850
9405
|
options?.sandbox?.egressTracePropagationDomains
|
|
9851
9406
|
);
|
|
9852
9407
|
setSandboxResourceConfig(options?.sandbox);
|
|
9408
|
+
setExperimentalFeatures(options?.experimental);
|
|
9853
9409
|
setConfigDefaults(options?.configDefaults);
|
|
9854
9410
|
warnUnregisteredConfigDefaults(options?.configDefaults);
|
|
9855
9411
|
if (options?.slack) {
|
|
@@ -9873,12 +9429,15 @@ async function createApp(options) {
|
|
|
9873
9429
|
setConfigDefaults(previousConfigDefaults);
|
|
9874
9430
|
setSlackReactionConfig(previousSlackReactionConfig);
|
|
9875
9431
|
setSandboxResourceConfig(previousSandboxResources);
|
|
9432
|
+
setExperimentalFeatures(previousExperimentalFeatures);
|
|
9876
9433
|
setDashboardConversationLinkOptions(previousDashboardLinkOptions);
|
|
9877
9434
|
throw error;
|
|
9878
9435
|
}
|
|
9879
9436
|
const waitUntil = options?.waitUntil ?? await defaultWaitUntil();
|
|
9880
9437
|
const tracePropagation = { domains: sandboxEgressTracePropagationDomains };
|
|
9438
|
+
const conversationWorkQueue = getVercelConversationWorkQueue();
|
|
9881
9439
|
const agentRunner = createAgentRunner(executeAgentRun, {
|
|
9440
|
+
bindSpawnAgent: (request) => bindSpawnAgent(request, { queue: conversationWorkQueue }),
|
|
9882
9441
|
tracePropagation
|
|
9883
9442
|
});
|
|
9884
9443
|
const runtimeServiceOverrides = {
|