@sentry/junior 0.138.0 → 0.139.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-SCR74Q3E.js → agent-hooks-MJXMD7JP.js} +10 -10
- package/dist/api/schema/task.d.ts +100 -1
- package/dist/api/schema.d.ts +2 -2
- package/dist/api/schema.js +9 -1
- package/dist/api.js +198 -54
- package/dist/app.js +288 -602
- package/dist/{catalog-runtime-IU3QF4GG.js → catalog-runtime-GCCFYPIK.js} +6 -6
- package/dist/chat/agent/request.d.ts +12 -2
- package/dist/chat/credentials/context.d.ts +14 -0
- package/dist/chat/resource-events/actor.d.ts +23 -0
- package/dist/chat/state/turn-session.d.ts +1 -3
- package/dist/chat/tasks/execution-stats.d.ts +34 -3
- package/dist/chat/tasks/read.d.ts +3 -1
- package/dist/{chunk-JNNJZURV.js → chunk-2ECYPYKP.js} +1 -1
- package/dist/chunk-3T2JAGRH.js +115 -0
- package/dist/{chunk-PB3CXNVL.js → chunk-4V4QIYJH.js} +1 -1
- package/dist/{chunk-FEUNPTGV.js → chunk-5GSZWRE2.js} +434 -12
- package/dist/{chunk-QS527AV5.js → chunk-6OHTDR4F.js} +1 -1
- package/dist/{chunk-TCS76X5D.js → chunk-6SU2DT27.js} +2 -2
- package/dist/{chunk-BYW4B4PR.js → chunk-75I3UBIL.js} +2 -2
- package/dist/{chunk-ZBSMCXKV.js → chunk-AEQISMMU.js} +7 -6
- package/dist/{chunk-KDCHVT25.js → chunk-C2N6MNO4.js} +9 -2
- package/dist/{chunk-KFRHRSCJ.js → chunk-CXH25EL4.js} +2 -2
- package/dist/{chunk-TDJCLNDH.js → chunk-DW4PMHNW.js} +3 -3
- package/dist/{chunk-A7WCHXZV.js → chunk-G52UXKGO.js} +4 -4
- package/dist/chunk-GI52BW74.js +207 -0
- package/dist/{chunk-ZXNTJJIE.js → chunk-GWQSZT4C.js} +2 -2
- package/dist/{chunk-EPBBYMNE.js → chunk-HUO3UTAQ.js} +1 -1
- package/dist/{chunk-5MXWHTCK.js → chunk-IIESAYDL.js} +6 -6
- package/dist/{chunk-YU5QUF67.js → chunk-J3S57AXY.js} +1 -1
- package/dist/{chunk-E5UYAIKJ.js → chunk-J6EJQCHY.js} +17 -19
- package/dist/{chunk-5LTJ4ITU.js → chunk-MQ5RYATN.js} +4 -4
- package/dist/{chunk-BOLJOV5T.js → chunk-MXTVUV3I.js} +1 -1
- package/dist/{chunk-FNLBTB4K.js → chunk-MXVD2BDS.js} +1 -1
- package/dist/{chunk-TUUDXEXU.js → chunk-PJW6U46K.js} +12 -15
- package/dist/{chunk-SIPKWSXK.js → chunk-QTBKPZDA.js} +3 -3
- package/dist/{chunk-77VDLF3Z.js → chunk-RUIXF3YQ.js} +10 -0
- package/dist/{chunk-SD3OFRWY.js → chunk-U27DSXKB.js} +6 -6
- package/dist/{chunk-C7ZVPO4Z.js → chunk-U7CMWQ7Z.js} +1 -1
- package/dist/{chunk-DCLLQGS6.js → chunk-UDBUS533.js} +8 -3
- package/dist/{chunk-HIWJWWMT.js → chunk-WQRX57EA.js} +3 -3
- package/dist/{chunk-LPVUNO2W.js → chunk-WZH4JV7R.js} +7 -7
- package/dist/{chunk-HCIVH3JS.js → chunk-YCTDA7BD.js} +28 -0
- package/dist/{chunk-VPZFVJND.js → chunk-YGZ2OLXL.js} +1 -1
- package/dist/{chunk-N7WARMC6.js → chunk-ZQCGQMF2.js} +7 -7
- package/dist/{chunk-RZIBSCYC.js → chunk-ZYQSPQYR.js} +25 -22
- package/dist/cli/chat.js +33 -33
- package/dist/cli/check.js +7 -7
- package/dist/cli/plugins.js +14 -14
- package/dist/cli/snapshot-create.js +10 -10
- package/dist/cli/upgrade.js +8 -8
- package/dist/db/schema/task-executions.d.ts +23 -2
- package/dist/db/schema.d.ts +20 -1
- package/dist/{db-UO2IWXGA.js → db-UXPPGHDF.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-MAQI43LX.js → oauth-callback-server-4ZYMD5UA.js} +22 -21
- package/dist/{runner-PIUQEXKE.js → runner-MZSEONRZ.js} +18 -16
- package/dist/{sandbox-egress-signals-A5HWIQH4.js → sandbox-egress-signals-EKPAVWQL.js} +2 -2
- package/dist/{skills-4ARJADHQ.js → skills-IMVPXSQ7.js} +7 -7
- package/dist/spawn-S5LSVOCE.js +38 -0
- package/dist/{validation-S3EE3HWL.js → validation-ZKCY2BVR.js} +7 -7
- package/dist/version.js +1 -1
- package/dist/{work-UARRUAW3.js → work-GG3XDYRX.js} +18 -18
- package/dist/{worker-DOCIRVD3.js → worker-23AUELCJ.js} +10 -10
- package/migrations/0022_task_execution_status.sql +3 -0
- package/migrations/meta/0022_snapshot.json +2186 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -5
- package/dist/chunk-ELKW5FIB.js +0 -233
- package/dist/spawn-G2AWPMCT.js +0 -38
package/dist/app.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
processConversationWork
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WQRX57EA.js";
|
|
4
4
|
import {
|
|
5
5
|
bindSpawnAgent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-4V4QIYJH.js";
|
|
7
7
|
import {
|
|
8
8
|
createAgentInvocationWorker,
|
|
9
9
|
enqueueAgentInvocation,
|
|
10
10
|
listPendingAgentInvocationMailboxAppends,
|
|
11
11
|
routeAgentInvocationWork
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-AEQISMMU.js";
|
|
13
13
|
import {
|
|
14
14
|
GET as GET2,
|
|
15
15
|
GET2 as GET3,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
splitSlackReplyText,
|
|
40
40
|
startSlackProcessingReaction,
|
|
41
41
|
stripLeadingBotMention
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-J6EJQCHY.js";
|
|
43
43
|
import "./chunk-FA6POGLH.js";
|
|
44
44
|
import {
|
|
45
45
|
CONVERSATION_WORK_STALE_ENQUEUE_MS,
|
|
@@ -51,32 +51,50 @@ import {
|
|
|
51
51
|
isInvalidConversationRecordError,
|
|
52
52
|
listActiveConversationIds,
|
|
53
53
|
removeActiveConversation
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-MQ5RYATN.js";
|
|
55
55
|
import {
|
|
56
56
|
buildDeliveredTurnStatePatch,
|
|
57
|
+
claimDispatchMailboxAppend,
|
|
57
58
|
completeAuthPauseTurn,
|
|
59
|
+
confirmDispatchMailboxAppend,
|
|
60
|
+
createOrGetDispatch,
|
|
58
61
|
finalizeFailedTurnReplyWithEvent,
|
|
59
62
|
getAgentTurnDiagnosticsAttributes,
|
|
63
|
+
getDispatchConversationId,
|
|
64
|
+
getDispatchInputMessageId,
|
|
65
|
+
getDispatchInputMessageIds,
|
|
66
|
+
getDispatchRecord,
|
|
67
|
+
getDispatchTurnId,
|
|
68
|
+
getPluginDispatchProjection,
|
|
60
69
|
getTurnUserMessage,
|
|
61
70
|
getTurnUserReplyAttachmentContext,
|
|
62
71
|
getTurnUserSlackMessageTs,
|
|
72
|
+
isTerminalDispatchStatus,
|
|
73
|
+
listPendingDispatchMailboxAppends,
|
|
74
|
+
markDispatchAwaitingResume,
|
|
75
|
+
markDispatchBlocked,
|
|
76
|
+
markDispatchCompleted,
|
|
77
|
+
markDispatchFailed,
|
|
78
|
+
markDispatchRunning,
|
|
63
79
|
persistAuthPauseTurnState,
|
|
64
80
|
processPluginTask,
|
|
65
81
|
requireTurnFailureEventId,
|
|
66
82
|
resolveTurnSessionRouting,
|
|
67
83
|
scheduleSessionCompletedPluginTasks
|
|
68
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-5GSZWRE2.js";
|
|
69
85
|
import {
|
|
70
86
|
ConversationTurnLifecycleService
|
|
71
87
|
} from "./chunk-Q6QZTTLS.js";
|
|
72
88
|
import {
|
|
73
89
|
GET,
|
|
74
90
|
conversationVisibilityFromSlackChannelType,
|
|
75
|
-
recordTaskExecution,
|
|
76
91
|
resolveSlackChannelTypeFromMessage,
|
|
77
92
|
resolveSlackConversationContext
|
|
78
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-3T2JAGRH.js";
|
|
79
94
|
import "./chunk-4CODA7P5.js";
|
|
95
|
+
import {
|
|
96
|
+
recordTaskExecution
|
|
97
|
+
} from "./chunk-GI52BW74.js";
|
|
80
98
|
import "./chunk-UTL3MHPC.js";
|
|
81
99
|
import {
|
|
82
100
|
getVercelConversationWorkQueue,
|
|
@@ -95,7 +113,7 @@ import {
|
|
|
95
113
|
import {
|
|
96
114
|
validatePluginEgressCredentialHooks,
|
|
97
115
|
validatePluginRegistrations
|
|
98
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-J3S57AXY.js";
|
|
99
117
|
import {
|
|
100
118
|
defineJuniorPlugins,
|
|
101
119
|
pluginCatalogConfigFromEnv,
|
|
@@ -128,18 +146,18 @@ import {
|
|
|
128
146
|
setConfigDefaults,
|
|
129
147
|
shouldEmitDevAgentTrace,
|
|
130
148
|
shouldPropagateSandboxEgressTrace
|
|
131
|
-
} from "./chunk-
|
|
149
|
+
} from "./chunk-ZYQSPQYR.js";
|
|
132
150
|
import {
|
|
133
151
|
AuthorizationFlowDisabledError,
|
|
134
152
|
PluginCredentialFailureError
|
|
135
|
-
} from "./chunk-
|
|
153
|
+
} from "./chunk-WZH4JV7R.js";
|
|
136
154
|
import "./chunk-DIB4GX3G.js";
|
|
137
155
|
import {
|
|
138
156
|
createUserTokenStore,
|
|
139
157
|
deleteMcpAuthSessionsForUserProvider,
|
|
140
158
|
deleteMcpServerSessionId,
|
|
141
159
|
deleteMcpStoredOAuthCredentials
|
|
142
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-ZQCGQMF2.js";
|
|
143
161
|
import {
|
|
144
162
|
RetryableDeliveryError
|
|
145
163
|
} from "./chunk-R776HKPK.js";
|
|
@@ -147,7 +165,7 @@ import {
|
|
|
147
165
|
formatProviderLabel,
|
|
148
166
|
postSlackMessage,
|
|
149
167
|
startOAuthFlow
|
|
150
|
-
} from "./chunk-
|
|
168
|
+
} from "./chunk-U27DSXKB.js";
|
|
151
169
|
import {
|
|
152
170
|
ConversationTurnBoundaryError,
|
|
153
171
|
CooperativeTurnYieldError,
|
|
@@ -203,11 +221,9 @@ import {
|
|
|
203
221
|
trimTrailingAssistantMessages,
|
|
204
222
|
updateConversationStats,
|
|
205
223
|
upsertConversationMessage
|
|
206
|
-
} from "./chunk-
|
|
207
|
-
import
|
|
208
|
-
|
|
209
|
-
} from "./chunk-3Y47VMHV.js";
|
|
210
|
-
import "./chunk-EPBBYMNE.js";
|
|
224
|
+
} from "./chunk-PJW6U46K.js";
|
|
225
|
+
import "./chunk-3Y47VMHV.js";
|
|
226
|
+
import "./chunk-HUO3UTAQ.js";
|
|
211
227
|
import {
|
|
212
228
|
getExperimentalFeatures,
|
|
213
229
|
setExperimentalFeatures
|
|
@@ -215,14 +231,14 @@ import {
|
|
|
215
231
|
import {
|
|
216
232
|
getSandboxResourceConfig,
|
|
217
233
|
setSandboxResourceConfig
|
|
218
|
-
} from "./chunk-
|
|
234
|
+
} from "./chunk-G52UXKGO.js";
|
|
219
235
|
import {
|
|
220
236
|
createSchedulerSqlStore,
|
|
221
237
|
findMatchingEventTasks
|
|
222
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-DW4PMHNW.js";
|
|
223
239
|
import {
|
|
224
240
|
parseSlackThreadId
|
|
225
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-MXVD2BDS.js";
|
|
226
242
|
import "./chunk-CDQ4YIZM.js";
|
|
227
243
|
import "./chunk-PDO5BLNM.js";
|
|
228
244
|
import "./chunk-UIE3R5XU.js";
|
|
@@ -242,7 +258,7 @@ import {
|
|
|
242
258
|
verifyEventTaskCredentialSubject,
|
|
243
259
|
verifyScheduledTaskCredentialSubject,
|
|
244
260
|
verifySlackDirectCredentialSubject
|
|
245
|
-
} from "./chunk-
|
|
261
|
+
} from "./chunk-IIESAYDL.js";
|
|
246
262
|
import {
|
|
247
263
|
SlackActionError,
|
|
248
264
|
downloadPrivateSlackFile,
|
|
@@ -252,7 +268,7 @@ import {
|
|
|
252
268
|
normalizeSlackConversationId,
|
|
253
269
|
runWithSlackInstallationToken,
|
|
254
270
|
runWithWorkspaceTeamId
|
|
255
|
-
} from "./chunk-
|
|
271
|
+
} from "./chunk-6SU2DT27.js";
|
|
256
272
|
import {
|
|
257
273
|
contextProvenance,
|
|
258
274
|
createSlackDestination,
|
|
@@ -264,20 +280,20 @@ import {
|
|
|
264
280
|
requireSlackDestination,
|
|
265
281
|
withConversationEventLock,
|
|
266
282
|
withConversationMutationLock
|
|
267
|
-
} from "./chunk-
|
|
283
|
+
} from "./chunk-QTBKPZDA.js";
|
|
268
284
|
import {
|
|
269
285
|
juniorAgentBindings,
|
|
270
286
|
juniorAgentInvocations,
|
|
271
287
|
juniorConversationEvents,
|
|
272
288
|
juniorConversations
|
|
273
|
-
} from "./chunk-
|
|
289
|
+
} from "./chunk-UDBUS533.js";
|
|
274
290
|
import {
|
|
275
291
|
sleep
|
|
276
292
|
} from "./chunk-EM225ITJ.js";
|
|
277
293
|
import {
|
|
278
294
|
acquireActiveLock,
|
|
279
295
|
getStateAdapter
|
|
280
|
-
} from "./chunk-
|
|
296
|
+
} from "./chunk-MXTVUV3I.js";
|
|
281
297
|
import {
|
|
282
298
|
STANDARD_MODEL_PROFILE,
|
|
283
299
|
botConfig,
|
|
@@ -295,19 +311,19 @@ import {
|
|
|
295
311
|
modelIdForProfile,
|
|
296
312
|
setSlackReactionConfig,
|
|
297
313
|
standardModelId
|
|
298
|
-
} from "./chunk-
|
|
314
|
+
} from "./chunk-75I3UBIL.js";
|
|
299
315
|
import {
|
|
300
316
|
juniorDestinations
|
|
301
317
|
} from "./chunk-VFUK3X5B.js";
|
|
302
|
-
import "./chunk-
|
|
303
|
-
import "./chunk-
|
|
318
|
+
import "./chunk-YGZ2OLXL.js";
|
|
319
|
+
import "./chunk-GWQSZT4C.js";
|
|
304
320
|
import {
|
|
305
321
|
pluginCatalogRuntime
|
|
306
|
-
} from "./chunk-
|
|
307
|
-
import "./chunk-
|
|
322
|
+
} from "./chunk-6OHTDR4F.js";
|
|
323
|
+
import "./chunk-CXH25EL4.js";
|
|
308
324
|
import {
|
|
309
|
-
|
|
310
|
-
} from "./chunk-
|
|
325
|
+
credentialContextForActor
|
|
326
|
+
} from "./chunk-RUIXF3YQ.js";
|
|
311
327
|
import {
|
|
312
328
|
createActor,
|
|
313
329
|
createSlackActor,
|
|
@@ -336,7 +352,7 @@ import {
|
|
|
336
352
|
withContext,
|
|
337
353
|
withLogContext,
|
|
338
354
|
withSpan
|
|
339
|
-
} from "./chunk-
|
|
355
|
+
} from "./chunk-2ECYPYKP.js";
|
|
340
356
|
import {
|
|
341
357
|
continueTrace
|
|
342
358
|
} from "./chunk-6GWA276C.js";
|
|
@@ -344,10 +360,10 @@ import "./chunk-OOUNJNMR.js";
|
|
|
344
360
|
import "./chunk-H4HBKISO.js";
|
|
345
361
|
import {
|
|
346
362
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
|
|
347
|
-
} from "./chunk-
|
|
363
|
+
} from "./chunk-C2N6MNO4.js";
|
|
348
364
|
import {
|
|
349
365
|
JUNIOR_VERSION
|
|
350
|
-
} from "./chunk-
|
|
366
|
+
} from "./chunk-U7CMWQ7Z.js";
|
|
351
367
|
import "./chunk-MLKGABMK.js";
|
|
352
368
|
|
|
353
369
|
// src/app.ts
|
|
@@ -409,400 +425,20 @@ async function verifyDispatchCallbackRequest(request) {
|
|
|
409
425
|
}
|
|
410
426
|
}
|
|
411
427
|
|
|
412
|
-
// src/chat/agent-dispatch/store.ts
|
|
413
|
-
import { createHash } from "crypto";
|
|
414
|
-
import {
|
|
415
|
-
destinationSchema,
|
|
416
|
-
destinationVisibilitySchema,
|
|
417
|
-
isSlackDestination,
|
|
418
|
-
replyAttributionSchema,
|
|
419
|
-
sourceSchema
|
|
420
|
-
} from "@sentry/junior-plugin-api";
|
|
421
|
-
import { z as z2 } from "zod";
|
|
422
|
-
var DISPATCH_PREFIX = "junior:agent_dispatch";
|
|
423
|
-
var DISPATCH_LOCK_TTL_MS = 10 * 60 * 1e3;
|
|
424
|
-
var DISPATCH_MAILBOX_APPEND_INDEX_LOCK_TTL_MS = 1e4;
|
|
425
|
-
var DISPATCH_MAILBOX_APPEND_INDEX_MAX_LENGTH = 1e4;
|
|
426
|
-
var nonEmptyExactStringSchema = z2.string().min(1).refine(
|
|
427
|
-
(value) => value === value.trim() && value.toLowerCase() !== "unknown"
|
|
428
|
-
);
|
|
429
|
-
var pendingDispatchMailboxAppendIndexSchema = z2.array(
|
|
430
|
-
nonEmptyExactStringSchema
|
|
431
|
-
);
|
|
432
|
-
var dispatchStatusSchema = z2.enum([
|
|
433
|
-
"pending",
|
|
434
|
-
"running",
|
|
435
|
-
"awaiting_resume",
|
|
436
|
-
"completed",
|
|
437
|
-
"failed",
|
|
438
|
-
"blocked"
|
|
439
|
-
]);
|
|
440
|
-
var dispatchActorSchema = z2.object({
|
|
441
|
-
platform: z2.literal("system"),
|
|
442
|
-
name: nonEmptyExactStringSchema
|
|
443
|
-
}).strict();
|
|
444
|
-
var dispatchRecordSchema = z2.object({
|
|
445
|
-
actor: dispatchActorSchema,
|
|
446
|
-
createdAtMs: z2.number().finite(),
|
|
447
|
-
credentialSubject: credentialSubjectSchema.optional(),
|
|
448
|
-
destination: destinationSchema,
|
|
449
|
-
destinationVisibility: destinationVisibilitySchema,
|
|
450
|
-
errorMessage: z2.string().optional(),
|
|
451
|
-
id: nonEmptyExactStringSchema,
|
|
452
|
-
idempotencyKey: z2.string().min(1),
|
|
453
|
-
input: z2.string().min(1),
|
|
454
|
-
metadata: z2.record(z2.string(), z2.string()).optional(),
|
|
455
|
-
plugin: nonEmptyExactStringSchema,
|
|
456
|
-
replyAttribution: replyAttributionSchema.optional(),
|
|
457
|
-
resultMessageTs: z2.string().optional(),
|
|
458
|
-
source: sourceSchema,
|
|
459
|
-
status: dispatchStatusSchema,
|
|
460
|
-
updatedAtMs: z2.number().finite()
|
|
461
|
-
}).strict().superRefine((record, ctx) => {
|
|
462
|
-
if (!isSlackDestination(record.destination)) {
|
|
463
|
-
ctx.addIssue({
|
|
464
|
-
code: z2.ZodIssueCode.custom,
|
|
465
|
-
message: "Dispatch destination platform must be slack",
|
|
466
|
-
path: ["destination"]
|
|
467
|
-
});
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
const subject = record.credentialSubject;
|
|
471
|
-
if (!subject) {
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
if (subject.allowedWhen === "private-direct-conversation") {
|
|
475
|
-
if (!record.destination.channelId.startsWith("D")) {
|
|
476
|
-
ctx.addIssue({
|
|
477
|
-
code: z2.ZodIssueCode.custom,
|
|
478
|
-
message: "Dispatch credentialSubject requires a private direct Slack destination",
|
|
479
|
-
path: ["credentialSubject"]
|
|
480
|
-
});
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
if (subject.binding.type !== "slack-direct-conversation" || subject.binding.teamId !== record.destination.teamId || subject.binding.channelId !== record.destination.channelId) {
|
|
484
|
-
ctx.addIssue({
|
|
485
|
-
code: z2.ZodIssueCode.custom,
|
|
486
|
-
message: "Dispatch credentialSubject binding must match destination",
|
|
487
|
-
path: ["credentialSubject", "binding"]
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
if (subject.binding.type !== subject.allowedWhen || subject.binding.plugin !== record.plugin || subject.binding.taskId !== subject.taskId) {
|
|
493
|
-
ctx.addIssue({
|
|
494
|
-
code: z2.ZodIssueCode.custom,
|
|
495
|
-
message: "Dispatch credentialSubject binding must match task",
|
|
496
|
-
path: ["credentialSubject", "binding"]
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
var storedDispatchRecordSchema = dispatchRecordSchema.extend({
|
|
501
|
-
attempt: z2.number().int().nonnegative().optional(),
|
|
502
|
-
lastCallbackAtMs: z2.number().finite().optional(),
|
|
503
|
-
leaseExpiresAtMs: z2.number().finite().optional(),
|
|
504
|
-
maxAttempts: z2.number().int().positive().optional(),
|
|
505
|
-
version: z2.number().int().positive().optional()
|
|
506
|
-
});
|
|
507
|
-
function getDispatchStorageKey(id) {
|
|
508
|
-
return `${DISPATCH_PREFIX}:record:${id}`;
|
|
509
|
-
}
|
|
510
|
-
function dispatchLockKey(id) {
|
|
511
|
-
return `${DISPATCH_PREFIX}:lock:${id}`;
|
|
512
|
-
}
|
|
513
|
-
function pendingDispatchMailboxAppendIndexKey() {
|
|
514
|
-
return `${DISPATCH_PREFIX}:incomplete`;
|
|
515
|
-
}
|
|
516
|
-
function pendingDispatchMailboxAppendIndexLockKey() {
|
|
517
|
-
return `${DISPATCH_PREFIX}:incomplete:lock`;
|
|
518
|
-
}
|
|
519
|
-
function normalizeMetadata(metadata) {
|
|
520
|
-
if (!metadata) {
|
|
521
|
-
return void 0;
|
|
522
|
-
}
|
|
523
|
-
const entries = Object.entries(metadata).filter(
|
|
524
|
-
(entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
|
|
525
|
-
);
|
|
526
|
-
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
527
|
-
}
|
|
528
|
-
function buildDispatchId(plugin, idempotencyKey) {
|
|
529
|
-
const digest = createHash("sha256").update(plugin).update("\0").update(idempotencyKey).digest("hex").slice(0, 32);
|
|
530
|
-
return `dispatch_${digest}`;
|
|
531
|
-
}
|
|
532
|
-
function parseDispatchRecord(value) {
|
|
533
|
-
const parsed = parseStoredDispatchRecord(value);
|
|
534
|
-
return parsed?.record;
|
|
535
|
-
}
|
|
536
|
-
function parseStoredDispatchRecord(value) {
|
|
537
|
-
const parsed = storedDispatchRecordSchema.safeParse(value);
|
|
538
|
-
if (!parsed.success) {
|
|
539
|
-
return void 0;
|
|
540
|
-
}
|
|
541
|
-
const {
|
|
542
|
-
attempt: _attempt,
|
|
543
|
-
lastCallbackAtMs: _lastCallbackAtMs,
|
|
544
|
-
leaseExpiresAtMs: _leaseExpiresAtMs,
|
|
545
|
-
maxAttempts: _maxAttempts,
|
|
546
|
-
version: _version,
|
|
547
|
-
...record
|
|
548
|
-
} = parsed.data;
|
|
549
|
-
return {
|
|
550
|
-
...typeof parsed.data.leaseExpiresAtMs === "number" ? { legacyLeaseExpiresAtMs: parsed.data.leaseExpiresAtMs } : {},
|
|
551
|
-
record
|
|
552
|
-
};
|
|
553
|
-
}
|
|
554
|
-
function getDispatchConversationId(dispatch2) {
|
|
555
|
-
return `agent-dispatch:${dispatch2.id}`;
|
|
556
|
-
}
|
|
557
|
-
function getDispatchInputMessageId(dispatchId) {
|
|
558
|
-
return `agent-dispatch:${dispatchId}`;
|
|
559
|
-
}
|
|
560
|
-
function getLegacyDispatchInputMessageId(dispatchId) {
|
|
561
|
-
return `dispatch:${dispatchId}:user`;
|
|
562
|
-
}
|
|
563
|
-
function getDispatchInputMessageIds(dispatchId) {
|
|
564
|
-
return [
|
|
565
|
-
getDispatchInputMessageId(dispatchId),
|
|
566
|
-
getLegacyDispatchInputMessageId(dispatchId)
|
|
567
|
-
];
|
|
568
|
-
}
|
|
569
|
-
function getDispatchTurnId(dispatchId) {
|
|
570
|
-
return `dispatch:${dispatchId}`;
|
|
571
|
-
}
|
|
572
|
-
function toDispatchProjection(record) {
|
|
573
|
-
return {
|
|
574
|
-
id: record.id,
|
|
575
|
-
status: record.status,
|
|
576
|
-
...record.resultMessageTs ? { resultMessageTs: record.resultMessageTs } : {},
|
|
577
|
-
...record.errorMessage ? { errorMessage: record.errorMessage } : {}
|
|
578
|
-
};
|
|
579
|
-
}
|
|
580
|
-
function isTerminalDispatchStatus(status) {
|
|
581
|
-
return status === "completed" || status === "failed" || status === "blocked";
|
|
582
|
-
}
|
|
583
|
-
async function withDispatchLock(dispatchId, task) {
|
|
584
|
-
const state = getStateAdapter();
|
|
585
|
-
await state.connect();
|
|
586
|
-
const lock = await state.acquireLock(
|
|
587
|
-
dispatchLockKey(dispatchId),
|
|
588
|
-
DISPATCH_LOCK_TTL_MS
|
|
589
|
-
);
|
|
590
|
-
if (!lock) {
|
|
591
|
-
throw new Error(`Could not acquire dispatch lock for ${dispatchId}`);
|
|
592
|
-
}
|
|
593
|
-
try {
|
|
594
|
-
return await task(state);
|
|
595
|
-
} finally {
|
|
596
|
-
await state.releaseLock(lock);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
async function putRecord(state, record) {
|
|
600
|
-
const parsed = dispatchRecordSchema.safeParse(record);
|
|
601
|
-
if (!parsed.success) {
|
|
602
|
-
throw new Error(
|
|
603
|
-
`Dispatch record is invalid: ${parsed.error.issues.map((issue) => `${issue.path.join(".") || "<root>"} ${issue.message}`).join("; ")}`
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
const next = parsed.data;
|
|
607
|
-
await state.set(
|
|
608
|
-
getDispatchStorageKey(next.id),
|
|
609
|
-
next,
|
|
610
|
-
JUNIOR_THREAD_STATE_TTL_MS
|
|
611
|
-
);
|
|
612
|
-
}
|
|
613
|
-
async function updatePendingDispatchMailboxAppendIndex(state, update) {
|
|
614
|
-
const lock = await state.acquireLock(
|
|
615
|
-
pendingDispatchMailboxAppendIndexLockKey(),
|
|
616
|
-
DISPATCH_MAILBOX_APPEND_INDEX_LOCK_TTL_MS
|
|
617
|
-
);
|
|
618
|
-
if (!lock) {
|
|
619
|
-
throw new Error("Could not acquire dispatch mailbox append index lock");
|
|
620
|
-
}
|
|
621
|
-
try {
|
|
622
|
-
const stored = await state.get(pendingDispatchMailboxAppendIndexKey());
|
|
623
|
-
const ids = stored === void 0 || stored === null ? [] : pendingDispatchMailboxAppendIndexSchema.parse(stored);
|
|
624
|
-
const next = [...new Set(update([...new Set(ids)]))].slice(
|
|
625
|
-
-DISPATCH_MAILBOX_APPEND_INDEX_MAX_LENGTH
|
|
626
|
-
);
|
|
627
|
-
if (next.length === ids.length && next.every((id, index) => id === ids[index])) {
|
|
628
|
-
return;
|
|
629
|
-
}
|
|
630
|
-
await state.set(
|
|
631
|
-
pendingDispatchMailboxAppendIndexKey(),
|
|
632
|
-
next,
|
|
633
|
-
JUNIOR_THREAD_STATE_TTL_MS
|
|
634
|
-
);
|
|
635
|
-
} finally {
|
|
636
|
-
await state.releaseLock(lock);
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
async function getDispatchRecord(id) {
|
|
640
|
-
const state = getStateAdapter();
|
|
641
|
-
await state.connect();
|
|
642
|
-
return parseDispatchRecord(await state.get(getDispatchStorageKey(id)));
|
|
643
|
-
}
|
|
644
|
-
async function createOrGetDispatch(args) {
|
|
645
|
-
const id = buildDispatchId(args.plugin, args.options.idempotencyKey);
|
|
646
|
-
return await withDispatchLock(id, async (state) => {
|
|
647
|
-
const existing = parseDispatchRecord(
|
|
648
|
-
await state.get(getDispatchStorageKey(id))
|
|
649
|
-
);
|
|
650
|
-
if (existing) {
|
|
651
|
-
return { record: existing, status: "already_exists" };
|
|
652
|
-
}
|
|
653
|
-
const metadata = normalizeMetadata(args.options.metadata);
|
|
654
|
-
const record = {
|
|
655
|
-
actor: { platform: "system", name: args.plugin },
|
|
656
|
-
createdAtMs: args.nowMs,
|
|
657
|
-
...args.options.credentialSubject ? { credentialSubject: args.options.credentialSubject } : {},
|
|
658
|
-
destination: args.options.destination,
|
|
659
|
-
destinationVisibility: args.options.destinationVisibility,
|
|
660
|
-
id,
|
|
661
|
-
idempotencyKey: args.options.idempotencyKey,
|
|
662
|
-
input: args.options.input,
|
|
663
|
-
...metadata ? { metadata } : {},
|
|
664
|
-
plugin: args.plugin,
|
|
665
|
-
...args.options.replyAttribution ? { replyAttribution: args.options.replyAttribution } : {},
|
|
666
|
-
status: "pending",
|
|
667
|
-
source: args.options.source,
|
|
668
|
-
updatedAtMs: args.nowMs
|
|
669
|
-
};
|
|
670
|
-
await updatePendingDispatchMailboxAppendIndex(
|
|
671
|
-
state,
|
|
672
|
-
(ids) => ids.includes(id) ? ids : [...ids, id]
|
|
673
|
-
);
|
|
674
|
-
await putRecord(state, record);
|
|
675
|
-
return { record, status: "created" };
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
async function transitionDispatch(id, transition) {
|
|
679
|
-
return await withDispatchLock(id, async (state) => {
|
|
680
|
-
const current = parseDispatchRecord(
|
|
681
|
-
await state.get(getDispatchStorageKey(id))
|
|
682
|
-
);
|
|
683
|
-
if (!current) {
|
|
684
|
-
return void 0;
|
|
685
|
-
}
|
|
686
|
-
const transitioned = transition(current);
|
|
687
|
-
if (transitioned === current) {
|
|
688
|
-
return current;
|
|
689
|
-
}
|
|
690
|
-
const next = {
|
|
691
|
-
...transitioned,
|
|
692
|
-
updatedAtMs: Date.now()
|
|
693
|
-
};
|
|
694
|
-
await putRecord(state, next);
|
|
695
|
-
return next;
|
|
696
|
-
});
|
|
697
|
-
}
|
|
698
|
-
async function markDispatchRunning(id) {
|
|
699
|
-
return await transitionDispatch(
|
|
700
|
-
id,
|
|
701
|
-
(record) => isTerminalDispatchStatus(record.status) ? record : { ...record, status: "running", errorMessage: void 0 }
|
|
702
|
-
);
|
|
703
|
-
}
|
|
704
|
-
async function markDispatchAwaitingResume(id) {
|
|
705
|
-
return await transitionDispatch(
|
|
706
|
-
id,
|
|
707
|
-
(record) => isTerminalDispatchStatus(record.status) ? record : {
|
|
708
|
-
...record,
|
|
709
|
-
status: "awaiting_resume"
|
|
710
|
-
}
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
async function markDispatchBlocked(id, errorMessage, resultMessageTs) {
|
|
714
|
-
return await transitionDispatch(
|
|
715
|
-
id,
|
|
716
|
-
(record) => isTerminalDispatchStatus(record.status) ? record : {
|
|
717
|
-
...record,
|
|
718
|
-
errorMessage,
|
|
719
|
-
...resultMessageTs ? { resultMessageTs } : {},
|
|
720
|
-
status: "blocked"
|
|
721
|
-
}
|
|
722
|
-
);
|
|
723
|
-
}
|
|
724
|
-
async function markDispatchCompleted(id, resultMessageTs) {
|
|
725
|
-
const previous = await getDispatchRecord(id);
|
|
726
|
-
const next = await transitionDispatch(
|
|
727
|
-
id,
|
|
728
|
-
(record) => isTerminalDispatchStatus(record.status) ? record : {
|
|
729
|
-
...record,
|
|
730
|
-
errorMessage: void 0,
|
|
731
|
-
...resultMessageTs ? { resultMessageTs } : {},
|
|
732
|
-
status: "completed"
|
|
733
|
-
}
|
|
734
|
-
);
|
|
735
|
-
if (next?.status === "completed" && previous?.status !== "completed" && next.plugin === "junior") {
|
|
736
|
-
const eventTaskId = next.metadata?.eventTaskId;
|
|
737
|
-
if (eventTaskId) {
|
|
738
|
-
await recordTaskExecution("event", eventTaskId, {
|
|
739
|
-
conversationId: getDispatchConversationId(next),
|
|
740
|
-
executionId: next.id,
|
|
741
|
-
nowMs: next.updatedAtMs
|
|
742
|
-
});
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
return next;
|
|
746
|
-
}
|
|
747
|
-
async function markDispatchFailed(id, errorMessage, resultMessageTs) {
|
|
748
|
-
return await transitionDispatch(
|
|
749
|
-
id,
|
|
750
|
-
(record) => isTerminalDispatchStatus(record.status) ? record : {
|
|
751
|
-
...record,
|
|
752
|
-
errorMessage,
|
|
753
|
-
...resultMessageTs ? { resultMessageTs } : {},
|
|
754
|
-
status: "failed"
|
|
755
|
-
}
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
async function confirmDispatchMailboxAppend(id) {
|
|
759
|
-
const state = getStateAdapter();
|
|
760
|
-
await state.connect();
|
|
761
|
-
await updatePendingDispatchMailboxAppendIndex(
|
|
762
|
-
state,
|
|
763
|
-
(ids) => ids.filter((candidate) => candidate !== id)
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
async function listPendingDispatchMailboxAppends() {
|
|
767
|
-
const state = getStateAdapter();
|
|
768
|
-
await state.connect();
|
|
769
|
-
const stored = await state.get(pendingDispatchMailboxAppendIndexKey());
|
|
770
|
-
return stored === void 0 || stored === null ? [] : [...new Set(pendingDispatchMailboxAppendIndexSchema.parse(stored))];
|
|
771
|
-
}
|
|
772
|
-
async function claimDispatchMailboxAppend(id, nowMs) {
|
|
773
|
-
return await withDispatchLock(id, async (state) => {
|
|
774
|
-
const stored = parseStoredDispatchRecord(
|
|
775
|
-
await state.get(getDispatchStorageKey(id))
|
|
776
|
-
);
|
|
777
|
-
if (!stored || stored.legacyLeaseExpiresAtMs && stored.legacyLeaseExpiresAtMs > nowMs) {
|
|
778
|
-
return void 0;
|
|
779
|
-
}
|
|
780
|
-
await putRecord(state, stored.record);
|
|
781
|
-
return stored.record;
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
async function getPluginDispatchProjection(args) {
|
|
785
|
-
const record = await getDispatchRecord(args.id);
|
|
786
|
-
if (!record || record.plugin !== args.plugin) {
|
|
787
|
-
return void 0;
|
|
788
|
-
}
|
|
789
|
-
return toDispatchProjection(record);
|
|
790
|
-
}
|
|
791
|
-
|
|
792
428
|
// src/chat/agent-dispatch/work.ts
|
|
793
|
-
import { z as
|
|
794
|
-
var agentDispatchMailboxMetadataSchema =
|
|
795
|
-
dispatchId:
|
|
796
|
-
kind:
|
|
429
|
+
import { z as z2 } from "zod";
|
|
430
|
+
var agentDispatchMailboxMetadataSchema = z2.object({
|
|
431
|
+
dispatchId: z2.string().min(1),
|
|
432
|
+
kind: z2.literal("agent_dispatch")
|
|
797
433
|
}).strict();
|
|
798
434
|
var AGENT_DISPATCH_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
799
435
|
function buildDispatchRoutingContext(dispatch2) {
|
|
800
436
|
return {
|
|
801
437
|
actor: dispatch2.actor,
|
|
802
|
-
credentialContext:
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
438
|
+
credentialContext: credentialContextForActor(
|
|
439
|
+
dispatch2.actor,
|
|
440
|
+
dispatch2.credentialSubject
|
|
441
|
+
),
|
|
806
442
|
destinationVisibility: dispatch2.destinationVisibility,
|
|
807
443
|
dispatch: {
|
|
808
444
|
actor: dispatch2.actor,
|
|
@@ -1301,7 +937,7 @@ import {
|
|
|
1301
937
|
// src/chat/agent-dispatch/validation.ts
|
|
1302
938
|
import {
|
|
1303
939
|
dispatchOptionsSchema,
|
|
1304
|
-
isSlackDestination
|
|
940
|
+
isSlackDestination
|
|
1305
941
|
} from "@sentry/junior-plugin-api";
|
|
1306
942
|
function hasIssueAtPath(issues, path) {
|
|
1307
943
|
return issues.some(
|
|
@@ -1398,7 +1034,7 @@ function validateDispatchOptions(options) {
|
|
|
1398
1034
|
}
|
|
1399
1035
|
const candidate = parsed.data;
|
|
1400
1036
|
const { credentialSubject, destination } = candidate;
|
|
1401
|
-
if (!
|
|
1037
|
+
if (!isSlackDestination(destination)) {
|
|
1402
1038
|
throw new Error("Dispatch destination platform must be slack");
|
|
1403
1039
|
}
|
|
1404
1040
|
if (credentialSubject !== void 0) {
|
|
@@ -1623,6 +1259,15 @@ function shouldSkipRun(task, run) {
|
|
|
1623
1259
|
}
|
|
1624
1260
|
return void 0;
|
|
1625
1261
|
}
|
|
1262
|
+
async function recordScheduledExecution(args) {
|
|
1263
|
+
const dispatchId = args.run.dispatchId;
|
|
1264
|
+
await recordTaskExecution("scheduled", args.run.taskId, {
|
|
1265
|
+
...dispatchId ? { conversationId: getDispatchConversationId({ id: dispatchId }) } : {},
|
|
1266
|
+
executionId: args.run.id,
|
|
1267
|
+
nowMs: args.nowMs,
|
|
1268
|
+
status: args.status
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1626
1271
|
async function applyDispatchResult(args) {
|
|
1627
1272
|
if (args.dispatch.status === "completed") {
|
|
1628
1273
|
const completed = await args.store.markRunCompleted({
|
|
@@ -1637,14 +1282,11 @@ async function applyDispatchResult(args) {
|
|
|
1637
1282
|
run: args.run,
|
|
1638
1283
|
status: "completed"
|
|
1639
1284
|
});
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
nowMs: args.nowMs
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1285
|
+
await recordScheduledExecution({
|
|
1286
|
+
nowMs: args.nowMs,
|
|
1287
|
+
run: args.run,
|
|
1288
|
+
status: "completed"
|
|
1289
|
+
});
|
|
1648
1290
|
return true;
|
|
1649
1291
|
}
|
|
1650
1292
|
if (args.dispatch.status === "blocked") {
|
|
@@ -1661,6 +1303,11 @@ async function applyDispatchResult(args) {
|
|
|
1661
1303
|
run: args.run,
|
|
1662
1304
|
status: "blocked"
|
|
1663
1305
|
});
|
|
1306
|
+
await recordScheduledExecution({
|
|
1307
|
+
nowMs: args.nowMs,
|
|
1308
|
+
run: args.run,
|
|
1309
|
+
status: "blocked"
|
|
1310
|
+
});
|
|
1664
1311
|
return true;
|
|
1665
1312
|
}
|
|
1666
1313
|
if (args.dispatch.status === "failed") {
|
|
@@ -1677,6 +1324,11 @@ async function applyDispatchResult(args) {
|
|
|
1677
1324
|
run: args.run,
|
|
1678
1325
|
status: "failed"
|
|
1679
1326
|
});
|
|
1327
|
+
await recordScheduledExecution({
|
|
1328
|
+
nowMs: args.nowMs,
|
|
1329
|
+
run: args.run,
|
|
1330
|
+
status: "failed"
|
|
1331
|
+
});
|
|
1680
1332
|
return true;
|
|
1681
1333
|
}
|
|
1682
1334
|
return false;
|
|
@@ -1699,6 +1351,11 @@ async function finishClaimedRun(args) {
|
|
|
1699
1351
|
run: args.run,
|
|
1700
1352
|
status: args.status
|
|
1701
1353
|
});
|
|
1354
|
+
await recordScheduledExecution({
|
|
1355
|
+
nowMs: args.nowMs,
|
|
1356
|
+
run: args.run,
|
|
1357
|
+
status: args.status
|
|
1358
|
+
});
|
|
1702
1359
|
}
|
|
1703
1360
|
async function runScheduledTaskHeartbeat(args) {
|
|
1704
1361
|
const store = createSchedulerSqlStore(getDb());
|
|
@@ -2658,7 +2315,7 @@ import {
|
|
|
2658
2315
|
Message,
|
|
2659
2316
|
ThreadImpl
|
|
2660
2317
|
} from "chat";
|
|
2661
|
-
import { z as
|
|
2318
|
+
import { z as z4 } from "zod";
|
|
2662
2319
|
|
|
2663
2320
|
// src/chat/ingress/message-router.ts
|
|
2664
2321
|
function normalizeIncomingSlackThreadId(threadId, message) {
|
|
@@ -2829,14 +2486,14 @@ async function ensureSlackMessageActorIdentity(message, teamId, lookupSlackUser2
|
|
|
2829
2486
|
}
|
|
2830
2487
|
|
|
2831
2488
|
// src/chat/slack/user.ts
|
|
2832
|
-
import { z as
|
|
2833
|
-
var slackUserInfoSchema =
|
|
2834
|
-
ok:
|
|
2835
|
-
user:
|
|
2836
|
-
name:
|
|
2837
|
-
profile:
|
|
2838
|
-
email:
|
|
2839
|
-
real_name:
|
|
2489
|
+
import { z as z3 } from "zod";
|
|
2490
|
+
var slackUserInfoSchema = z3.object({
|
|
2491
|
+
ok: z3.literal(true),
|
|
2492
|
+
user: z3.object({
|
|
2493
|
+
name: z3.string().nullish(),
|
|
2494
|
+
profile: z3.object({
|
|
2495
|
+
email: z3.string().nullish(),
|
|
2496
|
+
real_name: z3.string().nullish()
|
|
2840
2497
|
}).optional()
|
|
2841
2498
|
})
|
|
2842
2499
|
});
|
|
@@ -2913,6 +2570,20 @@ async function lookupSlackUser(teamId, userId) {
|
|
|
2913
2570
|
}
|
|
2914
2571
|
}
|
|
2915
2572
|
|
|
2573
|
+
// src/chat/resource-events/actor.ts
|
|
2574
|
+
var RESOURCE_EVENT_SLACK_AUTHOR_ID = "UJRNEVENT";
|
|
2575
|
+
var RESOURCE_EVENT_SYSTEM_ACTOR = {
|
|
2576
|
+
platform: "system",
|
|
2577
|
+
name: "resource-event"
|
|
2578
|
+
};
|
|
2579
|
+
function isResourceEventConversationMessage(message) {
|
|
2580
|
+
return Boolean(message.meta?.eventType) || message.author?.userId === RESOURCE_EVENT_SLACK_AUTHOR_ID;
|
|
2581
|
+
}
|
|
2582
|
+
function isResourceEventSlackMessage(message) {
|
|
2583
|
+
const raw = message.raw && typeof message.raw === "object" ? message.raw : void 0;
|
|
2584
|
+
return raw?.event_type === "resource_event";
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2916
2587
|
// src/chat/slack/message-control.ts
|
|
2917
2588
|
var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
|
|
2918
2589
|
function stripLeadingSteeringOverride(text) {
|
|
@@ -2920,17 +2591,17 @@ function stripLeadingSteeringOverride(text) {
|
|
|
2920
2591
|
}
|
|
2921
2592
|
|
|
2922
2593
|
// src/chat/task-execution/slack-work.ts
|
|
2923
|
-
var slackConversationRouteSchema =
|
|
2594
|
+
var slackConversationRouteSchema = z4.enum(["mention", "subscribed"]);
|
|
2924
2595
|
function hasSteeringOverride(text) {
|
|
2925
2596
|
return stripLeadingSteeringOverride(text) !== text;
|
|
2926
2597
|
}
|
|
2927
|
-
var serializedDateSchema =
|
|
2928
|
-
var mdastPointSchema =
|
|
2929
|
-
column:
|
|
2930
|
-
line:
|
|
2931
|
-
offset:
|
|
2598
|
+
var serializedDateSchema = z4.iso.datetime();
|
|
2599
|
+
var mdastPointSchema = z4.object({
|
|
2600
|
+
column: z4.number().int().positive(),
|
|
2601
|
+
line: z4.number().int().positive(),
|
|
2602
|
+
offset: z4.number().int().nonnegative().optional()
|
|
2932
2603
|
}).strict();
|
|
2933
|
-
var mdastPositionSchema =
|
|
2604
|
+
var mdastPositionSchema = z4.object({
|
|
2934
2605
|
end: mdastPointSchema,
|
|
2935
2606
|
start: mdastPointSchema
|
|
2936
2607
|
}).strict();
|
|
@@ -3042,7 +2713,7 @@ function isFormattedContentNode(value) {
|
|
|
3042
2713
|
return false;
|
|
3043
2714
|
}
|
|
3044
2715
|
}
|
|
3045
|
-
var formattedContentSchema =
|
|
2716
|
+
var formattedContentSchema = z4.custom(
|
|
3046
2717
|
(value) => {
|
|
3047
2718
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
3048
2719
|
return false;
|
|
@@ -3052,79 +2723,79 @@ var formattedContentSchema = z5.custom(
|
|
|
3052
2723
|
},
|
|
3053
2724
|
"must be a valid formatted-content root"
|
|
3054
2725
|
);
|
|
3055
|
-
var serializedMessageSchema =
|
|
3056
|
-
_type:
|
|
3057
|
-
attachments:
|
|
3058
|
-
|
|
3059
|
-
type:
|
|
3060
|
-
url:
|
|
3061
|
-
name:
|
|
3062
|
-
mimeType:
|
|
3063
|
-
size:
|
|
3064
|
-
width:
|
|
3065
|
-
height:
|
|
3066
|
-
fetchMetadata:
|
|
2726
|
+
var serializedMessageSchema = z4.object({
|
|
2727
|
+
_type: z4.literal("chat:Message"),
|
|
2728
|
+
attachments: z4.array(
|
|
2729
|
+
z4.object({
|
|
2730
|
+
type: z4.enum(["image", "file", "video", "audio"]),
|
|
2731
|
+
url: z4.string().optional(),
|
|
2732
|
+
name: z4.string().optional(),
|
|
2733
|
+
mimeType: z4.string().optional(),
|
|
2734
|
+
size: z4.number().finite().optional(),
|
|
2735
|
+
width: z4.number().finite().optional(),
|
|
2736
|
+
height: z4.number().finite().optional(),
|
|
2737
|
+
fetchMetadata: z4.record(z4.string(), z4.string()).optional()
|
|
3067
2738
|
}).strict()
|
|
3068
2739
|
),
|
|
3069
|
-
author:
|
|
3070
|
-
userId:
|
|
3071
|
-
userName:
|
|
3072
|
-
fullName:
|
|
3073
|
-
isBot:
|
|
3074
|
-
isMe:
|
|
2740
|
+
author: z4.object({
|
|
2741
|
+
userId: z4.string(),
|
|
2742
|
+
userName: z4.string(),
|
|
2743
|
+
fullName: z4.string(),
|
|
2744
|
+
isBot: z4.union([z4.boolean(), z4.literal("unknown")]),
|
|
2745
|
+
isMe: z4.boolean()
|
|
3075
2746
|
}).strict(),
|
|
3076
2747
|
formatted: formattedContentSchema,
|
|
3077
|
-
id:
|
|
3078
|
-
isMention:
|
|
3079
|
-
links:
|
|
3080
|
-
|
|
3081
|
-
url:
|
|
3082
|
-
title:
|
|
3083
|
-
description:
|
|
3084
|
-
imageUrl:
|
|
3085
|
-
siteName:
|
|
2748
|
+
id: z4.string().min(1),
|
|
2749
|
+
isMention: z4.boolean().optional(),
|
|
2750
|
+
links: z4.array(
|
|
2751
|
+
z4.object({
|
|
2752
|
+
url: z4.string(),
|
|
2753
|
+
title: z4.string().optional(),
|
|
2754
|
+
description: z4.string().optional(),
|
|
2755
|
+
imageUrl: z4.string().optional(),
|
|
2756
|
+
siteName: z4.string().optional()
|
|
3086
2757
|
}).strict()
|
|
3087
2758
|
).optional(),
|
|
3088
|
-
metadata:
|
|
2759
|
+
metadata: z4.object({
|
|
3089
2760
|
dateSent: serializedDateSchema,
|
|
3090
|
-
edited:
|
|
2761
|
+
edited: z4.boolean(),
|
|
3091
2762
|
editedAt: serializedDateSchema.optional()
|
|
3092
2763
|
}).strict(),
|
|
3093
|
-
raw:
|
|
3094
|
-
text:
|
|
3095
|
-
threadId:
|
|
2764
|
+
raw: z4.unknown(),
|
|
2765
|
+
text: z4.string(),
|
|
2766
|
+
threadId: z4.string().min(1)
|
|
3096
2767
|
}).strict();
|
|
3097
|
-
var serializedThreadSchema =
|
|
3098
|
-
_type:
|
|
3099
|
-
adapterName:
|
|
3100
|
-
channelId:
|
|
3101
|
-
channelVisibility:
|
|
2768
|
+
var serializedThreadSchema = z4.object({
|
|
2769
|
+
_type: z4.literal("chat:Thread"),
|
|
2770
|
+
adapterName: z4.literal("slack"),
|
|
2771
|
+
channelId: z4.string().min(1),
|
|
2772
|
+
channelVisibility: z4.enum(["private", "workspace", "external", "unknown"]).optional(),
|
|
3102
2773
|
currentMessage: serializedMessageSchema.optional(),
|
|
3103
|
-
id:
|
|
3104
|
-
isDM:
|
|
2774
|
+
id: z4.string().min(1),
|
|
2775
|
+
isDM: z4.boolean()
|
|
3105
2776
|
}).strict();
|
|
3106
|
-
var slackInstallationSchema =
|
|
3107
|
-
enterpriseId:
|
|
3108
|
-
isEnterpriseInstall:
|
|
3109
|
-
teamId:
|
|
2777
|
+
var slackInstallationSchema = z4.object({
|
|
2778
|
+
enterpriseId: z4.string().optional(),
|
|
2779
|
+
isEnterpriseInstall: z4.boolean().optional(),
|
|
2780
|
+
teamId: z4.string().optional()
|
|
3110
2781
|
}).strict();
|
|
3111
|
-
var slackConversationMessageMetadataBaseSchema =
|
|
2782
|
+
var slackConversationMessageMetadataBaseSchema = z4.object({
|
|
3112
2783
|
installation: slackInstallationSchema.optional(),
|
|
3113
2784
|
message: serializedMessageSchema,
|
|
3114
|
-
platform:
|
|
2785
|
+
platform: z4.literal("slack"),
|
|
3115
2786
|
route: slackConversationRouteSchema,
|
|
3116
2787
|
thread: serializedThreadSchema
|
|
3117
2788
|
});
|
|
3118
|
-
var slackConversationMessageMetadataSchema =
|
|
2789
|
+
var slackConversationMessageMetadataSchema = z4.union([
|
|
3119
2790
|
slackConversationMessageMetadataBaseSchema.strict(),
|
|
3120
2791
|
slackConversationMessageMetadataBaseSchema.extend({
|
|
3121
|
-
kind:
|
|
3122
|
-
resourceEvent:
|
|
3123
|
-
eventKey:
|
|
3124
|
-
eventType:
|
|
3125
|
-
namespace:
|
|
3126
|
-
identifier:
|
|
3127
|
-
subscriptionId:
|
|
2792
|
+
kind: z4.literal("resource_event"),
|
|
2793
|
+
resourceEvent: z4.object({
|
|
2794
|
+
eventKey: z4.string(),
|
|
2795
|
+
eventType: z4.string(),
|
|
2796
|
+
namespace: z4.string(),
|
|
2797
|
+
identifier: z4.string(),
|
|
2798
|
+
subscriptionId: z4.string()
|
|
3128
2799
|
}).strict()
|
|
3129
2800
|
}).strict()
|
|
3130
2801
|
]);
|
|
@@ -3157,7 +2828,7 @@ function slackSerializedResourceEventMessage(input) {
|
|
|
3157
2828
|
_type: "chat:Message",
|
|
3158
2829
|
attachments: [],
|
|
3159
2830
|
author: {
|
|
3160
|
-
userId:
|
|
2831
|
+
userId: RESOURCE_EVENT_SLACK_AUTHOR_ID,
|
|
3161
2832
|
userName: "junior-event",
|
|
3162
2833
|
fullName: "Junior event",
|
|
3163
2834
|
isBot: true,
|
|
@@ -3175,7 +2846,7 @@ function slackSerializedResourceEventMessage(input) {
|
|
|
3175
2846
|
resource_event_type: input.eventType,
|
|
3176
2847
|
thread_ts: input.threadTs,
|
|
3177
2848
|
type: "message",
|
|
3178
|
-
user:
|
|
2849
|
+
user: RESOURCE_EVENT_SLACK_AUTHOR_ID
|
|
3179
2850
|
},
|
|
3180
2851
|
text: input.text,
|
|
3181
2852
|
threadId: `slack:${input.channelId}:${input.threadTs}`
|
|
@@ -3219,7 +2890,7 @@ function createSlackResourceEventInboundMessage(input) {
|
|
|
3219
2890
|
receivedAtMs: Date.now(),
|
|
3220
2891
|
input: {
|
|
3221
2892
|
text: input.text,
|
|
3222
|
-
authorId:
|
|
2893
|
+
authorId: RESOURCE_EVENT_SLACK_AUTHOR_ID,
|
|
3223
2894
|
metadata: {
|
|
3224
2895
|
kind: "resource_event",
|
|
3225
2896
|
installation: {
|
|
@@ -3259,10 +2930,6 @@ function routeForRecords(records) {
|
|
|
3259
2930
|
return metadata.route === "mention";
|
|
3260
2931
|
}) ? "mention" : "subscribed";
|
|
3261
2932
|
}
|
|
3262
|
-
function isResourceEventNotificationMessage(message) {
|
|
3263
|
-
const raw = message.raw && typeof message.raw === "object" ? message.raw : void 0;
|
|
3264
|
-
return raw?.event_type === "resource_event";
|
|
3265
|
-
}
|
|
3266
2933
|
function restoreMessage(args) {
|
|
3267
2934
|
const metadata = parseSlackMetadata(args.record.input.metadata);
|
|
3268
2935
|
if (!metadata) {
|
|
@@ -3278,7 +2945,7 @@ function restoreMessage(args) {
|
|
|
3278
2945
|
async function bindSlackActorIdentities(args) {
|
|
3279
2946
|
const byAuthorId = /* @__PURE__ */ new Map();
|
|
3280
2947
|
for (const message of args.messages) {
|
|
3281
|
-
if (
|
|
2948
|
+
if (isResourceEventSlackMessage(message)) {
|
|
3282
2949
|
continue;
|
|
3283
2950
|
}
|
|
3284
2951
|
const authorId = requireSlackAuthorId(message);
|
|
@@ -4497,7 +4164,7 @@ function registerVercelPluginTaskDevConsumer() {
|
|
|
4497
4164
|
}
|
|
4498
4165
|
|
|
4499
4166
|
// src/chat/services/subscribed-decision.ts
|
|
4500
|
-
import { z as
|
|
4167
|
+
import { z as z5 } from "zod";
|
|
4501
4168
|
|
|
4502
4169
|
// src/chat/services/subscribed-reply-router-policy.ts
|
|
4503
4170
|
function buildSubscribedReplyRouterPolicy(assistantName) {
|
|
@@ -4542,13 +4209,13 @@ Assess conversation floor ownership and whether the latest message continues wor
|
|
|
4542
4209
|
}
|
|
4543
4210
|
|
|
4544
4211
|
// src/chat/services/subscribed-decision.ts
|
|
4545
|
-
var replyDecisionSchema =
|
|
4546
|
-
should_reply:
|
|
4547
|
-
should_unsubscribe:
|
|
4212
|
+
var replyDecisionSchema = z5.object({
|
|
4213
|
+
should_reply: z5.boolean().describe("Whether Junior should respond to this thread message."),
|
|
4214
|
+
should_unsubscribe: z5.boolean().describe(
|
|
4548
4215
|
"Whether Junior should unsubscribe from this thread because the user clearly asked it to stop participating."
|
|
4549
4216
|
),
|
|
4550
|
-
confidence:
|
|
4551
|
-
reason:
|
|
4217
|
+
confidence: z5.number().min(0).max(1).describe("Classifier confidence from 0 to 1."),
|
|
4218
|
+
reason: z5.string().describe("Short reason for the decision; use an empty string if none.")
|
|
4552
4219
|
}).strict();
|
|
4553
4220
|
var ROUTER_CONFIDENCE_THRESHOLD = 0.7;
|
|
4554
4221
|
var ROUTER_CLASSIFIER_MAX_TOKENS = 400;
|
|
@@ -5003,10 +4670,6 @@ function buildLogContext(deps, args) {
|
|
|
5003
4670
|
function actorUserName(message) {
|
|
5004
4671
|
return getMessageActorIdentity(message)?.userName;
|
|
5005
4672
|
}
|
|
5006
|
-
function isResourceEventNotificationMessage2(message) {
|
|
5007
|
-
const raw = message.raw && typeof message.raw === "object" ? message.raw : void 0;
|
|
5008
|
-
return raw?.event_type === "resource_event";
|
|
5009
|
-
}
|
|
5010
4673
|
function createSlackTurnRuntime(deps) {
|
|
5011
4674
|
const logContext = (args) => buildLogContext(deps, args);
|
|
5012
4675
|
const maybeHandleThreadOptOutDecision = async (args) => {
|
|
@@ -5427,7 +5090,7 @@ function createSlackTurnRuntime(deps) {
|
|
|
5427
5090
|
const threadId = deps.getThreadId(thread, message);
|
|
5428
5091
|
const channelId = deps.getChannelId(thread, message);
|
|
5429
5092
|
const runId = deps.getRunId(thread, message);
|
|
5430
|
-
const isResourceEventNotification =
|
|
5093
|
+
const isResourceEventNotification = isResourceEventSlackMessage(message);
|
|
5431
5094
|
const actorId = isResourceEventNotification ? void 0 : message.author.userId;
|
|
5432
5095
|
const turnContext = logContext({
|
|
5433
5096
|
threadId,
|
|
@@ -6225,11 +5888,11 @@ function createJuniorRuntimeServices(overrides = {}) {
|
|
|
6225
5888
|
import { createSlackSource as createSlackSource2 } from "@sentry/junior-plugin-api";
|
|
6226
5889
|
|
|
6227
5890
|
// src/chat/slack/action-token.ts
|
|
6228
|
-
import { z as
|
|
6229
|
-
var slackActionTokenSchema =
|
|
6230
|
-
var slackMessageEnvelopeSchema =
|
|
6231
|
-
raw:
|
|
6232
|
-
action_token:
|
|
5891
|
+
import { z as z6 } from "zod";
|
|
5892
|
+
var slackActionTokenSchema = z6.string().trim().min(1).brand();
|
|
5893
|
+
var slackMessageEnvelopeSchema = z6.object({
|
|
5894
|
+
raw: z6.object({
|
|
5895
|
+
action_token: z6.unknown().optional()
|
|
6233
5896
|
}).optional()
|
|
6234
5897
|
});
|
|
6235
5898
|
function readSlackActionToken(message) {
|
|
@@ -6393,7 +6056,7 @@ function queuedInstructionActor(queued) {
|
|
|
6393
6056
|
};
|
|
6394
6057
|
}
|
|
6395
6058
|
function queuedInstructionProvenance(queued, teamId) {
|
|
6396
|
-
if (
|
|
6059
|
+
if (isResourceEventSlackMessage(queued.message)) {
|
|
6397
6060
|
return contextProvenance;
|
|
6398
6061
|
}
|
|
6399
6062
|
const identity = getMessageActorIdentity(queued.message);
|
|
@@ -6407,13 +6070,6 @@ function queuedInstructionProvenance(queued, teamId) {
|
|
|
6407
6070
|
);
|
|
6408
6071
|
return instructionProvenanceFor(author);
|
|
6409
6072
|
}
|
|
6410
|
-
function isResourceEventMessage(message) {
|
|
6411
|
-
const raw = message.raw && typeof message.raw === "object" ? message.raw : void 0;
|
|
6412
|
-
return raw?.event_type === "resource_event";
|
|
6413
|
-
}
|
|
6414
|
-
function resourceEventCredentialContext(message) {
|
|
6415
|
-
return isResourceEventMessage(message) ? { actor: { platform: "system", name: "resource-event" } } : void 0;
|
|
6416
|
-
}
|
|
6417
6073
|
async function resolveChannelName(thread) {
|
|
6418
6074
|
const existingName = thread.channel.name?.trim();
|
|
6419
6075
|
if (existingName) {
|
|
@@ -6542,7 +6198,7 @@ function createReplyToThread(deps) {
|
|
|
6542
6198
|
)
|
|
6543
6199
|
};
|
|
6544
6200
|
await Promise.all(
|
|
6545
|
-
(options.queuedMessages ?? []).filter((queued) => !
|
|
6201
|
+
(options.queuedMessages ?? []).filter((queued) => !isResourceEventSlackMessage(queued.message)).map(
|
|
6546
6202
|
(queued) => ensureSlackMessageActorIdentity(
|
|
6547
6203
|
queued.message,
|
|
6548
6204
|
teamId,
|
|
@@ -6551,15 +6207,28 @@ function createReplyToThread(deps) {
|
|
|
6551
6207
|
)
|
|
6552
6208
|
);
|
|
6553
6209
|
const effectiveUserText = currentText.userText;
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6210
|
+
let executionActor;
|
|
6211
|
+
let credentialContext;
|
|
6212
|
+
if (options.execution) {
|
|
6213
|
+
executionActor = options.execution.dispatch.actor;
|
|
6214
|
+
credentialContext = options.execution.credentialContext;
|
|
6215
|
+
} else if (isResourceEventSlackMessage(message)) {
|
|
6216
|
+
executionActor = RESOURCE_EVENT_SYSTEM_ACTOR;
|
|
6217
|
+
credentialContext = credentialContextForActor(executionActor);
|
|
6218
|
+
} else {
|
|
6219
|
+
executionActor = await ensureSlackMessageActorIdentity(
|
|
6220
|
+
message,
|
|
6221
|
+
teamId,
|
|
6222
|
+
deps.services.lookupSlackUser
|
|
6223
|
+
);
|
|
6224
|
+
if (executionActor) {
|
|
6225
|
+
credentialContext = credentialContextForActor(executionActor);
|
|
6226
|
+
}
|
|
6227
|
+
}
|
|
6228
|
+
if (!executionActor || !credentialContext) {
|
|
6229
|
+
throw new Error("Slack reply execution requires an actor");
|
|
6230
|
+
}
|
|
6231
|
+
const actor = "userId" in executionActor ? executionActor : void 0;
|
|
6563
6232
|
const slackActorId = actor?.userId;
|
|
6564
6233
|
const preparedState = options.preparedState ?? await deps.prepareTurnState({
|
|
6565
6234
|
thread,
|
|
@@ -6633,7 +6302,7 @@ function createReplyToThread(deps) {
|
|
|
6633
6302
|
attachments,
|
|
6634
6303
|
{
|
|
6635
6304
|
threadId,
|
|
6636
|
-
actorId:
|
|
6305
|
+
actorId: isResourceEventSlackMessage(queued.message) ? void 0 : queued.message.author.userId,
|
|
6637
6306
|
channelId,
|
|
6638
6307
|
runId,
|
|
6639
6308
|
conversation: preparedState.conversation,
|
|
@@ -7208,7 +6877,9 @@ function createReplyToThread(deps) {
|
|
|
7208
6877
|
},
|
|
7209
6878
|
routing: {
|
|
7210
6879
|
credentialContext,
|
|
7211
|
-
|
|
6880
|
+
// Always set the execution actor when known. Resource-event turns
|
|
6881
|
+
// carry the system principal; interactive turns carry the Slack user.
|
|
6882
|
+
actor: executionActor,
|
|
7212
6883
|
slackConversation,
|
|
7213
6884
|
source,
|
|
7214
6885
|
destination,
|
|
@@ -8236,27 +7907,57 @@ async function failContinuationStartup(args) {
|
|
|
8236
7907
|
);
|
|
8237
7908
|
}
|
|
8238
7909
|
}
|
|
8239
|
-
async function
|
|
8240
|
-
|
|
8241
|
-
|
|
7910
|
+
async function resolveSlackResumeUserActor(args) {
|
|
7911
|
+
try {
|
|
7912
|
+
const work = await getConversationWorkState({
|
|
7913
|
+
conversationId: args.conversationId
|
|
7914
|
+
});
|
|
7915
|
+
const workActor = work?.actor;
|
|
7916
|
+
if (workActor?.teamId === args.teamId && workActor.slackUserId === args.userId) {
|
|
7917
|
+
try {
|
|
7918
|
+
return createSlackActor(args.teamId, args.userId, {
|
|
7919
|
+
email: workActor.email,
|
|
7920
|
+
fullName: workActor.fullName,
|
|
7921
|
+
userName: workActor.slackUserName
|
|
7922
|
+
});
|
|
7923
|
+
} catch {
|
|
7924
|
+
}
|
|
7925
|
+
}
|
|
7926
|
+
} catch {
|
|
7927
|
+
}
|
|
7928
|
+
try {
|
|
8242
7929
|
return createSlackResumeActor({
|
|
8243
|
-
actor: stored,
|
|
8244
7930
|
teamId: args.teamId,
|
|
8245
7931
|
userId: args.userId
|
|
8246
7932
|
});
|
|
7933
|
+
} catch {
|
|
7934
|
+
return void 0;
|
|
8247
7935
|
}
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
return
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
7936
|
+
}
|
|
7937
|
+
async function resolveResumeExecutionIdentity(args) {
|
|
7938
|
+
const routing = args.routingContext;
|
|
7939
|
+
if (routing?.credentialContext) {
|
|
7940
|
+
const actor2 = routing.dispatch?.actor ?? routing.actor ?? (!("type" in routing.credentialContext.actor) ? routing.credentialContext.actor : void 0);
|
|
7941
|
+
return actor2 ? { actor: actor2, credentialContext: routing.credentialContext } : void 0;
|
|
7942
|
+
}
|
|
7943
|
+
let actor = routing?.actor;
|
|
7944
|
+
if (!actor && isResourceEventConversationMessage(args.userMessage)) {
|
|
7945
|
+
actor = RESOURCE_EVENT_SYSTEM_ACTOR;
|
|
7946
|
+
}
|
|
7947
|
+
if (!actor && args.userMessage.author?.userId) {
|
|
7948
|
+
actor = await resolveSlackResumeUserActor({
|
|
7949
|
+
conversationId: args.conversationId,
|
|
7950
|
+
teamId: args.teamId,
|
|
7951
|
+
userId: args.userMessage.author.userId
|
|
8257
7952
|
});
|
|
8258
7953
|
}
|
|
8259
|
-
|
|
7954
|
+
if (!actor) {
|
|
7955
|
+
return void 0;
|
|
7956
|
+
}
|
|
7957
|
+
return {
|
|
7958
|
+
actor,
|
|
7959
|
+
credentialContext: credentialContextForActor(actor)
|
|
7960
|
+
};
|
|
8260
7961
|
}
|
|
8261
7962
|
function isContinuationResume(summary) {
|
|
8262
7963
|
return summary.state === "awaiting_resume" && (summary.resumeReason === "timeout" || summary.resumeReason === "yield" || summary.resumeReason === "retry");
|
|
@@ -8274,7 +7975,6 @@ async function failUnresumableContinuation(args) {
|
|
|
8274
7975
|
conversationId: args.conversationId
|
|
8275
7976
|
});
|
|
8276
7977
|
await recordAgentTurnSessionSummary({
|
|
8277
|
-
actor: args.summary.actor,
|
|
8278
7978
|
conversationId: args.conversationId,
|
|
8279
7979
|
destination: routing.destination,
|
|
8280
7980
|
dispatchId: args.summary.dispatchId,
|
|
@@ -8341,16 +8041,32 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
|
|
|
8341
8041
|
(message) => message.role === "user" && options.inputMessageIds?.includes(message.id)
|
|
8342
8042
|
) : void 0;
|
|
8343
8043
|
const userMessage = getTurnUserMessage(conversation, payload.sessionId) ?? dispatchUserMessage;
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
);
|
|
8044
|
+
if (!userMessage) {
|
|
8045
|
+
await failStrandedSessionWithFallback({
|
|
8046
|
+
conversationId: payload.conversationId,
|
|
8047
|
+
errorMessage: `Unable to locate the persisted user message for agent continuation session "${payload.sessionId}"`,
|
|
8048
|
+
sessionRecord: activeSessionRecord
|
|
8049
|
+
});
|
|
8050
|
+
return false;
|
|
8350
8051
|
}
|
|
8351
8052
|
if (conversation.processing.activeTurnId !== payload.sessionId) {
|
|
8352
8053
|
return false;
|
|
8353
8054
|
}
|
|
8055
|
+
const identity = await resolveResumeExecutionIdentity({
|
|
8056
|
+
conversationId: payload.conversationId,
|
|
8057
|
+
routingContext: options.routingContext,
|
|
8058
|
+
teamId: destination.teamId,
|
|
8059
|
+
userMessage
|
|
8060
|
+
});
|
|
8061
|
+
if (!identity) {
|
|
8062
|
+
await failStrandedSessionWithFallback({
|
|
8063
|
+
conversationId: payload.conversationId,
|
|
8064
|
+
errorMessage: "Unable to rebuild Slack actor for continuation",
|
|
8065
|
+
sessionRecord: activeSessionRecord
|
|
8066
|
+
});
|
|
8067
|
+
return false;
|
|
8068
|
+
}
|
|
8069
|
+
const { actor, credentialContext } = identity;
|
|
8354
8070
|
const channelConfiguration = getChannelConfigurationServiceById(
|
|
8355
8071
|
destination.channelId
|
|
8356
8072
|
);
|
|
@@ -8358,34 +8074,6 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
|
|
|
8358
8074
|
excludeMessageId: userMessage.id
|
|
8359
8075
|
});
|
|
8360
8076
|
const sandboxRef = getPersistedSandboxState(currentState);
|
|
8361
|
-
let actor;
|
|
8362
|
-
let credentialContext;
|
|
8363
|
-
if (options.routingContext?.credentialContext) {
|
|
8364
|
-
credentialContext = options.routingContext.credentialContext;
|
|
8365
|
-
} else if (systemActor) {
|
|
8366
|
-
credentialContext = { actor: systemActor };
|
|
8367
|
-
} else {
|
|
8368
|
-
actor = await resolveContinuationActor({
|
|
8369
|
-
conversationId: payload.conversationId,
|
|
8370
|
-
sessionRecordActor: activeSessionRecord.actor,
|
|
8371
|
-
teamId: destination.teamId,
|
|
8372
|
-
userId: userActorId
|
|
8373
|
-
});
|
|
8374
|
-
if (!actor) {
|
|
8375
|
-
await failStrandedSessionWithFallback({
|
|
8376
|
-
conversationId: payload.conversationId,
|
|
8377
|
-
errorMessage: "Stored Slack actor missing for continuation",
|
|
8378
|
-
sessionRecord: activeSessionRecord
|
|
8379
|
-
});
|
|
8380
|
-
return false;
|
|
8381
|
-
}
|
|
8382
|
-
credentialContext = {
|
|
8383
|
-
actor: {
|
|
8384
|
-
type: "user",
|
|
8385
|
-
userId: actor.userId
|
|
8386
|
-
}
|
|
8387
|
-
};
|
|
8388
|
-
}
|
|
8389
8077
|
const routing = await resolveTurnSessionRouting({
|
|
8390
8078
|
conversationId: payload.conversationId
|
|
8391
8079
|
});
|
|
@@ -8433,7 +8121,7 @@ async function continueSlackAgentRunInContext(payload, options, runOptions) {
|
|
|
8433
8121
|
routing: {
|
|
8434
8122
|
...options.routingContext,
|
|
8435
8123
|
credentialContext,
|
|
8436
|
-
|
|
8124
|
+
actor,
|
|
8437
8125
|
destination: routingDestination,
|
|
8438
8126
|
source,
|
|
8439
8127
|
toolChannelId: artifacts.assistantContextChannelId ?? destination.channelId
|
|
@@ -8554,7 +8242,6 @@ async function failStrandedSessionWithFallback(args) {
|
|
|
8554
8242
|
}
|
|
8555
8243
|
if (args.sessionRecord.dispatchId) {
|
|
8556
8244
|
await recordAgentTurnSessionSummary({
|
|
8557
|
-
actor: args.sessionRecord.actor,
|
|
8558
8245
|
conversationId: args.conversationId,
|
|
8559
8246
|
destination: routing.destination,
|
|
8560
8247
|
dispatchId: args.sessionRecord.dispatchId,
|
|
@@ -8619,7 +8306,6 @@ async function recoverStrandedRunningSession(args) {
|
|
|
8619
8306
|
messages: sessionRecord.piMessages,
|
|
8620
8307
|
errorMessage: "Recovered running session after hard worker death",
|
|
8621
8308
|
modelId,
|
|
8622
|
-
actor: sessionRecord.actor,
|
|
8623
8309
|
surface: sessionRecord.surface
|
|
8624
8310
|
});
|
|
8625
8311
|
if (!parked) {
|
|
@@ -8949,7 +8635,7 @@ async function ingestResourceEvent(input, options) {
|
|
|
8949
8635
|
}
|
|
8950
8636
|
|
|
8951
8637
|
// src/chat/event-tasks/ingest.ts
|
|
8952
|
-
import { createHash
|
|
8638
|
+
import { createHash } from "crypto";
|
|
8953
8639
|
import {
|
|
8954
8640
|
createSlackSource as createSlackSource3,
|
|
8955
8641
|
RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
|
|
@@ -8957,7 +8643,7 @@ import {
|
|
|
8957
8643
|
resourceEventSchema as resourceEventSchema2
|
|
8958
8644
|
} from "@sentry/junior-plugin-api";
|
|
8959
8645
|
function eventTaskDispatchKey(taskId, namespace, eventKey) {
|
|
8960
|
-
return `event-task:${
|
|
8646
|
+
return `event-task:${createHash("sha256").update(`${taskId}\0${namespace}\0${eventKey}`).digest("hex").slice(0, 32)}`;
|
|
8961
8647
|
}
|
|
8962
8648
|
function oneLine(value) {
|
|
8963
8649
|
return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 512);
|