@sentry/junior 0.128.0 → 0.129.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-F75ANGBV.js → agent-hooks-ZM4WMZCN.js} +9 -9
- package/dist/api/schema/task.d.ts +152 -0
- package/dist/api/schema.d.ts +2 -0
- package/dist/api/schema.js +13 -3
- package/dist/api/tasks/routes.d.ts +4 -0
- package/dist/api.js +425 -23
- package/dist/app.d.ts +2 -1
- package/dist/app.js +315 -27
- package/dist/{catalog-runtime-ZPSA5QM2.js → catalog-runtime-TN2GPVEI.js} +5 -5
- package/dist/chat/agent-dispatch/context.d.ts +18 -0
- package/dist/chat/event-tasks/store.d.ts +7 -1
- package/dist/chat/event-tasks/tool-support.d.ts +1 -0
- package/dist/chat/resource-events/runtime-catalog.d.ts +3 -0
- package/dist/chat/sandbox/resources.d.ts +12 -1
- package/dist/chat/scheduled-tasks/cadence.d.ts +27 -0
- package/dist/chat/scheduled-tasks/heartbeat.d.ts +6 -0
- package/dist/chat/scheduled-tasks/identity.d.ts +6 -0
- package/dist/chat/scheduled-tasks/personal.d.ts +26 -0
- package/dist/chat/scheduled-tasks/schedule-intent.d.ts +61 -0
- package/dist/chat/scheduled-tasks/store.d.ts +77 -0
- package/dist/chat/scheduled-tasks/tool-support.d.ts +203 -0
- package/dist/chat/scheduled-tasks/tools/create.d.ts +80 -0
- package/dist/chat/scheduled-tasks/tools/delete.d.ts +56 -0
- package/dist/chat/scheduled-tasks/tools/list.d.ts +54 -0
- package/dist/chat/scheduled-tasks/tools/run-now.d.ts +56 -0
- package/dist/chat/scheduled-tasks/tools/update.d.ts +82 -0
- package/dist/chat/scheduled-tasks/tools.d.ts +6 -0
- package/dist/chat/scheduled-tasks/types.d.ts +81 -0
- package/dist/chat/tasks/read.d.ts +9 -0
- package/dist/chat/tools/scheduled-tasks.d.ts +4 -0
- package/dist/{chunk-K5ZB3WWH.js → chunk-2BCQKJTX.js} +2 -2
- package/dist/{chunk-G6XQODHM.js → chunk-3N4MWF3R.js} +1 -1
- package/dist/{chunk-NHWE6Y7G.js → chunk-6CMYU62S.js} +7 -7
- package/dist/{chunk-YY6CVET7.js → chunk-6QQOLIJJ.js} +1308 -804
- package/dist/{chunk-WZ365SQC.js → chunk-A6QQPVSH.js} +1 -1
- package/dist/chunk-BDIEEZK7.js +1470 -0
- package/dist/{chunk-AFJF3RGU.js → chunk-BVKP37NE.js} +61 -13
- package/dist/{chunk-5KKIBIIP.js → chunk-CZJUBH6O.js} +12 -12
- package/dist/{chunk-OLGB5Y7R.js → chunk-CZQ2DSQZ.js} +1 -1
- package/dist/{chunk-3PKF6YNU.js → chunk-E4UCPRYL.js} +1 -1
- package/dist/{chunk-KNRODVH2.js → chunk-ESYXDXNX.js} +6 -6
- package/dist/{chunk-Z4KTQMWW.js → chunk-GPWHBHAG.js} +1 -1
- package/dist/{chunk-JDCPDJ54.js → chunk-GURSWCI4.js} +2 -2
- package/dist/{chunk-RYWMDDWK.js → chunk-K3U5447S.js} +1 -1
- package/dist/{chunk-SHMHHXD5.js → chunk-KB2M27DL.js} +58 -0
- package/dist/{chunk-PBWUUVVG.js → chunk-LV2BQ26V.js} +1 -1
- package/dist/{chunk-KTGJAWRO.js → chunk-NNRV4T2C.js} +1 -2
- package/dist/{chunk-B6E3YA2H.js → chunk-P6I7LFKC.js} +1 -1
- package/dist/{chunk-B7FPRGUJ.js → chunk-PQFNTLZI.js} +3 -3
- package/dist/{chunk-A76LKS5W.js → chunk-QAOA4GUG.js} +5 -5
- package/dist/{chunk-BY43CEXN.js → chunk-R62DRNKB.js} +2 -2
- package/dist/{chunk-HBFQLSGV.js → chunk-U23X4ASF.js} +4 -4
- package/dist/{chunk-2HTHX6XV.js → chunk-XENYUOZG.js} +38 -17
- package/dist/cli/chat.js +24 -24
- package/dist/cli/check.js +6 -6
- package/dist/cli/plugins.js +12 -12
- package/dist/cli/snapshot-create.js +9 -9
- package/dist/cli/upgrade.js +9 -17
- package/dist/db/schema/scheduled-tasks.d.ts +257 -0
- package/dist/db/schema.d.ts +258 -1
- package/dist/{db-FYJYPAKG.js → db-ZI6TBXIS.js} +7 -7
- package/dist/instrumentation.js +4 -4
- package/dist/nitro.js +2 -2
- package/dist/{oauth-callback-server-W3PPIHCS.js → oauth-callback-server-TLA4GARF.js} +17 -17
- package/dist/{runner-5NOFUYKR.js → runner-23YFRWQJ.js} +11 -11
- package/dist/{skills-ENIBKF5V.js → skills-QIUG4D6M.js} +6 -6
- package/dist/{validation-BHLBOO6K.js → validation-3KGEBATS.js} +6 -6
- package/dist/version.js +1 -1
- package/migrations/0016_neat_the_anarchist.sql +171 -0
- package/migrations/meta/0016_snapshot.json +1617 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +5 -6
- package/dist/chunk-FJEIX3AH.js +0 -37
package/dist/app.js
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
startConversationWork,
|
|
51
51
|
startSlackProcessingReaction,
|
|
52
52
|
stripLeadingBotMention
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-CZJUBH6O.js";
|
|
54
54
|
import "./chunk-FA6POGLH.js";
|
|
55
55
|
import {
|
|
56
56
|
ConversationTurnLifecycleService,
|
|
@@ -65,13 +65,13 @@ import {
|
|
|
65
65
|
processPluginTask,
|
|
66
66
|
requireTurnFailureEventId,
|
|
67
67
|
scheduleSessionCompletedPluginTasks
|
|
68
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-ESYXDXNX.js";
|
|
69
69
|
import {
|
|
70
70
|
GET,
|
|
71
71
|
conversationVisibilityFromSlackChannelType,
|
|
72
72
|
resolveSlackChannelTypeFromMessage,
|
|
73
73
|
resolveSlackConversationContext
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-GURSWCI4.js";
|
|
75
75
|
import "./chunk-4CODA7P5.js";
|
|
76
76
|
import "./chunk-UTL3MHPC.js";
|
|
77
77
|
import {
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
import {
|
|
91
91
|
validatePluginEgressCredentialHooks,
|
|
92
92
|
validatePluginRegistrations
|
|
93
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-E4UCPRYL.js";
|
|
94
94
|
import {
|
|
95
95
|
defineJuniorPlugins,
|
|
96
96
|
pluginCatalogConfigFromEnv,
|
|
@@ -112,7 +112,6 @@ import {
|
|
|
112
112
|
deliverResourceEventSubscription,
|
|
113
113
|
executeAgentRun,
|
|
114
114
|
executeCredentialedEgressRequest,
|
|
115
|
-
findMatchingEventTasks,
|
|
116
115
|
findMatchingResourceEventSubscriptions,
|
|
117
116
|
getConfigDefaults,
|
|
118
117
|
latestReportedProgress,
|
|
@@ -122,10 +121,11 @@ import {
|
|
|
122
121
|
renderSlackLegacyAttachmentText,
|
|
123
122
|
resolveDestinationVisibility,
|
|
124
123
|
resolveSandboxEgressProviderForHost,
|
|
124
|
+
sanitizeScheduledTaskPrincipal,
|
|
125
125
|
setConfigDefaults,
|
|
126
126
|
shouldEmitDevAgentTrace,
|
|
127
127
|
shouldPropagateSandboxEgressTrace
|
|
128
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-6QQOLIJJ.js";
|
|
129
129
|
import "./chunk-DIB4GX3G.js";
|
|
130
130
|
import {
|
|
131
131
|
RetryableDeliveryError,
|
|
@@ -136,7 +136,7 @@ import {
|
|
|
136
136
|
formatProviderLabel,
|
|
137
137
|
postSlackMessage,
|
|
138
138
|
startOAuthFlow
|
|
139
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-6CMYU62S.js";
|
|
140
140
|
import {
|
|
141
141
|
ConversationTurnBoundaryError,
|
|
142
142
|
CooperativeTurnYieldError,
|
|
@@ -192,13 +192,19 @@ import {
|
|
|
192
192
|
trimTrailingAssistantMessages,
|
|
193
193
|
updateConversationStats,
|
|
194
194
|
upsertConversationMessage
|
|
195
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-U23X4ASF.js";
|
|
196
196
|
import "./chunk-EPBBYMNE.js";
|
|
197
|
-
import
|
|
198
|
-
|
|
197
|
+
import {
|
|
198
|
+
getSandboxResourceConfig,
|
|
199
|
+
setSandboxResourceConfig
|
|
200
|
+
} from "./chunk-XENYUOZG.js";
|
|
201
|
+
import {
|
|
202
|
+
createSchedulerSqlStore,
|
|
203
|
+
findMatchingEventTasks
|
|
204
|
+
} from "./chunk-BDIEEZK7.js";
|
|
199
205
|
import {
|
|
200
206
|
parseSlackThreadId
|
|
201
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-LV2BQ26V.js";
|
|
202
208
|
import "./chunk-HX236W2U.js";
|
|
203
209
|
import "./chunk-PDO5BLNM.js";
|
|
204
210
|
import "./chunk-UIE3R5XU.js";
|
|
@@ -226,7 +232,7 @@ import {
|
|
|
226
232
|
verifyEventTaskCredentialSubject,
|
|
227
233
|
verifyScheduledTaskCredentialSubject,
|
|
228
234
|
verifySlackDirectCredentialSubject
|
|
229
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-QAOA4GUG.js";
|
|
230
236
|
import {
|
|
231
237
|
contextProvenance,
|
|
232
238
|
createSlackDestination,
|
|
@@ -237,16 +243,16 @@ import {
|
|
|
237
243
|
instructionProvenanceFor,
|
|
238
244
|
requireSlackDestination,
|
|
239
245
|
withConversationEventLock
|
|
240
|
-
} from "./chunk-
|
|
246
|
+
} from "./chunk-PQFNTLZI.js";
|
|
241
247
|
import {
|
|
242
248
|
juniorConversationEvents,
|
|
243
249
|
juniorConversations
|
|
244
|
-
} from "./chunk-
|
|
250
|
+
} from "./chunk-KB2M27DL.js";
|
|
245
251
|
import {
|
|
246
252
|
acquireActiveLock,
|
|
247
253
|
getStateAdapter,
|
|
248
254
|
sleep
|
|
249
|
-
} from "./chunk-
|
|
255
|
+
} from "./chunk-3N4MWF3R.js";
|
|
250
256
|
import {
|
|
251
257
|
STANDARD_MODEL_PROFILE,
|
|
252
258
|
botConfig,
|
|
@@ -264,16 +270,16 @@ import {
|
|
|
264
270
|
modelIdForProfile,
|
|
265
271
|
setSlackReactionConfig,
|
|
266
272
|
standardModelId
|
|
267
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-2BCQKJTX.js";
|
|
268
274
|
import {
|
|
269
275
|
juniorDestinations
|
|
270
276
|
} from "./chunk-VFUK3X5B.js";
|
|
271
|
-
import "./chunk-
|
|
272
|
-
import "./chunk-
|
|
277
|
+
import "./chunk-GPWHBHAG.js";
|
|
278
|
+
import "./chunk-R62DRNKB.js";
|
|
273
279
|
import {
|
|
274
280
|
pluginCatalogRuntime
|
|
275
|
-
} from "./chunk-
|
|
276
|
-
import "./chunk-
|
|
281
|
+
} from "./chunk-A6QQPVSH.js";
|
|
282
|
+
import "./chunk-CZQ2DSQZ.js";
|
|
277
283
|
import {
|
|
278
284
|
credentialSubjectSchema
|
|
279
285
|
} from "./chunk-77VDLF3Z.js";
|
|
@@ -305,7 +311,7 @@ import {
|
|
|
305
311
|
withContext,
|
|
306
312
|
withLogContext,
|
|
307
313
|
withSpan
|
|
308
|
-
} from "./chunk-
|
|
314
|
+
} from "./chunk-P6I7LFKC.js";
|
|
309
315
|
import {
|
|
310
316
|
continueTrace
|
|
311
317
|
} from "./chunk-6GWA276C.js";
|
|
@@ -313,10 +319,10 @@ import "./chunk-OOUNJNMR.js";
|
|
|
313
319
|
import "./chunk-H4HBKISO.js";
|
|
314
320
|
import {
|
|
315
321
|
JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE
|
|
316
|
-
} from "./chunk-
|
|
322
|
+
} from "./chunk-K3U5447S.js";
|
|
317
323
|
import {
|
|
318
324
|
JUNIOR_VERSION
|
|
319
|
-
} from "./chunk-
|
|
325
|
+
} from "./chunk-NNRV4T2C.js";
|
|
320
326
|
import "./chunk-MLKGABMK.js";
|
|
321
327
|
|
|
322
328
|
// src/app.ts
|
|
@@ -1233,6 +1239,11 @@ async function recoverConversationWork(args) {
|
|
|
1233
1239
|
return result;
|
|
1234
1240
|
}
|
|
1235
1241
|
|
|
1242
|
+
// src/chat/scheduled-tasks/heartbeat.ts
|
|
1243
|
+
import {
|
|
1244
|
+
createSlackSource
|
|
1245
|
+
} from "@sentry/junior-plugin-api";
|
|
1246
|
+
|
|
1236
1247
|
// src/chat/agent-dispatch/validation.ts
|
|
1237
1248
|
import {
|
|
1238
1249
|
dispatchOptionsSchema,
|
|
@@ -1467,6 +1478,264 @@ async function dispatchEventTask(args) {
|
|
|
1467
1478
|
plugin
|
|
1468
1479
|
});
|
|
1469
1480
|
}
|
|
1481
|
+
async function dispatchScheduledTask(args) {
|
|
1482
|
+
const plugin = "scheduler";
|
|
1483
|
+
const { credentialSubject, ...unboundOptions } = args.options;
|
|
1484
|
+
validateDispatchOptions({ ...unboundOptions });
|
|
1485
|
+
const boundSubject = credentialSubject ? bindScheduledTaskCredentialSubject({
|
|
1486
|
+
plugin,
|
|
1487
|
+
subject: credentialSubject
|
|
1488
|
+
}) : void 0;
|
|
1489
|
+
if (credentialSubject && !boundSubject) {
|
|
1490
|
+
throw new Error("Dispatch credentialSubject is not valid for this action");
|
|
1491
|
+
}
|
|
1492
|
+
const options = {
|
|
1493
|
+
...unboundOptions,
|
|
1494
|
+
...boundSubject ? { credentialSubject: boundSubject } : {}
|
|
1495
|
+
};
|
|
1496
|
+
return await dispatch({
|
|
1497
|
+
conversationWorkQueue: args.conversationWorkQueue,
|
|
1498
|
+
nowMs: args.nowMs,
|
|
1499
|
+
options,
|
|
1500
|
+
plugin
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
async function getScheduledTaskDispatch(id) {
|
|
1504
|
+
return await getPluginDispatchProjection({ plugin: "scheduler", id });
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// src/chat/scheduled-tasks/heartbeat.ts
|
|
1508
|
+
var SCHEDULED_TASK_HEARTBEAT_LIMIT = 10;
|
|
1509
|
+
var SCHEDULE_FREQUENCY_COPY = {
|
|
1510
|
+
daily: { label: "Daily", unit: "day" },
|
|
1511
|
+
weekly: { label: "Weekly", unit: "week" },
|
|
1512
|
+
monthly: { label: "Monthly", unit: "month" },
|
|
1513
|
+
yearly: { label: "Yearly", unit: "year" }
|
|
1514
|
+
};
|
|
1515
|
+
function singleLineMetadataValue(value) {
|
|
1516
|
+
return value.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
1517
|
+
}
|
|
1518
|
+
function buildDispatchMetadata(args) {
|
|
1519
|
+
const creator = sanitizeScheduledTaskPrincipal(args.task.createdBy);
|
|
1520
|
+
if (!args.task.task.text?.trim()) {
|
|
1521
|
+
throw new Error("Scheduled task text is required");
|
|
1522
|
+
}
|
|
1523
|
+
return {
|
|
1524
|
+
creatorSlackUserId: creator.slackUserId,
|
|
1525
|
+
runId: args.run.id,
|
|
1526
|
+
schedule: singleLineMetadataValue(args.task.schedule.description),
|
|
1527
|
+
scheduleKind: args.task.schedule.kind,
|
|
1528
|
+
scheduledFor: new Date(args.run.scheduledForMs).toISOString(),
|
|
1529
|
+
runningAt: new Date(args.nowMs).toISOString(),
|
|
1530
|
+
taskId: args.task.id,
|
|
1531
|
+
timezone: args.task.schedule.timezone,
|
|
1532
|
+
...args.task.schedule.recurrence ? {
|
|
1533
|
+
recurrenceFrequency: args.task.schedule.recurrence.frequency,
|
|
1534
|
+
recurrenceInterval: String(args.task.schedule.recurrence.interval),
|
|
1535
|
+
recurrenceStartDate: args.task.schedule.recurrence.startDate
|
|
1536
|
+
} : {}
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
function replyAttribution(task) {
|
|
1540
|
+
if (task.schedule.kind === "one_off") {
|
|
1541
|
+
return { label: "Scheduled task", detail: "One-time" };
|
|
1542
|
+
}
|
|
1543
|
+
const recurrence = task.schedule.recurrence;
|
|
1544
|
+
if (!recurrence) {
|
|
1545
|
+
return { label: "Scheduled task", detail: "Recurring" };
|
|
1546
|
+
}
|
|
1547
|
+
const frequency = SCHEDULE_FREQUENCY_COPY[recurrence.frequency];
|
|
1548
|
+
return recurrence.interval === 1 ? { label: "Scheduled task", detail: frequency.label } : {
|
|
1549
|
+
label: "Scheduled task",
|
|
1550
|
+
detail: `Every ${recurrence.interval} ${frequency.unit}s`
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
function dispatchSource(task) {
|
|
1554
|
+
return createSlackSource({
|
|
1555
|
+
teamId: task.destination.teamId,
|
|
1556
|
+
channelId: task.destination.channelId,
|
|
1557
|
+
visibility: task.conversationAccess.visibility
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
function shouldSkipRun(task, run) {
|
|
1561
|
+
if (task.status === "deleted") {
|
|
1562
|
+
return `Scheduled task ${task.id} was deleted before the run started.`;
|
|
1563
|
+
}
|
|
1564
|
+
if (task.status !== "active") {
|
|
1565
|
+
return `Scheduled task ${task.id} was ${task.status} before the run started.`;
|
|
1566
|
+
}
|
|
1567
|
+
if (task.nextRunAtMs !== run.scheduledForMs && task.runNowAtMs !== run.scheduledForMs) {
|
|
1568
|
+
return `Scheduled task ${task.id} no longer targets ${new Date(run.scheduledForMs).toISOString()}.`;
|
|
1569
|
+
}
|
|
1570
|
+
return void 0;
|
|
1571
|
+
}
|
|
1572
|
+
async function applyDispatchResult(args) {
|
|
1573
|
+
if (args.dispatch.status === "completed") {
|
|
1574
|
+
const completed = await args.store.markRunCompleted({
|
|
1575
|
+
completedAtMs: args.nowMs,
|
|
1576
|
+
resultMessageTs: args.dispatch.resultMessageTs,
|
|
1577
|
+
runId: args.run.id,
|
|
1578
|
+
startedAtMs: args.run.startedAtMs
|
|
1579
|
+
});
|
|
1580
|
+
if (!completed) return false;
|
|
1581
|
+
await args.store.updateTaskAfterRun({
|
|
1582
|
+
nowMs: args.nowMs,
|
|
1583
|
+
run: args.run,
|
|
1584
|
+
status: "completed"
|
|
1585
|
+
});
|
|
1586
|
+
return true;
|
|
1587
|
+
}
|
|
1588
|
+
if (args.dispatch.status === "blocked") {
|
|
1589
|
+
const blocked = await args.store.markRunBlocked({
|
|
1590
|
+
completedAtMs: args.nowMs,
|
|
1591
|
+
errorMessage: args.dispatch.errorMessage ?? "Dispatch blocked.",
|
|
1592
|
+
runId: args.run.id,
|
|
1593
|
+
startedAtMs: args.run.startedAtMs
|
|
1594
|
+
});
|
|
1595
|
+
if (!blocked) return false;
|
|
1596
|
+
await args.store.updateTaskAfterRun({
|
|
1597
|
+
errorMessage: blocked.errorMessage,
|
|
1598
|
+
nowMs: args.nowMs,
|
|
1599
|
+
run: args.run,
|
|
1600
|
+
status: "blocked"
|
|
1601
|
+
});
|
|
1602
|
+
return true;
|
|
1603
|
+
}
|
|
1604
|
+
if (args.dispatch.status === "failed") {
|
|
1605
|
+
const failed = await args.store.markRunFailed({
|
|
1606
|
+
completedAtMs: args.nowMs,
|
|
1607
|
+
errorMessage: args.dispatch.errorMessage ?? "Dispatch failed.",
|
|
1608
|
+
runId: args.run.id,
|
|
1609
|
+
startedAtMs: args.run.startedAtMs
|
|
1610
|
+
});
|
|
1611
|
+
if (!failed) return false;
|
|
1612
|
+
await args.store.updateTaskAfterRun({
|
|
1613
|
+
errorMessage: failed.errorMessage,
|
|
1614
|
+
nowMs: args.nowMs,
|
|
1615
|
+
run: args.run,
|
|
1616
|
+
status: "failed"
|
|
1617
|
+
});
|
|
1618
|
+
return true;
|
|
1619
|
+
}
|
|
1620
|
+
return false;
|
|
1621
|
+
}
|
|
1622
|
+
async function finishClaimedRun(args) {
|
|
1623
|
+
const finished = args.status === "blocked" ? await args.store.markRunBlocked({
|
|
1624
|
+
completedAtMs: args.nowMs,
|
|
1625
|
+
errorMessage: args.errorMessage,
|
|
1626
|
+
runId: args.run.id
|
|
1627
|
+
}) : await args.store.markRunFailed({
|
|
1628
|
+
completedAtMs: args.nowMs,
|
|
1629
|
+
errorMessage: args.errorMessage,
|
|
1630
|
+
runId: args.run.id,
|
|
1631
|
+
startedAtMs: args.run.startedAtMs
|
|
1632
|
+
});
|
|
1633
|
+
if (!finished) return;
|
|
1634
|
+
await args.store.updateTaskAfterRun({
|
|
1635
|
+
errorMessage: args.errorMessage,
|
|
1636
|
+
nowMs: args.nowMs,
|
|
1637
|
+
run: args.run,
|
|
1638
|
+
status: args.status
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1641
|
+
async function runScheduledTaskHeartbeat(args) {
|
|
1642
|
+
const store = createSchedulerSqlStore(getDb());
|
|
1643
|
+
let processedCount = 0;
|
|
1644
|
+
let dispatchCount = 0;
|
|
1645
|
+
for (const run of await store.listIncompleteRuns()) {
|
|
1646
|
+
if (!run.dispatchId) continue;
|
|
1647
|
+
const dispatch2 = await getScheduledTaskDispatch(run.dispatchId);
|
|
1648
|
+
if (!dispatch2) {
|
|
1649
|
+
await finishClaimedRun({
|
|
1650
|
+
errorMessage: "Scheduled task dispatch record is missing.",
|
|
1651
|
+
nowMs: args.nowMs,
|
|
1652
|
+
run,
|
|
1653
|
+
status: "failed",
|
|
1654
|
+
store
|
|
1655
|
+
});
|
|
1656
|
+
continue;
|
|
1657
|
+
}
|
|
1658
|
+
if (await applyDispatchResult({ dispatch: dispatch2, nowMs: args.nowMs, run, store })) {
|
|
1659
|
+
processedCount += 1;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
for (let index = processedCount; index < SCHEDULED_TASK_HEARTBEAT_LIMIT; index += 1) {
|
|
1663
|
+
const run = await store.claimDueRun({ nowMs: args.nowMs });
|
|
1664
|
+
if (!run) break;
|
|
1665
|
+
const task = await store.getTask(run.taskId);
|
|
1666
|
+
if (!task) {
|
|
1667
|
+
await store.markRunFailed({
|
|
1668
|
+
completedAtMs: args.nowMs,
|
|
1669
|
+
errorMessage: `Scheduled task ${run.taskId} was not found`,
|
|
1670
|
+
runId: run.id
|
|
1671
|
+
});
|
|
1672
|
+
continue;
|
|
1673
|
+
}
|
|
1674
|
+
const skippedReason = shouldSkipRun(task, run);
|
|
1675
|
+
if (skippedReason) {
|
|
1676
|
+
await store.markRunSkipped({
|
|
1677
|
+
completedAtMs: args.nowMs,
|
|
1678
|
+
errorMessage: skippedReason,
|
|
1679
|
+
runId: run.id
|
|
1680
|
+
});
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1683
|
+
let metadata;
|
|
1684
|
+
try {
|
|
1685
|
+
metadata = buildDispatchMetadata({ nowMs: args.nowMs, run, task });
|
|
1686
|
+
} catch (error) {
|
|
1687
|
+
await finishClaimedRun({
|
|
1688
|
+
errorMessage: error instanceof Error ? `Scheduled task dispatch metadata could not be built: ${error.message}` : "Scheduled task dispatch metadata could not be built.",
|
|
1689
|
+
nowMs: args.nowMs,
|
|
1690
|
+
run,
|
|
1691
|
+
status: "blocked",
|
|
1692
|
+
store
|
|
1693
|
+
});
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
let dispatch2;
|
|
1697
|
+
try {
|
|
1698
|
+
dispatch2 = await dispatchScheduledTask({
|
|
1699
|
+
conversationWorkQueue: args.conversationWorkQueue,
|
|
1700
|
+
nowMs: args.nowMs,
|
|
1701
|
+
options: {
|
|
1702
|
+
idempotencyKey: run.id,
|
|
1703
|
+
...task.credentialMode === "creator" ? {
|
|
1704
|
+
credentialSubject: {
|
|
1705
|
+
type: "user",
|
|
1706
|
+
userId: task.createdBy.slackUserId,
|
|
1707
|
+
allowedWhen: "scheduled-task",
|
|
1708
|
+
taskId: task.id
|
|
1709
|
+
}
|
|
1710
|
+
} : {},
|
|
1711
|
+
destination: task.destination,
|
|
1712
|
+
destinationVisibility: task.conversationAccess.visibility,
|
|
1713
|
+
input: task.task.text,
|
|
1714
|
+
metadata,
|
|
1715
|
+
replyAttribution: replyAttribution(task),
|
|
1716
|
+
source: dispatchSource(task)
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
} catch (error) {
|
|
1720
|
+
await finishClaimedRun({
|
|
1721
|
+
errorMessage: error instanceof Error ? `Scheduled task dispatch could not be created: ${error.message}` : "Scheduled task dispatch could not be created.",
|
|
1722
|
+
nowMs: args.nowMs,
|
|
1723
|
+
run,
|
|
1724
|
+
status: "blocked",
|
|
1725
|
+
store
|
|
1726
|
+
});
|
|
1727
|
+
continue;
|
|
1728
|
+
}
|
|
1729
|
+
await store.markRunDispatched({
|
|
1730
|
+
claimedAtMs: run.claimedAtMs,
|
|
1731
|
+
dispatchId: dispatch2.id,
|
|
1732
|
+
nowMs: args.nowMs,
|
|
1733
|
+
runId: run.id
|
|
1734
|
+
});
|
|
1735
|
+
dispatchCount += 1;
|
|
1736
|
+
}
|
|
1737
|
+
return dispatchCount;
|
|
1738
|
+
}
|
|
1470
1739
|
|
|
1471
1740
|
// src/chat/agent-dispatch/heartbeat.ts
|
|
1472
1741
|
var DEFAULT_PLUGIN_LIMIT = 25;
|
|
@@ -1568,6 +1837,19 @@ async function runHeartbeat(args) {
|
|
|
1568
1837
|
conversationWorkQueue: queue,
|
|
1569
1838
|
nowMs: args.nowMs
|
|
1570
1839
|
});
|
|
1840
|
+
try {
|
|
1841
|
+
const dispatchCount = await runScheduledTaskHeartbeat({
|
|
1842
|
+
conversationWorkQueue: queue,
|
|
1843
|
+
nowMs: args.nowMs
|
|
1844
|
+
});
|
|
1845
|
+
if (dispatchCount > 0) {
|
|
1846
|
+
logInfo("scheduled_tasks.heartbeat.dispatched", {
|
|
1847
|
+
"app.dispatch.count": dispatchCount
|
|
1848
|
+
});
|
|
1849
|
+
}
|
|
1850
|
+
} catch (error) {
|
|
1851
|
+
logException(error, "scheduled_tasks.heartbeat.failed");
|
|
1852
|
+
}
|
|
1571
1853
|
await runPluginHeartbeats({
|
|
1572
1854
|
conversationWorkQueue: queue,
|
|
1573
1855
|
nowMs: args.nowMs
|
|
@@ -6256,7 +6538,7 @@ function createJuniorRuntimeServices(overrides = {}) {
|
|
|
6256
6538
|
}
|
|
6257
6539
|
|
|
6258
6540
|
// src/chat/runtime/reply-executor.ts
|
|
6259
|
-
import { createSlackSource } from "@sentry/junior-plugin-api";
|
|
6541
|
+
import { createSlackSource as createSlackSource2 } from "@sentry/junior-plugin-api";
|
|
6260
6542
|
|
|
6261
6543
|
// src/chat/slack/message.ts
|
|
6262
6544
|
function getSlackMessageTs(message) {
|
|
@@ -6546,7 +6828,7 @@ function createReplyToThread(deps) {
|
|
|
6546
6828
|
const assistantThreadContext = getAssistantThreadContext(message);
|
|
6547
6829
|
const messageTs = getMessageTs(message);
|
|
6548
6830
|
const teamId = destination.teamId;
|
|
6549
|
-
const source = options.execution?.source ??
|
|
6831
|
+
const source = options.execution?.source ?? createSlackSource2({
|
|
6550
6832
|
channelId: channelId ?? destination.channelId,
|
|
6551
6833
|
messageTs,
|
|
6552
6834
|
teamId,
|
|
@@ -8955,7 +9237,7 @@ async function ingestResourceEvent(input, options) {
|
|
|
8955
9237
|
// src/chat/event-tasks/ingest.ts
|
|
8956
9238
|
import { createHash as createHash2 } from "crypto";
|
|
8957
9239
|
import {
|
|
8958
|
-
createSlackSource as
|
|
9240
|
+
createSlackSource as createSlackSource3,
|
|
8959
9241
|
RESOURCE_EVENT_SUMMARY_MAX_LENGTH,
|
|
8960
9242
|
RESOURCE_EVENT_TEXT_MAX_LENGTH,
|
|
8961
9243
|
resourceEventSchema as resourceEventSchema2
|
|
@@ -9018,7 +9300,7 @@ async function ingestEventTasks(input, options) {
|
|
|
9018
9300
|
destination: task.destination,
|
|
9019
9301
|
destinationVisibility: task.destinationVisibility,
|
|
9020
9302
|
input: eventInput(task, event),
|
|
9021
|
-
source:
|
|
9303
|
+
source: createSlackSource3({
|
|
9022
9304
|
teamId: task.destination.teamId,
|
|
9023
9305
|
channelId: task.destination.channelId,
|
|
9024
9306
|
visibility: task.destinationVisibility
|
|
@@ -9193,6 +9475,7 @@ function dashboardHostRoutePaths(dashboard) {
|
|
|
9193
9475
|
`${pagePath("locations")}/*`,
|
|
9194
9476
|
peoplePath,
|
|
9195
9477
|
`${peoplePath}/*`,
|
|
9478
|
+
pagePath("tasks"),
|
|
9196
9479
|
pagePath("system"),
|
|
9197
9480
|
`${pagePath("system")}/*`,
|
|
9198
9481
|
pagePath("plugins"),
|
|
@@ -9216,6 +9499,8 @@ function dashboardHostRoutePaths(dashboard) {
|
|
|
9216
9499
|
"/api/plugin-reports",
|
|
9217
9500
|
"/api/user-pages",
|
|
9218
9501
|
"/api/user-pages/*",
|
|
9502
|
+
"/api/tasks",
|
|
9503
|
+
"/api/tasks/*",
|
|
9219
9504
|
"/api/skills",
|
|
9220
9505
|
"/api/stats",
|
|
9221
9506
|
"/api/conversations",
|
|
@@ -9349,6 +9634,7 @@ async function createApp(options) {
|
|
|
9349
9634
|
const previousPlugins = setPlugins(plugins);
|
|
9350
9635
|
const previousConfigDefaults = getConfigDefaults();
|
|
9351
9636
|
const previousSlackReactionConfig = getSlackReactionConfig();
|
|
9637
|
+
const previousSandboxResources = getSandboxResourceConfig();
|
|
9352
9638
|
const previousDashboardLinkOptions = setDashboardConversationLinkOptions(dashboard);
|
|
9353
9639
|
let pluginRoutes = [];
|
|
9354
9640
|
let pluginApiRoutes = [];
|
|
@@ -9383,6 +9669,7 @@ async function createApp(options) {
|
|
|
9383
9669
|
sandboxEgressTracePropagationDomains = normalizeSandboxEgressTracePropagationDomains(
|
|
9384
9670
|
options?.sandbox?.egressTracePropagationDomains
|
|
9385
9671
|
);
|
|
9672
|
+
setSandboxResourceConfig(options?.sandbox);
|
|
9386
9673
|
setConfigDefaults(options?.configDefaults);
|
|
9387
9674
|
if (options?.slack) {
|
|
9388
9675
|
setSlackReactionConfig(options.slack);
|
|
@@ -9404,6 +9691,7 @@ async function createApp(options) {
|
|
|
9404
9691
|
setPlugins(previousPlugins);
|
|
9405
9692
|
setConfigDefaults(previousConfigDefaults);
|
|
9406
9693
|
setSlackReactionConfig(previousSlackReactionConfig);
|
|
9694
|
+
setSandboxResourceConfig(previousSandboxResources);
|
|
9407
9695
|
setDashboardConversationLinkOptions(previousDashboardLinkOptions);
|
|
9408
9696
|
throw error;
|
|
9409
9697
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pluginCatalogRuntime
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-A6QQPVSH.js";
|
|
4
|
+
import "./chunk-CZQ2DSQZ.js";
|
|
5
5
|
import "./chunk-77VDLF3Z.js";
|
|
6
6
|
import "./chunk-HZF5P5UN.js";
|
|
7
7
|
import "./chunk-F3B2YJ76.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-P6I7LFKC.js";
|
|
9
9
|
import "./chunk-6GWA276C.js";
|
|
10
10
|
import "./chunk-OOUNJNMR.js";
|
|
11
11
|
import "./chunk-H4HBKISO.js";
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-K3U5447S.js";
|
|
13
|
+
import "./chunk-NNRV4T2C.js";
|
|
14
14
|
import "./chunk-MLKGABMK.js";
|
|
15
15
|
export {
|
|
16
16
|
pluginCatalogRuntime
|
|
@@ -23,3 +23,21 @@ export declare function dispatchEventTask(args: {
|
|
|
23
23
|
id: string;
|
|
24
24
|
status: "already_exists" | "created";
|
|
25
25
|
}>;
|
|
26
|
+
/** Create and enqueue one core-owned scheduled task dispatch. */
|
|
27
|
+
export declare function dispatchScheduledTask(args: {
|
|
28
|
+
conversationWorkQueue: ConversationWorkQueue;
|
|
29
|
+
nowMs: number;
|
|
30
|
+
options: Omit<SlackDispatchOptions, "credentialSubject"> & {
|
|
31
|
+
credentialSubject?: {
|
|
32
|
+
allowedWhen: "scheduled-task";
|
|
33
|
+
taskId: string;
|
|
34
|
+
type: "user";
|
|
35
|
+
userId: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
}): Promise<{
|
|
39
|
+
id: string;
|
|
40
|
+
status: "already_exists" | "created";
|
|
41
|
+
}>;
|
|
42
|
+
/** Read the bounded outcome for one core-owned scheduled task dispatch. */
|
|
43
|
+
export declare function getScheduledTaskDispatch(id: string): Promise<import("./types").DispatchProjection | undefined>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ResourceEvent } from "@sentry/junior-plugin-api";
|
|
1
|
+
import { type ResourceEvent, type User } from "@sentry/junior-plugin-api";
|
|
2
2
|
import type { JuniorDatabase } from "@/db/db";
|
|
3
3
|
import { type EventTask } from "./types";
|
|
4
4
|
/** Read one event task by id. */
|
|
@@ -11,5 +11,11 @@ export declare function saveEventTask(db: JuniorDatabase, task: EventTask): Prom
|
|
|
11
11
|
export declare function deleteEventTask(db: JuniorDatabase, id: string): Promise<EventTask | undefined>;
|
|
12
12
|
/** List event tasks in one Slack workspace. */
|
|
13
13
|
export declare function listEventTasksForTeam(db: JuniorDatabase, teamId: string): Promise<EventTask[]>;
|
|
14
|
+
/** Return whether one event task was created by a viewer-linked Slack identity. */
|
|
15
|
+
export declare function eventTaskBelongsToUser(task: EventTask, user: User): boolean;
|
|
16
|
+
/** List a bounded newest-first page of event tasks created by one user. */
|
|
17
|
+
export declare function listEventTasksCreatedBy(db: JuniorDatabase, user: User, limit: number): Promise<EventTask[]>;
|
|
18
|
+
/** List event tasks whose current Slack destination is public. */
|
|
19
|
+
export declare function listPublicEventTasksForTeams(db: JuniorDatabase, teamIds: string[], limit: number): Promise<EventTask[]>;
|
|
14
20
|
/** Find every task matching one normalized resource event. */
|
|
15
21
|
export declare function findMatchingEventTasks(db: JuniorDatabase, event: ResourceEvent, teamId: string): Promise<EventTask[]>;
|
|
@@ -102,6 +102,7 @@ export declare function eventTaskMatchesDestination(task: EventTask, destination
|
|
|
102
102
|
}): boolean;
|
|
103
103
|
/** Load one task only when it belongs to this Slack channel or DM. */
|
|
104
104
|
export declare function writableEventTask(context: ToolRuntimeContext, id: string): Promise<EventTask>;
|
|
105
|
+
export declare function eventTaskTriggerAvailable(task: EventTask, catalog: ResourceEventCatalog): boolean;
|
|
105
106
|
/** Project an event task into the bounded tool-result shape. */
|
|
106
107
|
export declare function compactEventTask(task: EventTask, catalog: ResourceEventCatalog): {
|
|
107
108
|
id: string;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
export interface SandboxResourceConfig {
|
|
2
|
+
vcpus?: number;
|
|
3
|
+
}
|
|
4
|
+
/** Return the app-level sandbox sizing override. */
|
|
5
|
+
export declare function getSandboxResourceConfig(): {
|
|
6
|
+
vcpus: number;
|
|
7
|
+
} | undefined;
|
|
8
|
+
/** Replace app-level sandbox sizing and return the previous setting. */
|
|
9
|
+
export declare function setSandboxResourceConfig(config?: SandboxResourceConfig): {
|
|
10
|
+
vcpus: number;
|
|
11
|
+
} | undefined;
|
|
12
|
+
/** Resolve app-level sandbox sizing, falling back to the legacy environment setting. */
|
|
2
13
|
export declare function getSandboxResources(): {
|
|
3
14
|
vcpus: number;
|
|
4
15
|
} | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Calendar arithmetic for core-owned scheduled tasks. */
|
|
2
|
+
import type { ScheduledLocalTime, ScheduledTask, ScheduledTaskRecurrence } from "./types";
|
|
3
|
+
export interface ZonedDateTimeParts {
|
|
4
|
+
day: number;
|
|
5
|
+
hour: number;
|
|
6
|
+
minute: number;
|
|
7
|
+
month: number;
|
|
8
|
+
second: number;
|
|
9
|
+
weekday: number;
|
|
10
|
+
year: number;
|
|
11
|
+
}
|
|
12
|
+
/** Resolve a UTC timestamp into calendar parts for a named time zone. */
|
|
13
|
+
export declare function getZonedDateTimeParts(timestampMs: number, timezone: string): ZonedDateTimeParts;
|
|
14
|
+
/** Resolve local time, rejecting DST gaps and choosing the earlier instant in a fold. */
|
|
15
|
+
export declare function resolveLocalScheduleAtMs(args: {
|
|
16
|
+
date: string;
|
|
17
|
+
time: ScheduledLocalTime;
|
|
18
|
+
timezone: string;
|
|
19
|
+
}): number | undefined;
|
|
20
|
+
/** Compute the first recurring calendar occurrence strictly after a timestamp. */
|
|
21
|
+
export declare function getFirstRunAtMs(args: {
|
|
22
|
+
afterMs: number;
|
|
23
|
+
recurrence: ScheduledTaskRecurrence;
|
|
24
|
+
timezone: string;
|
|
25
|
+
}): number | undefined;
|
|
26
|
+
/** Return the next fire time after a completed run, when the task recurs. */
|
|
27
|
+
export declare function getNextRunAtMs(task: ScheduledTask, scheduledForMs: number, afterMs?: number): number | undefined;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ConversationWorkQueue } from "@/chat/task-execution/queue";
|
|
2
|
+
/** Reconcile completed dispatches and enqueue a bounded batch of due tasks. */
|
|
3
|
+
export declare function runScheduledTaskHeartbeat(args: {
|
|
4
|
+
conversationWorkQueue: ConversationWorkQueue;
|
|
5
|
+
nowMs: number;
|
|
6
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Presentation helpers for persisted scheduled-task creators. */
|
|
2
|
+
import type { ScheduledTaskPrincipal } from "./types";
|
|
3
|
+
/** Keep scheduler creator metadata from promoting Slack IDs into display names. */
|
|
4
|
+
export declare function sanitizeScheduledTaskPrincipal(principal: ScheduledTaskPrincipal): ScheduledTaskPrincipal;
|
|
5
|
+
/** Render scheduler creator metadata without inventing human profile fields. */
|
|
6
|
+
export declare function scheduledTaskPrincipalLabel(principal: ScheduledTaskPrincipal): string;
|