@sentry/junior 0.232.0 → 0.234.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-n9qfV697.js → agent-hooks-BcH6E48y.js} +89 -12
- package/dist/{agent-runner-D_FVvrwA.js → agent-runner-DUkGlK89.js} +224 -768
- package/dist/api/schema.d.ts +538 -2
- package/dist/api/schema.js +4 -4
- package/dist/api.js +230 -19
- package/dist/app.js +31 -21
- package/dist/{briefs-B7wDx-LM.js → briefs-lyAQbDxJ.js} +4 -4
- package/dist/{catalog-runtime-FU8TmK-W.js → catalog-runtime-BSgsPVnr.js} +1 -1
- package/dist/{checkpoint-DuA1tIcd.js → checkpoint-BNfXlq_1.js} +7 -7
- package/dist/cli/chat.js +13 -13
- package/dist/cli/check.js +3 -3
- package/dist/cli/main.js +1 -1
- package/dist/cli/plugins.js +3 -3
- package/dist/cli/snapshot-create.js +3 -3
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-BMqP14EE.js → client-BX5lJRqW.js} +2 -2
- package/dist/{config-Q7ayKDYh.js → config-DuCzUoCo.js} +2 -2
- package/dist/{conversation-DsuDtoYR.js → conversation-CPjHYOV5.js} +13 -2
- package/dist/{conversation-privacy-DNNsgprf.js → conversation-privacy-CSxvdSoV.js} +1 -1
- package/dist/{credential-sync-DbgAGIhd.js → credential-sync-BO4DfH9a.js} +13 -13
- package/dist/{executor-DDonSWxn.js → executor--jWf-Nnm.js} +1 -1
- package/dist/{images-Bj8PcvZ5.js → images-BaL19wFC.js} +3 -3
- package/dist/instrumentation.js +2 -2
- package/dist/{job-queue-Dqc7qQbR.js → job-queue-cwHVOwVZ.js} +1 -1
- package/dist/{logging-X4U7SInw.js → logging-Cox1Mgcv.js} +1 -1
- package/dist/nitro.js +3 -3
- package/dist/{oauth-authorization-CetcZcwQ.js → oauth-authorization-CC8a1JKP.js} +1 -1
- package/dist/{oauth-callback-server-o34WSoGm.js → oauth-callback-server-Z7QSt416.js} +2 -2
- package/dist/{pending-auth-XoxEa4O5.js → pending-auth-DQhC3eSR.js} +1 -1
- package/dist/{profile-DzqqgpDo.js → profile-BdApelHS.js} +4 -4
- package/dist/{prompt-D5RPLy92.js → prompt-3D0sSbTC.js} +1 -1
- package/dist/{registry-RrIfDnkS.js → registry-DiY6B8CN.js} +1 -1
- package/dist/{resolve-Ccu6uGtp.js → resolve-VpJoiDpc.js} +2 -2
- package/dist/{runner-DDQCEV1P.js → runner-BIMegnPE.js} +9 -9
- package/dist/{sandbox-egress-signals-CT3xOtNG.js → sandbox-egress-signals-Cbtxe492.js} +1 -1
- package/dist/{schema-B-Taar1W.js → schema-CxwnlTDN.js} +4 -117
- package/dist/{skills-NB_I9BuR.js → skills-WttpPJUy.js} +2 -2
- package/dist/{spawn-DmwIhiNu.js → spawn-DhfMKt4y.js} +2 -2
- package/dist/{task-queue-B5CERq_E.js → task-queue-CZqUNJD0.js} +3 -3
- package/dist/{task-runner-COivEGS3.js → task-runner-BZaqoUCT.js} +16 -13
- package/dist/{thread-state-C7yyfiVM.js → thread-state-8tXZhu0y.js} +5 -5
- package/dist/{turn-failure-response-D990svo-.js → turn-failure-response-DFJ9L9NQ.js} +8 -8
- package/dist/{turn-lifecycle-C-LUNJC6.js → turn-lifecycle-WbpTUQ_r.js} +1 -1
- package/dist/{turn-session-routing-CoF0GbaY.js → turn-session-routing--EhI76rH.js} +1 -1
- package/dist/types-Du-HbEun.js +621 -0
- package/dist/{validation-f0y71ety.js → validation-0F9IgG3b.js} +1 -1
- package/dist/{version-CkRTIRkV.js → version-A7-RRBOE.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{web-authorization-BBwQsNCZ.js → web-authorization-BJggXofy.js} +6 -6
- package/dist/{web-input-Bkn-JGWd.js → web-input-B-siN5Dr.js} +212 -164
- package/dist/web-message-id-CVVCTWUb.js +464 -0
- package/dist/{work-vWPq9P5x.js → work-CNc0ejGG.js} +7 -7
- package/dist/{worker-BgZog5Jp.js → worker-BHbqpUAu.js} +5 -5
- package/package.json +5 -5
- package/dist/web-message-id-xPI_EFSC.js +0 -239
|
@@ -0,0 +1,621 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { actorUserIdSchema, destinationVisibilitySchema, eventMatchSchema, eventTypeSchema, slackDestinationSchema, taskOutcomeSchema } from "@sentry/junior-plugin-api";
|
|
3
|
+
//#region src/chat/task-outcomes-schema.ts
|
|
4
|
+
const taskMessageDestinationInputSchema = z.enum(["current_conversation", "task_creator"]).describe("Where to send the message. Use current_conversation for posts, digests, summaries, and channel reminders. Use task_creator only when the user asks for a direct reminder or notification.");
|
|
5
|
+
/** Input accepted by task authoring tools before a user becomes a DM Destination. */
|
|
6
|
+
const taskOutcomeInputSchema = z.object({
|
|
7
|
+
action: z.literal("send_message"),
|
|
8
|
+
destination: taskMessageDestinationInputSchema
|
|
9
|
+
}).strict();
|
|
10
|
+
/** Validate the persisted Slack creator identity for an event automation. */
|
|
11
|
+
const eventAutomationPrincipalSchema = z.object({
|
|
12
|
+
slackUserId: actorUserIdSchema,
|
|
13
|
+
fullName: z.string().optional(),
|
|
14
|
+
userName: z.string().optional()
|
|
15
|
+
}).strict();
|
|
16
|
+
/** Validate one persisted event-automation selector and its presentation metadata. */
|
|
17
|
+
const eventAutomationTriggerSchema = z.object({
|
|
18
|
+
events: z.array(eventTypeSchema).min(1),
|
|
19
|
+
label: z.string().min(1),
|
|
20
|
+
match: eventMatchSchema.optional(),
|
|
21
|
+
namespace: z.string().min(1),
|
|
22
|
+
identifier: z.string().min(1).max(300),
|
|
23
|
+
resourceType: z.string().min(1)
|
|
24
|
+
}).strict();
|
|
25
|
+
/** Event automations target a Slack channel or DM, never a message thread. */
|
|
26
|
+
const eventAutomationDestinationSchema = slackDestinationSchema.omit({ threadTs: true });
|
|
27
|
+
const eventAutomationOutcomeSchema = taskOutcomeSchema.extend({ destination: eventAutomationDestinationSchema });
|
|
28
|
+
/** Validate one persisted event automation. */
|
|
29
|
+
const eventAutomationSchema = z.object({
|
|
30
|
+
id: z.string().min(1),
|
|
31
|
+
createdAtMs: z.number().finite(),
|
|
32
|
+
createdBy: eventAutomationPrincipalSchema,
|
|
33
|
+
credentialMode: z.enum(["system", "creator"]),
|
|
34
|
+
destination: eventAutomationDestinationSchema,
|
|
35
|
+
destinationVisibility: destinationVisibilitySchema,
|
|
36
|
+
/** Explicit visible effects after successful work. An empty list is silent. */
|
|
37
|
+
outcomes: z.array(eventAutomationOutcomeSchema).max(5),
|
|
38
|
+
task: z.object({ text: z.string().min(1) }).strict(),
|
|
39
|
+
trigger: eventAutomationTriggerSchema
|
|
40
|
+
}).strict();
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/chat/scheduled-automations/cadence.ts
|
|
43
|
+
const FORMATTERS = /* @__PURE__ */ new Map();
|
|
44
|
+
function getFormatter(timezone) {
|
|
45
|
+
const existing = FORMATTERS.get(timezone);
|
|
46
|
+
if (existing) return existing;
|
|
47
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
48
|
+
timeZone: timezone,
|
|
49
|
+
hour12: false,
|
|
50
|
+
year: "numeric",
|
|
51
|
+
month: "2-digit",
|
|
52
|
+
day: "2-digit",
|
|
53
|
+
hour: "2-digit",
|
|
54
|
+
minute: "2-digit",
|
|
55
|
+
second: "2-digit"
|
|
56
|
+
});
|
|
57
|
+
FORMATTERS.set(timezone, formatter);
|
|
58
|
+
return formatter;
|
|
59
|
+
}
|
|
60
|
+
function normalizeHour(hour) {
|
|
61
|
+
return hour === 24 ? 0 : hour;
|
|
62
|
+
}
|
|
63
|
+
function getLocalDateWeekday(date) {
|
|
64
|
+
return new Date(Date.UTC(date.year, date.month - 1, date.day)).getUTCDay();
|
|
65
|
+
}
|
|
66
|
+
function getWeekStart(date) {
|
|
67
|
+
return addDays(date, -((getLocalDateWeekday(date) + 6) % 7));
|
|
68
|
+
}
|
|
69
|
+
/** Resolve a UTC timestamp into calendar parts for a named time zone. */
|
|
70
|
+
function getZonedDateTimeParts(timestampMs, timezone) {
|
|
71
|
+
const parts = getFormatter(timezone).formatToParts(new Date(timestampMs));
|
|
72
|
+
const values = new Map(parts.map((part) => [part.type, part.value]));
|
|
73
|
+
const year = Number(values.get("year"));
|
|
74
|
+
const month = Number(values.get("month"));
|
|
75
|
+
const day = Number(values.get("day"));
|
|
76
|
+
return {
|
|
77
|
+
year,
|
|
78
|
+
month,
|
|
79
|
+
day,
|
|
80
|
+
hour: normalizeHour(Number(values.get("hour"))),
|
|
81
|
+
minute: Number(values.get("minute")),
|
|
82
|
+
second: Number(values.get("second")),
|
|
83
|
+
weekday: getLocalDateWeekday({
|
|
84
|
+
year,
|
|
85
|
+
month,
|
|
86
|
+
day
|
|
87
|
+
})
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function getTimeZoneOffsetMs(timestampMs, timezone) {
|
|
91
|
+
const parts = getZonedDateTimeParts(timestampMs, timezone);
|
|
92
|
+
return Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second) - timestampMs;
|
|
93
|
+
}
|
|
94
|
+
function localDateTimeToTimestampMs(args) {
|
|
95
|
+
const localAsUtcMs = Date.UTC(args.date.year, args.date.month - 1, args.date.day, args.time.hour, args.time.minute, 0);
|
|
96
|
+
const offsets = /* @__PURE__ */ new Set();
|
|
97
|
+
for (const probeDeltaMs of [
|
|
98
|
+
-1296e5,
|
|
99
|
+
-432e5,
|
|
100
|
+
0,
|
|
101
|
+
432e5,
|
|
102
|
+
1296e5
|
|
103
|
+
]) offsets.add(getTimeZoneOffsetMs(localAsUtcMs + probeDeltaMs, args.timezone));
|
|
104
|
+
const matches = [...offsets].map((offsetMs) => localAsUtcMs - offsetMs).filter((timestampMs) => {
|
|
105
|
+
const parts = getZonedDateTimeParts(timestampMs, args.timezone);
|
|
106
|
+
return parts.year === args.date.year && parts.month === args.date.month && parts.day === args.date.day && parts.hour === args.time.hour && parts.minute === args.time.minute;
|
|
107
|
+
});
|
|
108
|
+
if (matches.length === 0) return;
|
|
109
|
+
return Math.min(...matches);
|
|
110
|
+
}
|
|
111
|
+
/** Resolve local time, rejecting DST gaps and choosing the earlier instant in a fold. */
|
|
112
|
+
function resolveLocalScheduleAtMs(args) {
|
|
113
|
+
const date = parseLocalDate(args.date);
|
|
114
|
+
if (!date) return;
|
|
115
|
+
return localDateTimeToTimestampMs({
|
|
116
|
+
date,
|
|
117
|
+
time: args.time,
|
|
118
|
+
timezone: args.timezone
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function daysBetween(left, right) {
|
|
122
|
+
return Math.floor((Date.UTC(right.year, right.month - 1, right.day) - Date.UTC(left.year, left.month - 1, left.day)) / 864e5);
|
|
123
|
+
}
|
|
124
|
+
function weeklyRecurrenceMatchesDate(date, start, recurrence) {
|
|
125
|
+
if (compareDate(date, start) < 0) return false;
|
|
126
|
+
return normalizeWeekdays(recurrence.weekdays).includes(getLocalDateWeekday(date)) && Math.floor(daysBetween(getWeekStart(start), getWeekStart(date)) / 7) % recurrence.interval === 0;
|
|
127
|
+
}
|
|
128
|
+
function greatestCommonDivisor(left, right) {
|
|
129
|
+
let a = Math.abs(left);
|
|
130
|
+
let b = Math.abs(right);
|
|
131
|
+
while (b !== 0) [a, b] = [b, a % b];
|
|
132
|
+
return a;
|
|
133
|
+
}
|
|
134
|
+
function findNextRunAtMs(args) {
|
|
135
|
+
const start = parseLocalDate(args.recurrence.startDate);
|
|
136
|
+
const interval = args.recurrence.interval;
|
|
137
|
+
if (!start || !Number.isInteger(interval) || interval <= 0) return;
|
|
138
|
+
const searchFrom = compareDate(args.searchFrom, start) < 0 ? start : args.searchFrom;
|
|
139
|
+
if (args.recurrence.frequency === "daily") {
|
|
140
|
+
const offsetDays = daysBetween(start, searchFrom);
|
|
141
|
+
let candidateDate = addDays(start, Math.ceil(offsetDays / interval) * interval);
|
|
142
|
+
const gregorianCycleDays = 146097;
|
|
143
|
+
const candidateCount = gregorianCycleDays / greatestCommonDivisor(gregorianCycleDays, interval);
|
|
144
|
+
for (let attempts = 0; attempts < candidateCount; attempts += 1) {
|
|
145
|
+
const candidate = buildCandidate({
|
|
146
|
+
date: candidateDate,
|
|
147
|
+
recurrence: args.recurrence,
|
|
148
|
+
timezone: args.timezone
|
|
149
|
+
});
|
|
150
|
+
if (candidate !== void 0 && candidate > args.afterMs) return candidate;
|
|
151
|
+
candidateDate = addDays(candidateDate, interval);
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (args.recurrence.frequency === "weekly") {
|
|
156
|
+
if (normalizeWeekdays(args.recurrence.weekdays).length === 0) return;
|
|
157
|
+
let candidateDate = searchFrom;
|
|
158
|
+
const gregorianCycleDays = 146097;
|
|
159
|
+
const cadenceDays = interval * 7;
|
|
160
|
+
const searchDays = gregorianCycleDays * cadenceDays / greatestCommonDivisor(gregorianCycleDays, cadenceDays);
|
|
161
|
+
for (let attempts = 0; attempts < searchDays; attempts += 1) {
|
|
162
|
+
if (weeklyRecurrenceMatchesDate(candidateDate, start, args.recurrence)) {
|
|
163
|
+
const candidate = buildCandidate({
|
|
164
|
+
date: candidateDate,
|
|
165
|
+
recurrence: args.recurrence,
|
|
166
|
+
timezone: args.timezone
|
|
167
|
+
});
|
|
168
|
+
if (candidate !== void 0 && candidate > args.afterMs) return candidate;
|
|
169
|
+
}
|
|
170
|
+
candidateDate = addDays(candidateDate, 1);
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (args.recurrence.frequency === "monthly") {
|
|
175
|
+
const startMonth = start.year * 12 + start.month - 1;
|
|
176
|
+
const searchMonth = searchFrom.year * 12 + searchFrom.month - 1;
|
|
177
|
+
let candidateMonth = startMonth + Math.ceil((searchMonth - startMonth) / interval) * interval;
|
|
178
|
+
const gregorianCycleMonths = 4800;
|
|
179
|
+
const candidateCount = gregorianCycleMonths / greatestCommonDivisor(gregorianCycleMonths, interval);
|
|
180
|
+
for (let attempts = 0; attempts < candidateCount; attempts += 1) {
|
|
181
|
+
const candidateDate = {
|
|
182
|
+
year: Math.floor(candidateMonth / 12),
|
|
183
|
+
month: candidateMonth % 12 + 1,
|
|
184
|
+
day: args.recurrence.dayOfMonth ?? 0
|
|
185
|
+
};
|
|
186
|
+
if (compareDate(candidateDate, searchFrom) >= 0) {
|
|
187
|
+
const candidate = buildCandidate({
|
|
188
|
+
date: candidateDate,
|
|
189
|
+
recurrence: args.recurrence,
|
|
190
|
+
timezone: args.timezone
|
|
191
|
+
});
|
|
192
|
+
if (candidate !== void 0 && candidate > args.afterMs) return candidate;
|
|
193
|
+
}
|
|
194
|
+
candidateMonth += interval;
|
|
195
|
+
}
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
let candidateYear = start.year + Math.ceil((searchFrom.year - start.year) / interval) * interval;
|
|
199
|
+
const candidateCount = 400 / greatestCommonDivisor(400, interval);
|
|
200
|
+
for (let attempts = 0; attempts < candidateCount; attempts += 1) {
|
|
201
|
+
const candidateDate = {
|
|
202
|
+
year: candidateYear,
|
|
203
|
+
month: args.recurrence.month ?? 0,
|
|
204
|
+
day: args.recurrence.dayOfMonth ?? 0
|
|
205
|
+
};
|
|
206
|
+
if (compareDate(candidateDate, searchFrom) >= 0) {
|
|
207
|
+
const candidate = buildCandidate({
|
|
208
|
+
date: candidateDate,
|
|
209
|
+
recurrence: args.recurrence,
|
|
210
|
+
timezone: args.timezone
|
|
211
|
+
});
|
|
212
|
+
if (candidate !== void 0 && candidate > args.afterMs) return candidate;
|
|
213
|
+
}
|
|
214
|
+
candidateYear += interval;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Compute the first recurring calendar occurrence strictly after a timestamp. */
|
|
218
|
+
function getFirstRunAtMs(args) {
|
|
219
|
+
return findNextRunAtMs({
|
|
220
|
+
...args,
|
|
221
|
+
searchFrom: getLocalDate(args.afterMs, args.timezone)
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
function compareDate(left, right) {
|
|
225
|
+
return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
|
|
226
|
+
}
|
|
227
|
+
function addDays(date, days) {
|
|
228
|
+
const next = new Date(Date.UTC(date.year, date.month - 1, date.day + days));
|
|
229
|
+
return {
|
|
230
|
+
year: next.getUTCFullYear(),
|
|
231
|
+
month: next.getUTCMonth() + 1,
|
|
232
|
+
day: next.getUTCDate()
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
function daysInMonth(year, month) {
|
|
236
|
+
return new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
237
|
+
}
|
|
238
|
+
function parseLocalDate(value) {
|
|
239
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
240
|
+
if (!match) return;
|
|
241
|
+
const year = Number(match[1]);
|
|
242
|
+
const month = Number(match[2]);
|
|
243
|
+
const day = Number(match[3]);
|
|
244
|
+
if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day) || month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month)) return;
|
|
245
|
+
return {
|
|
246
|
+
year,
|
|
247
|
+
month,
|
|
248
|
+
day
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function getLocalDate(timestampMs, timezone) {
|
|
252
|
+
const parts = getZonedDateTimeParts(timestampMs, timezone);
|
|
253
|
+
return {
|
|
254
|
+
year: parts.year,
|
|
255
|
+
month: parts.month,
|
|
256
|
+
day: parts.day
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function normalizeWeekdays(values) {
|
|
260
|
+
return [...new Set((values ?? []).filter((value) => value >= 0 && value <= 6))].sort((a, b) => a - b);
|
|
261
|
+
}
|
|
262
|
+
function buildCandidate(args) {
|
|
263
|
+
return localDateTimeToTimestampMs({
|
|
264
|
+
date: args.date,
|
|
265
|
+
time: args.recurrence.time,
|
|
266
|
+
timezone: args.timezone
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/** Return the next fire time after a completed run, when the task recurs. */
|
|
270
|
+
function getNextRunAtMs(task, scheduledForMs, afterMs = scheduledForMs) {
|
|
271
|
+
if (task.schedule.kind !== "recurring") return;
|
|
272
|
+
const recurrence = task.schedule.recurrence;
|
|
273
|
+
if (!recurrence || !Number.isFinite(recurrence.interval) || recurrence.interval <= 0) return;
|
|
274
|
+
const timezone = task.schedule.timezone;
|
|
275
|
+
const afterDate = getLocalDate(afterMs, timezone);
|
|
276
|
+
const nextScheduledDate = addDays(getLocalDate(scheduledForMs, timezone), 1);
|
|
277
|
+
return findNextRunAtMs({
|
|
278
|
+
afterMs,
|
|
279
|
+
recurrence,
|
|
280
|
+
searchFrom: compareDate(afterDate, nextScheduledDate) < 0 ? nextScheduledDate : afterDate,
|
|
281
|
+
timezone
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/chat/scheduled-automations/schedule-intent.ts
|
|
286
|
+
/**
|
|
287
|
+
* Owns model-facing schedule intent and materializes it against the trusted
|
|
288
|
+
* server clock into the canonical schedule persisted by core.
|
|
289
|
+
*/
|
|
290
|
+
const localDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Use a local date in YYYY-MM-DD format.");
|
|
291
|
+
const localTimeSchema = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "Use local time in HH:MM format.");
|
|
292
|
+
const timezoneSchema = z.string().min(1).max(80).describe("IANA timezone, for example America/Los_Angeles. Omit or use null for the scheduler default.").nullable().optional();
|
|
293
|
+
const weekdaySchema = z.enum([
|
|
294
|
+
"sunday",
|
|
295
|
+
"monday",
|
|
296
|
+
"tuesday",
|
|
297
|
+
"wednesday",
|
|
298
|
+
"thursday",
|
|
299
|
+
"friday",
|
|
300
|
+
"saturday"
|
|
301
|
+
]);
|
|
302
|
+
const oneOffScheduleIntentSchema = z.object({
|
|
303
|
+
kind: z.literal("one_off").describe("A schedule that runs once."),
|
|
304
|
+
timezone: timezoneSchema,
|
|
305
|
+
timing: z.discriminatedUnion("type", [z.object({
|
|
306
|
+
type: z.literal("after").describe("Run after a relative delay from the server clock."),
|
|
307
|
+
value: z.number().int().positive().max(1e5),
|
|
308
|
+
unit: z.enum([
|
|
309
|
+
"second",
|
|
310
|
+
"minute",
|
|
311
|
+
"hour",
|
|
312
|
+
"day",
|
|
313
|
+
"week"
|
|
314
|
+
])
|
|
315
|
+
}).strict(), z.object({
|
|
316
|
+
type: z.literal("at").describe("Run at an explicit local calendar date and time."),
|
|
317
|
+
date: localDateSchema.describe("Requested local calendar date in YYYY-MM-DD format."),
|
|
318
|
+
time: localTimeSchema.describe("Requested local wall-clock time in HH:MM format.")
|
|
319
|
+
}).strict()]).describe("Relative delay or explicit local time for the one-off run.")
|
|
320
|
+
}).strict();
|
|
321
|
+
const recurringScheduleIntentSchema = z.object({
|
|
322
|
+
kind: z.literal("recurring").describe("A repeating calendar schedule."),
|
|
323
|
+
frequency: z.enum([
|
|
324
|
+
"daily",
|
|
325
|
+
"weekly",
|
|
326
|
+
"monthly",
|
|
327
|
+
"yearly"
|
|
328
|
+
]).describe("Recurring tasks can run at most once per day."),
|
|
329
|
+
interval: z.number().int().positive().max(365).describe("Repeat every N frequency units. Defaults to 1.").nullable().optional(),
|
|
330
|
+
time: localTimeSchema.describe("Local wall-clock time for each occurrence in HH:MM format."),
|
|
331
|
+
weekdays: z.array(weekdaySchema).min(1).max(7).describe("Required for weekly schedules.").nullable().optional(),
|
|
332
|
+
dayOfMonth: z.number().int().min(1).max(31).describe("Required for monthly and yearly schedules.").nullable().optional(),
|
|
333
|
+
month: z.number().int().min(1).max(12).describe("Required for yearly schedules, where January is 1.").nullable().optional(),
|
|
334
|
+
startDate: localDateSchema.describe("Optional local calendar date that anchors the recurrence. Omit to start with the next matching occurrence.").nullable().optional(),
|
|
335
|
+
timezone: timezoneSchema
|
|
336
|
+
}).strict().superRefine((schedule, context) => {
|
|
337
|
+
if (schedule.frequency === "weekly" && schedule.weekdays == null) context.addIssue({
|
|
338
|
+
code: "custom",
|
|
339
|
+
message: "Weekly schedules require weekdays.",
|
|
340
|
+
path: ["weekdays"]
|
|
341
|
+
});
|
|
342
|
+
if ((schedule.frequency === "monthly" || schedule.frequency === "yearly") && schedule.dayOfMonth == null) context.addIssue({
|
|
343
|
+
code: "custom",
|
|
344
|
+
message: `${schedule.frequency} schedules require dayOfMonth.`,
|
|
345
|
+
path: ["dayOfMonth"]
|
|
346
|
+
});
|
|
347
|
+
if (schedule.frequency === "yearly" && schedule.month == null) context.addIssue({
|
|
348
|
+
code: "custom",
|
|
349
|
+
message: "Yearly schedules require month.",
|
|
350
|
+
path: ["month"]
|
|
351
|
+
});
|
|
352
|
+
if (schedule.frequency !== "weekly" && schedule.weekdays != null) context.addIssue({
|
|
353
|
+
code: "custom",
|
|
354
|
+
message: "weekdays applies only to weekly schedules.",
|
|
355
|
+
path: ["weekdays"]
|
|
356
|
+
});
|
|
357
|
+
if (schedule.frequency !== "monthly" && schedule.frequency !== "yearly" && schedule.dayOfMonth != null) context.addIssue({
|
|
358
|
+
code: "custom",
|
|
359
|
+
message: "dayOfMonth applies only to monthly or yearly schedules.",
|
|
360
|
+
path: ["dayOfMonth"]
|
|
361
|
+
});
|
|
362
|
+
if (schedule.frequency !== "yearly" && schedule.month != null) context.addIssue({
|
|
363
|
+
code: "custom",
|
|
364
|
+
message: "month applies only to yearly schedules.",
|
|
365
|
+
path: ["month"]
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
const scheduleIntentSchema = z.union([oneOffScheduleIntentSchema, recurringScheduleIntentSchema]);
|
|
369
|
+
const WEEKDAY_INDEX = {
|
|
370
|
+
sunday: 0,
|
|
371
|
+
monday: 1,
|
|
372
|
+
tuesday: 2,
|
|
373
|
+
wednesday: 3,
|
|
374
|
+
thursday: 4,
|
|
375
|
+
friday: 5,
|
|
376
|
+
saturday: 6
|
|
377
|
+
};
|
|
378
|
+
const DURATION_MS = {
|
|
379
|
+
second: 1e3,
|
|
380
|
+
minute: 6e4,
|
|
381
|
+
hour: 36e5,
|
|
382
|
+
day: 864e5,
|
|
383
|
+
week: 6048e5
|
|
384
|
+
};
|
|
385
|
+
function parseLocalTime(value) {
|
|
386
|
+
const [hour, minute] = value.split(":").map(Number);
|
|
387
|
+
return {
|
|
388
|
+
hour,
|
|
389
|
+
minute
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function localDateAt(timestampMs, timezone) {
|
|
393
|
+
const parts = getZonedDateTimeParts(timestampMs, timezone);
|
|
394
|
+
return [
|
|
395
|
+
parts.year,
|
|
396
|
+
parts.month,
|
|
397
|
+
parts.day
|
|
398
|
+
].map((value, index) => index === 0 ? String(value).padStart(4, "0") : String(value).padStart(2, "0")).join("-");
|
|
399
|
+
}
|
|
400
|
+
function isValidTimeZone(timezone) {
|
|
401
|
+
try {
|
|
402
|
+
new Intl.DateTimeFormat("en-US", { timeZone: timezone }).format();
|
|
403
|
+
return true;
|
|
404
|
+
} catch {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function plural(value, unit) {
|
|
409
|
+
return value === 1 ? unit : `${unit}s`;
|
|
410
|
+
}
|
|
411
|
+
function formatWeekdays(weekdays) {
|
|
412
|
+
const labels = weekdays.map((weekday) => `${weekday[0].toUpperCase()}${weekday.slice(1)}`);
|
|
413
|
+
if (labels.length < 2) return labels[0] ?? "";
|
|
414
|
+
return `${labels.slice(0, -1).join(", ")} and ${labels.at(-1)}`;
|
|
415
|
+
}
|
|
416
|
+
function recurringDescription(schedule, timezone) {
|
|
417
|
+
const interval = schedule.interval ?? 1;
|
|
418
|
+
const cadenceUnit = {
|
|
419
|
+
daily: "day",
|
|
420
|
+
weekly: "week",
|
|
421
|
+
monthly: "month",
|
|
422
|
+
yearly: "year"
|
|
423
|
+
}[schedule.frequency];
|
|
424
|
+
const cadence = interval === 1 ? cadenceUnit : `${interval} ${cadenceUnit}s`;
|
|
425
|
+
let detail = "";
|
|
426
|
+
if (schedule.frequency === "weekly") detail = ` on ${formatWeekdays(schedule.weekdays)}`;
|
|
427
|
+
else if (schedule.frequency === "monthly") detail = ` on day ${schedule.dayOfMonth}`;
|
|
428
|
+
else if (schedule.frequency === "yearly") detail = ` on ${String(schedule.month).padStart(2, "0")}-${String(schedule.dayOfMonth).padStart(2, "0")}`;
|
|
429
|
+
return `Every ${cadence}${detail} at ${schedule.time} (${timezone})`;
|
|
430
|
+
}
|
|
431
|
+
var ScheduleIntentError = class extends Error {};
|
|
432
|
+
/** Materialize model-interpreted schedule intent against the trusted server clock. */
|
|
433
|
+
function compileScheduleIntent(args) {
|
|
434
|
+
const timezone = args.intent.timezone ?? args.defaultTimezone;
|
|
435
|
+
if (!isValidTimeZone(timezone)) throw new ScheduleIntentError("timezone must be a valid IANA time zone.");
|
|
436
|
+
if (args.intent.kind === "one_off") {
|
|
437
|
+
if (args.intent.timing.type === "after") return {
|
|
438
|
+
nextRunAtMs: args.nowMs + args.intent.timing.value * DURATION_MS[args.intent.timing.unit],
|
|
439
|
+
schedule: {
|
|
440
|
+
description: `In ${args.intent.timing.value} ${plural(args.intent.timing.value, args.intent.timing.unit)}`,
|
|
441
|
+
kind: "one_off",
|
|
442
|
+
timezone
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
const nextRunAtMs = resolveLocalScheduleAtMs({
|
|
446
|
+
date: args.intent.timing.date,
|
|
447
|
+
time: parseLocalTime(args.intent.timing.time),
|
|
448
|
+
timezone
|
|
449
|
+
});
|
|
450
|
+
if (nextRunAtMs === void 0) throw new ScheduleIntentError("The requested local date or time does not exist in that timezone.");
|
|
451
|
+
if (nextRunAtMs <= args.nowMs) throw new ScheduleIntentError("The requested one-off schedule must be in the future.");
|
|
452
|
+
return {
|
|
453
|
+
nextRunAtMs,
|
|
454
|
+
schedule: {
|
|
455
|
+
description: `Once on ${args.intent.timing.date} at ${args.intent.timing.time} (${timezone})`,
|
|
456
|
+
kind: "one_off",
|
|
457
|
+
timezone
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
const recurrence = {
|
|
462
|
+
frequency: args.intent.frequency,
|
|
463
|
+
interval: args.intent.interval ?? 1,
|
|
464
|
+
startDate: args.intent.startDate ?? localDateAt(args.nowMs, timezone),
|
|
465
|
+
time: parseLocalTime(args.intent.time),
|
|
466
|
+
...args.intent.frequency === "weekly" ? { weekdays: [...new Set(args.intent.weekdays.map((weekday) => WEEKDAY_INDEX[weekday]))].sort((left, right) => left - right) } : void 0,
|
|
467
|
+
...args.intent.frequency === "monthly" || args.intent.frequency === "yearly" ? { dayOfMonth: args.intent.dayOfMonth ?? void 0 } : void 0,
|
|
468
|
+
...args.intent.frequency === "yearly" ? { month: args.intent.month ?? void 0 } : void 0
|
|
469
|
+
};
|
|
470
|
+
const searchRecurrence = args.intent.startDate ? recurrence : {
|
|
471
|
+
...recurrence,
|
|
472
|
+
interval: 1
|
|
473
|
+
};
|
|
474
|
+
const nextRunAtMs = getFirstRunAtMs({
|
|
475
|
+
afterMs: args.nowMs,
|
|
476
|
+
recurrence: searchRecurrence,
|
|
477
|
+
timezone
|
|
478
|
+
});
|
|
479
|
+
if (nextRunAtMs === void 0) throw new ScheduleIntentError("The recurring schedule has no valid future occurrence.");
|
|
480
|
+
const materializedRecurrence = args.intent.startDate ? recurrence : {
|
|
481
|
+
...recurrence,
|
|
482
|
+
startDate: localDateAt(nextRunAtMs, timezone)
|
|
483
|
+
};
|
|
484
|
+
return {
|
|
485
|
+
nextRunAtMs,
|
|
486
|
+
schedule: {
|
|
487
|
+
description: recurringDescription(args.intent, timezone),
|
|
488
|
+
kind: "recurring",
|
|
489
|
+
recurrence: materializedRecurrence,
|
|
490
|
+
timezone
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
//#endregion
|
|
495
|
+
//#region src/chat/automations/edit-schema.ts
|
|
496
|
+
const automationTitleSchema = z.string().trim().min(1).max(60);
|
|
497
|
+
const automationInstructionSchema = z.string().trim().min(1).max(4e3);
|
|
498
|
+
const automationEditFieldsSchema = z.object({
|
|
499
|
+
title: automationTitleSchema.optional(),
|
|
500
|
+
instruction: automationInstructionSchema.optional(),
|
|
501
|
+
credentialMode: z.enum(["system", "creator"]).optional(),
|
|
502
|
+
outcomes: z.array(z.union([taskOutcomeInputSchema, taskOutcomeSchema])).max(5).optional()
|
|
503
|
+
});
|
|
504
|
+
const scheduledAutomationEditSchema = automationEditFieldsSchema.extend({
|
|
505
|
+
schedule: scheduleIntentSchema.optional(),
|
|
506
|
+
status: z.enum(["active", "blocked"]).optional()
|
|
507
|
+
}).strict();
|
|
508
|
+
const eventAutomationEditSchema = automationEditFieldsSchema.extend({ trigger: eventAutomationTriggerSchema.extend({
|
|
509
|
+
identifier: z.string().trim().min(1).max(300),
|
|
510
|
+
label: z.string().trim().min(1).max(500)
|
|
511
|
+
}).optional() }).strict();
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region src/chat/scheduled-automations/types.ts
|
|
514
|
+
/** Durable scheduled-automation domain types owned by Junior core. */
|
|
515
|
+
const scheduledAutomationStatusSchema = z.enum([
|
|
516
|
+
"active",
|
|
517
|
+
"blocked",
|
|
518
|
+
"paused",
|
|
519
|
+
"completed",
|
|
520
|
+
"deleted"
|
|
521
|
+
]);
|
|
522
|
+
const scheduledAutomationCredentialModeSchema = z.enum(["system", "creator"]);
|
|
523
|
+
const scheduledRunStatusSchema = z.enum([
|
|
524
|
+
"pending",
|
|
525
|
+
"running",
|
|
526
|
+
"completed",
|
|
527
|
+
"failed",
|
|
528
|
+
"blocked",
|
|
529
|
+
"skipped"
|
|
530
|
+
]);
|
|
531
|
+
const scheduledAutomationPrincipalSchema = z.object({
|
|
532
|
+
slackUserId: actorUserIdSchema,
|
|
533
|
+
fullName: z.string().optional(),
|
|
534
|
+
userName: z.string().optional()
|
|
535
|
+
}).strict();
|
|
536
|
+
const scheduledAutomationRecurrenceSchema = z.object({
|
|
537
|
+
dayOfMonth: z.number().optional(),
|
|
538
|
+
frequency: z.enum([
|
|
539
|
+
"daily",
|
|
540
|
+
"weekly",
|
|
541
|
+
"monthly",
|
|
542
|
+
"yearly"
|
|
543
|
+
]),
|
|
544
|
+
interval: z.number(),
|
|
545
|
+
month: z.number().optional(),
|
|
546
|
+
startDate: z.string(),
|
|
547
|
+
time: z.object({
|
|
548
|
+
hour: z.number(),
|
|
549
|
+
minute: z.number()
|
|
550
|
+
}).strict(),
|
|
551
|
+
weekdays: z.array(z.number()).optional()
|
|
552
|
+
}).strict();
|
|
553
|
+
const scheduledAutomationScheduleSchema = z.object({
|
|
554
|
+
description: z.string(),
|
|
555
|
+
kind: z.enum(["one_off", "recurring"]),
|
|
556
|
+
recurrence: scheduledAutomationRecurrenceSchema.optional(),
|
|
557
|
+
timezone: z.string()
|
|
558
|
+
}).strict();
|
|
559
|
+
const scheduledAutomationExecutionActorSchema = z.object({
|
|
560
|
+
platform: z.literal("system"),
|
|
561
|
+
name: z.string()
|
|
562
|
+
}).strict();
|
|
563
|
+
/** Scheduled automations target a Slack conversation, never one message thread. */
|
|
564
|
+
const scheduledAutomationDestinationSchema = slackDestinationSchema.omit({ threadTs: true });
|
|
565
|
+
const scheduledAutomationOutcomeSchema = z.object({
|
|
566
|
+
action: z.literal("send_message"),
|
|
567
|
+
destination: scheduledAutomationDestinationSchema
|
|
568
|
+
}).strict();
|
|
569
|
+
/** Validate the current scheduled-automation domain shape. */
|
|
570
|
+
const scheduledAutomationSchema = z.object({
|
|
571
|
+
id: z.string(),
|
|
572
|
+
conversationAccess: z.object({
|
|
573
|
+
audience: z.enum([
|
|
574
|
+
"direct",
|
|
575
|
+
"group",
|
|
576
|
+
"channel"
|
|
577
|
+
]),
|
|
578
|
+
visibility: z.enum(["private", "public"])
|
|
579
|
+
}).strict(),
|
|
580
|
+
createdAtMs: z.number(),
|
|
581
|
+
createdBy: scheduledAutomationPrincipalSchema,
|
|
582
|
+
/** Authoritative provider identity that created the task. */
|
|
583
|
+
creatorIdentityId: z.string(),
|
|
584
|
+
/** Selects system credentials or task-bound creator credential delegation. */
|
|
585
|
+
credentialMode: scheduledAutomationCredentialModeSchema,
|
|
586
|
+
destination: scheduledAutomationDestinationSchema,
|
|
587
|
+
executionActor: scheduledAutomationExecutionActorSchema.optional(),
|
|
588
|
+
lastRunAtMs: z.number().optional(),
|
|
589
|
+
nextRunAtMs: z.number().optional(),
|
|
590
|
+
originalRequest: z.string().optional(),
|
|
591
|
+
runNowAtMs: z.number().optional(),
|
|
592
|
+
schedule: scheduledAutomationScheduleSchema,
|
|
593
|
+
status: scheduledAutomationStatusSchema,
|
|
594
|
+
statusReason: z.string().optional(),
|
|
595
|
+
/** Explicit visible effects after successful work. An empty list is silent. */
|
|
596
|
+
outcomes: z.array(scheduledAutomationOutcomeSchema).max(5),
|
|
597
|
+
task: z.object({ text: z.string() }).strict(),
|
|
598
|
+
/** SQL-backed short display title generated from the task instruction. */
|
|
599
|
+
title: z.string().optional(),
|
|
600
|
+
updatedAtMs: z.number()
|
|
601
|
+
}).strict();
|
|
602
|
+
/** Validate the current scheduled-run domain shape. */
|
|
603
|
+
const scheduledRunSchema = z.object({
|
|
604
|
+
id: z.string(),
|
|
605
|
+
attempt: z.number(),
|
|
606
|
+
claimedAtMs: z.number(),
|
|
607
|
+
completedAtMs: z.number().optional(),
|
|
608
|
+
dispatchId: z.string().optional(),
|
|
609
|
+
errorMessage: z.string().optional(),
|
|
610
|
+
resultMessageTs: z.string().optional(),
|
|
611
|
+
scheduledForMs: z.number(),
|
|
612
|
+
startedAtMs: z.number().optional(),
|
|
613
|
+
status: scheduledRunStatusSchema,
|
|
614
|
+
taskId: z.string()
|
|
615
|
+
}).strict();
|
|
616
|
+
const SCHEDULED_AUTOMATION_SYSTEM_ACTOR = Object.freeze({
|
|
617
|
+
platform: "system",
|
|
618
|
+
name: "scheduled-automation"
|
|
619
|
+
});
|
|
620
|
+
//#endregion
|
|
621
|
+
export { automationTitleSchema as a, ScheduleIntentError as c, getFirstRunAtMs as d, getNextRunAtMs as f, taskOutcomeInputSchema as g, eventAutomationTriggerSchema as h, automationInstructionSchema as i, compileScheduleIntent as l, eventAutomationSchema as m, scheduledAutomationSchema as n, eventAutomationEditSchema as o, getZonedDateTimeParts as p, scheduledRunSchema as r, scheduledAutomationEditSchema as s, SCHEDULED_AUTOMATION_SYSTEM_ACTOR as t, scheduleIntentSchema as u };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
|
|
2
|
-
import { n as pluginCatalogRuntime } from "./catalog-runtime-
|
|
2
|
+
import { n as pluginCatalogRuntime } from "./catalog-runtime-BSgsPVnr.js";
|
|
3
3
|
import { isDeepStrictEqual } from "node:util";
|
|
4
4
|
//#region src/chat/plugins/validation.ts
|
|
5
5
|
var validation_exports = /* @__PURE__ */ __exportAll({
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as JUNIOR_VERSION } from "./version-
|
|
1
|
+
import { t as JUNIOR_VERSION } from "./version-A7-RRBOE.js";
|
|
2
2
|
export { JUNIOR_VERSION };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Zt as getConversationEventStore } from "./agent-hooks-
|
|
3
|
-
import { n as loadTurnCheckpoint, o as failTurnRecord, s as getTurnRecord } from "./checkpoint-
|
|
4
|
-
import { w as getStateAdapter } from "./profile-
|
|
5
|
-
import { a as getVercelConversationWorkQueue } from "./job-queue-
|
|
6
|
-
import { n as resolveTurnSessionRouting } from "./turn-session-routing
|
|
1
|
+
import { It as ensureConversationWake, Kt as requestConversationWork } from "./agent-runner-DUkGlK89.js";
|
|
2
|
+
import { Zt as getConversationEventStore } from "./agent-hooks-BcH6E48y.js";
|
|
3
|
+
import { n as loadTurnCheckpoint, o as failTurnRecord, s as getTurnRecord } from "./checkpoint-BNfXlq_1.js";
|
|
4
|
+
import { w as getStateAdapter } from "./profile-BdApelHS.js";
|
|
5
|
+
import { a as getVercelConversationWorkQueue } from "./job-queue-cwHVOwVZ.js";
|
|
6
|
+
import { n as resolveTurnSessionRouting } from "./turn-session-routing--EhI76rH.js";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { randomUUID } from "node:crypto";
|
|
9
9
|
//#region src/chat/task-execution/authorized-turn.ts
|