@jini-ai/daemon 0.1.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/LICENSE +201 -0
- package/dist/agent-executor.d.ts +458 -0
- package/dist/agent-executor.d.ts.map +1 -0
- package/dist/agent-executor.js +1277 -0
- package/dist/agent-executor.js.map +1 -0
- package/dist/artifacts/index.d.ts +14 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +14 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/manifest.d.ts +90 -0
- package/dist/artifacts/manifest.d.ts.map +1 -0
- package/dist/artifacts/manifest.js +229 -0
- package/dist/artifacts/manifest.js.map +1 -0
- package/dist/artifacts/publication-guard.d.ts +28 -0
- package/dist/artifacts/publication-guard.d.ts.map +1 -0
- package/dist/artifacts/publication-guard.js +77 -0
- package/dist/artifacts/publication-guard.js.map +1 -0
- package/dist/artifacts/runtime-compat.d.ts +37 -0
- package/dist/artifacts/runtime-compat.d.ts.map +1 -0
- package/dist/artifacts/runtime-compat.js +33 -0
- package/dist/artifacts/runtime-compat.js.map +1 -0
- package/dist/artifacts/store.d.ts +85 -0
- package/dist/artifacts/store.d.ts.map +1 -0
- package/dist/artifacts/store.js +92 -0
- package/dist/artifacts/store.js.map +1 -0
- package/dist/artifacts/stub-guard.d.ts +73 -0
- package/dist/artifacts/stub-guard.d.ts.map +1 -0
- package/dist/artifacts/stub-guard.js +198 -0
- package/dist/artifacts/stub-guard.js.map +1 -0
- package/dist/artifacts/text-suppression.d.ts +68 -0
- package/dist/artifacts/text-suppression.d.ts.map +1 -0
- package/dist/artifacts/text-suppression.js +184 -0
- package/dist/artifacts/text-suppression.js.map +1 -0
- package/dist/close-status.d.ts +86 -0
- package/dist/close-status.d.ts.map +1 -0
- package/dist/close-status.js +91 -0
- package/dist/close-status.js.map +1 -0
- package/dist/continuation/continuation-transport.d.ts +41 -0
- package/dist/continuation/continuation-transport.d.ts.map +1 -0
- package/dist/continuation/continuation-transport.js +18 -0
- package/dist/continuation/continuation-transport.js.map +1 -0
- package/dist/continuation/index.d.ts +4 -0
- package/dist/continuation/index.d.ts.map +1 -0
- package/dist/continuation/index.js +4 -0
- package/dist/continuation/index.js.map +1 -0
- package/dist/continuation/journal.d.ts +37 -0
- package/dist/continuation/journal.d.ts.map +1 -0
- package/dist/continuation/journal.js +23 -0
- package/dist/continuation/journal.js.map +1 -0
- package/dist/continuation/run-start-handler.d.ts +75 -0
- package/dist/continuation/run-start-handler.d.ts.map +1 -0
- package/dist/continuation/run-start-handler.js +32 -0
- package/dist/continuation/run-start-handler.js.map +1 -0
- package/dist/delegated-tool-bridge.d.ts +53 -0
- package/dist/delegated-tool-bridge.d.ts.map +1 -0
- package/dist/delegated-tool-bridge.js +92 -0
- package/dist/delegated-tool-bridge.js.map +1 -0
- package/dist/event-log.d.ts +134 -0
- package/dist/event-log.d.ts.map +1 -0
- package/dist/event-log.js +108 -0
- package/dist/event-log.js.map +1 -0
- package/dist/frontend-capability-tools.d.ts +102 -0
- package/dist/frontend-capability-tools.d.ts.map +1 -0
- package/dist/frontend-capability-tools.js +68 -0
- package/dist/frontend-capability-tools.js.map +1 -0
- package/dist/frontend-session-registry.d.ts +127 -0
- package/dist/frontend-session-registry.d.ts.map +1 -0
- package/dist/frontend-session-registry.js +180 -0
- package/dist/frontend-session-registry.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy-data-migration.d.ts +104 -0
- package/dist/legacy-data-migration.d.ts.map +1 -0
- package/dist/legacy-data-migration.js +239 -0
- package/dist/legacy-data-migration.js.map +1 -0
- package/dist/routines/index.d.ts +12 -0
- package/dist/routines/index.d.ts.map +1 -0
- package/dist/routines/index.js +12 -0
- package/dist/routines/index.js.map +1 -0
- package/dist/routines/routine-store.d.ts +77 -0
- package/dist/routines/routine-store.d.ts.map +1 -0
- package/dist/routines/routine-store.js +162 -0
- package/dist/routines/routine-store.js.map +1 -0
- package/dist/routines/schedule.d.ts +72 -0
- package/dist/routines/schedule.d.ts.map +1 -0
- package/dist/routines/schedule.js +263 -0
- package/dist/routines/schedule.js.map +1 -0
- package/dist/routines/scheduler.d.ts +34 -0
- package/dist/routines/scheduler.d.ts.map +1 -0
- package/dist/routines/scheduler.js +330 -0
- package/dist/routines/scheduler.js.map +1 -0
- package/dist/routines/types.d.ts +131 -0
- package/dist/routines/types.d.ts.map +1 -0
- package/dist/routines/types.js +9 -0
- package/dist/routines/types.js.map +1 -0
- package/dist/run/core/failure-taxonomy.d.ts +27 -0
- package/dist/run/core/failure-taxonomy.d.ts.map +1 -0
- package/dist/run/core/failure-taxonomy.js +16 -0
- package/dist/run/core/failure-taxonomy.js.map +1 -0
- package/dist/run/core/index.d.ts +5 -0
- package/dist/run/core/index.d.ts.map +1 -0
- package/dist/run/core/index.js +5 -0
- package/dist/run/core/index.js.map +1 -0
- package/dist/run/core/result.d.ts +25 -0
- package/dist/run/core/result.d.ts.map +1 -0
- package/dist/run/core/result.js +52 -0
- package/dist/run/core/result.js.map +1 -0
- package/dist/run/core/retry.d.ts +106 -0
- package/dist/run/core/retry.d.ts.map +1 -0
- package/dist/run/core/retry.js +210 -0
- package/dist/run/core/retry.js.map +1 -0
- package/dist/run/diagnostics/diagnostics.d.ts +86 -0
- package/dist/run/diagnostics/diagnostics.d.ts.map +1 -0
- package/dist/run/diagnostics/diagnostics.js +211 -0
- package/dist/run/diagnostics/diagnostics.js.map +1 -0
- package/dist/run/diagnostics/index.d.ts +3 -0
- package/dist/run/diagnostics/index.d.ts.map +1 -0
- package/dist/run/diagnostics/index.js +3 -0
- package/dist/run/diagnostics/index.js.map +1 -0
- package/dist/run/index.d.ts +16 -0
- package/dist/run/index.d.ts.map +1 -0
- package/dist/run/index.js +16 -0
- package/dist/run/index.js.map +1 -0
- package/dist/run-lifecycle.d.ts +118 -0
- package/dist/run-lifecycle.d.ts.map +1 -0
- package/dist/run-lifecycle.js +451 -0
- package/dist/run-lifecycle.js.map +1 -0
- package/dist/terminal-session.d.ts +139 -0
- package/dist/terminal-session.d.ts.map +1 -0
- package/dist/terminal-session.js +316 -0
- package/dist/terminal-session.js.map +1 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +19 -0
- package/dist/tokens.js.map +1 -0
- package/dist/tool-executor.d.ts +97 -0
- package/dist/tool-executor.d.ts.map +1 -0
- package/dist/tool-executor.js +198 -0
- package/dist/tool-executor.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// ---------- timezone math ----------
|
|
2
|
+
/**
|
|
3
|
+
* Returns the wall-clock parts of `atUtc` rendered in `timezone`. Uses `Intl.DateTimeFormat`. If
|
|
4
|
+
* the timezone is invalid the formatter throws — callers catch upstream.
|
|
5
|
+
*
|
|
6
|
+
* Exported for the same reason as {@link tzWallToUtcCandidates}/{@link tzWallToUtcGapFallback}:
|
|
7
|
+
* its two defensive fallbacks (an Intl-reported hour of `"24"` at local midnight in some
|
|
8
|
+
* locale/zone combinations, and an unrecognized weekday abbreviation) are ICU-implementation
|
|
9
|
+
* edge cases no timezone on this test runner's ICU data naturally triggers — directly testable
|
|
10
|
+
* with a mocked `Intl.DateTimeFormat.prototype.formatToParts` instead of left unreachable.
|
|
11
|
+
*/
|
|
12
|
+
export function partsInTimezone(timezone, atUtc) {
|
|
13
|
+
const dtf = new Intl.DateTimeFormat('en-US', {
|
|
14
|
+
timeZone: timezone,
|
|
15
|
+
hour12: false,
|
|
16
|
+
year: 'numeric',
|
|
17
|
+
month: '2-digit',
|
|
18
|
+
day: '2-digit',
|
|
19
|
+
hour: '2-digit',
|
|
20
|
+
minute: '2-digit',
|
|
21
|
+
second: '2-digit',
|
|
22
|
+
weekday: 'short',
|
|
23
|
+
});
|
|
24
|
+
const parts = dtf.formatToParts(atUtc);
|
|
25
|
+
const get = (type) => parts.find((p) => p.type === type)?.value ?? '0';
|
|
26
|
+
const weekdayStr = get('weekday');
|
|
27
|
+
const weekdayMap = {
|
|
28
|
+
Sun: 0,
|
|
29
|
+
Mon: 1,
|
|
30
|
+
Tue: 2,
|
|
31
|
+
Wed: 3,
|
|
32
|
+
Thu: 4,
|
|
33
|
+
Fri: 5,
|
|
34
|
+
Sat: 6,
|
|
35
|
+
};
|
|
36
|
+
let h = Number(get('hour'));
|
|
37
|
+
// Intl emits "24" at midnight in some locales/zones; normalize to 0.
|
|
38
|
+
if (h === 24)
|
|
39
|
+
h = 0;
|
|
40
|
+
return {
|
|
41
|
+
year: Number(get('year')),
|
|
42
|
+
month: Number(get('month')),
|
|
43
|
+
day: Number(get('day')),
|
|
44
|
+
hour: h,
|
|
45
|
+
minute: Number(get('minute')),
|
|
46
|
+
second: Number(get('second')),
|
|
47
|
+
weekday: weekdayMap[weekdayStr] ?? 0,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Returns every UTC instant at which the wall clock in `timezone` reads the requested Y-M-D h:m,
|
|
52
|
+
* sorted ascending. Most days have exactly one match. On a fall-back transition day the requested
|
|
53
|
+
* time inside the repeated hour has two matches (one before the transition, one after); outside
|
|
54
|
+
* that hour it still has one. On a spring-forward gap the requested time inside the gap has zero
|
|
55
|
+
* matches — callers fall back to {@link tzWallToUtcGapFallback} to land on a post-gap instant the
|
|
56
|
+
* same day. Probes offsets at three reference points across the day so that both pre- and
|
|
57
|
+
* post-transition offsets are sampled regardless of which side of the transition `tentative`
|
|
58
|
+
* happens to land on. Returns `[]` if `timezone` is invalid.
|
|
59
|
+
*
|
|
60
|
+
* Exported (unlike this module's other low-level helpers) so its own `catch` branch is directly
|
|
61
|
+
* unit-testable: {@link nextWallTimeMatching}, this function's only real caller, already calls
|
|
62
|
+
* the unguarded `partsInTimezone` earlier in its own loop body, so an invalid timezone throws
|
|
63
|
+
* there first — this function's defensive catch is otherwise unreachable through that call path.
|
|
64
|
+
*/
|
|
65
|
+
export function tzWallToUtcCandidates(timezone, year, month, day, hour, minute) {
|
|
66
|
+
try {
|
|
67
|
+
const tentative = Date.UTC(year, month - 1, day, hour, minute, 0);
|
|
68
|
+
const probeOffsetsMs = [-12, 0, 12].map((h) => h * 60 * 60_000);
|
|
69
|
+
const seen = new Set();
|
|
70
|
+
const out = [];
|
|
71
|
+
for (const dms of probeOffsetsMs) {
|
|
72
|
+
const off = tzOffsetMinutes(timezone, new Date(tentative + dms));
|
|
73
|
+
const cand = new Date(tentative - off * 60_000);
|
|
74
|
+
const t = cand.getTime();
|
|
75
|
+
if (seen.has(t))
|
|
76
|
+
continue;
|
|
77
|
+
if (matchesWallClock(timezone, cand, year, month, day, hour, minute)) {
|
|
78
|
+
seen.add(t);
|
|
79
|
+
out.push(cand);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return out.sort((a, b) => a.getTime() - b.getTime());
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Spring-forward gap fallback: when the requested wall time doesn't exist in `timezone` on this
|
|
90
|
+
* day (clocks jumped over it), return the later of the two probe candidates. That instant has
|
|
91
|
+
* crossed the transition and renders as the first valid post-gap wall time, so a routine still
|
|
92
|
+
* fires today instead of firing an hour early before the gap. Returns `null` if `timezone` is
|
|
93
|
+
* invalid.
|
|
94
|
+
*
|
|
95
|
+
* Exported for the same reason as {@link tzWallToUtcCandidates} — its own `catch` branch is
|
|
96
|
+
* otherwise unreachable through {@link nextWallTimeMatching}'s call path.
|
|
97
|
+
*/
|
|
98
|
+
export function tzWallToUtcGapFallback(timezone, year, month, day, hour, minute) {
|
|
99
|
+
try {
|
|
100
|
+
const tentative = Date.UTC(year, month - 1, day, hour, minute, 0);
|
|
101
|
+
const t1 = tzOffsetMinutes(timezone, new Date(tentative));
|
|
102
|
+
const candidate1 = new Date(tentative - t1 * 60_000);
|
|
103
|
+
const t2 = tzOffsetMinutes(timezone, candidate1);
|
|
104
|
+
const candidate2 = new Date(tentative - t2 * 60_000);
|
|
105
|
+
return candidate1.getTime() > candidate2.getTime() ? candidate1 : candidate2;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function matchesWallClock(timezone, at, year, month, day, hour, minute) {
|
|
112
|
+
const p = partsInTimezone(timezone, at);
|
|
113
|
+
return p.year === year && p.month === month && p.day === day && p.hour === hour && p.minute === minute;
|
|
114
|
+
}
|
|
115
|
+
/** Minutes east of UTC for `timezone` at instant `at`. e.g. Asia/Shanghai returns 480. */
|
|
116
|
+
function tzOffsetMinutes(timezone, at) {
|
|
117
|
+
const p = partsInTimezone(timezone, at);
|
|
118
|
+
const asIfUtc = Date.UTC(p.year, p.month - 1, p.day, p.hour, p.minute, p.second);
|
|
119
|
+
return Math.round((asIfUtc - at.getTime()) / 60_000);
|
|
120
|
+
}
|
|
121
|
+
// ---------- next-fire calculation ----------
|
|
122
|
+
export function nextHourlyRunAt(minute, now = new Date()) {
|
|
123
|
+
const next = new Date(now);
|
|
124
|
+
next.setSeconds(0, 0);
|
|
125
|
+
next.setMinutes(minute);
|
|
126
|
+
if (next.getTime() <= now.getTime()) {
|
|
127
|
+
next.setHours(next.getHours() + 1);
|
|
128
|
+
}
|
|
129
|
+
return next;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Returns the next instant at which the wall-clock in `timezone` reads "HH:MM" on a day where
|
|
133
|
+
* `predicate(weekday)` holds. Walks forward at most 14 calendar days as a safety bound (covers
|
|
134
|
+
* any weekday-based pattern). Exported (unlike this module's other internal helpers) so its
|
|
135
|
+
* 14-day-exhaustion fallback is directly unit-testable: every `predicate` `nextRunAtForSchedule`
|
|
136
|
+
* actually passes (daily/weekdays/weekly) structurally guarantees a match within 7 days, making
|
|
137
|
+
* that branch otherwise unreachable through the public schedule-kind API alone.
|
|
138
|
+
*/
|
|
139
|
+
export function nextWallTimeMatching(timezone, time, predicate, now) {
|
|
140
|
+
const m = /^(\d{2}):(\d{2})$/.exec(time);
|
|
141
|
+
if (!m)
|
|
142
|
+
return null;
|
|
143
|
+
const hour = Number(m[1]);
|
|
144
|
+
const minute = Number(m[2]);
|
|
145
|
+
if (!Number.isFinite(hour) || hour < 0 || hour > 23)
|
|
146
|
+
return null;
|
|
147
|
+
if (!Number.isFinite(minute) || minute < 0 || minute > 59)
|
|
148
|
+
return null;
|
|
149
|
+
// Walk day by day in the target timezone.
|
|
150
|
+
for (let offset = 0; offset < 14; offset += 1) {
|
|
151
|
+
const probe = new Date(now.getTime() + offset * 24 * 60 * 60_000);
|
|
152
|
+
const parts = partsInTimezone(timezone, probe);
|
|
153
|
+
if (!predicate(parts.weekday))
|
|
154
|
+
continue;
|
|
155
|
+
const candidates = tzWallToUtcCandidates(timezone, parts.year, parts.month, parts.day, hour, minute);
|
|
156
|
+
if (candidates.length === 0) {
|
|
157
|
+
// Spring-forward gap: no valid wall instant exists today; pick the synthesized post-gap
|
|
158
|
+
// fallback so the routine still fires today.
|
|
159
|
+
const fallback = tzWallToUtcGapFallback(timezone, parts.year, parts.month, parts.day, hour, minute);
|
|
160
|
+
// Null-safety guard against tzWallToUtcGapFallback's `Date | null` return type (it returns
|
|
161
|
+
// null only for an invalid timezone). Structurally unreachable from THIS call site: the
|
|
162
|
+
// unguarded `partsInTimezone(timezone, probe)` two lines above already succeeded for this
|
|
163
|
+
// exact `timezone` earlier in this same loop iteration, which proves it valid before
|
|
164
|
+
// `tzWallToUtcGapFallback` (guarding the identical Intl call) is ever reached — so this
|
|
165
|
+
// branch cannot be exercised without bypassing that invariant. Kept rather than removed:
|
|
166
|
+
// the guard is still correct defensive programming against the function's real signature,
|
|
167
|
+
// and `tzWallToUtcGapFallback`'s own null path is independently covered by a direct test
|
|
168
|
+
// (see schedule.test.ts) against an invalid timezone.
|
|
169
|
+
if (!fallback)
|
|
170
|
+
return null;
|
|
171
|
+
if (fallback.getTime() > now.getTime())
|
|
172
|
+
return fallback;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// Iterate candidates in ascending order so that on a fall-back overlap day, when `now`
|
|
176
|
+
// already passed the first occurrence (EDT), we still pick the second one (EST) before
|
|
177
|
+
// walking to the next day.
|
|
178
|
+
for (const candidate of candidates) {
|
|
179
|
+
if (candidate.getTime() > now.getTime())
|
|
180
|
+
return candidate;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
export function nextRunAtForSchedule(schedule, now = new Date()) {
|
|
186
|
+
if (schedule.kind === 'hourly') {
|
|
187
|
+
return nextHourlyRunAt(schedule.minute, now);
|
|
188
|
+
}
|
|
189
|
+
if (schedule.kind === 'daily') {
|
|
190
|
+
return nextWallTimeMatching(schedule.timezone, schedule.time, () => true, now);
|
|
191
|
+
}
|
|
192
|
+
if (schedule.kind === 'weekdays') {
|
|
193
|
+
// Mon=1 .. Fri=5
|
|
194
|
+
return nextWallTimeMatching(schedule.timezone, schedule.time, (w) => w >= 1 && w <= 5, now);
|
|
195
|
+
}
|
|
196
|
+
if (schedule.kind === 'weekly') {
|
|
197
|
+
return nextWallTimeMatching(schedule.timezone, schedule.time, (w) => w === schedule.weekday, now);
|
|
198
|
+
}
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
// ---------- validation ----------
|
|
202
|
+
export function isValidWallTime(time) {
|
|
203
|
+
const m = /^(\d{2}):(\d{2})$/.exec(time);
|
|
204
|
+
if (!m)
|
|
205
|
+
return false;
|
|
206
|
+
const h = Number(m[1]);
|
|
207
|
+
const mm = Number(m[2]);
|
|
208
|
+
return h >= 0 && h <= 23 && mm >= 0 && mm <= 59;
|
|
209
|
+
}
|
|
210
|
+
export function isValidTimezone(tz) {
|
|
211
|
+
if (!tz || typeof tz !== 'string')
|
|
212
|
+
return false;
|
|
213
|
+
try {
|
|
214
|
+
new Intl.DateTimeFormat('en-US', { timeZone: tz });
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
export function validateSchedule(schedule) {
|
|
222
|
+
if (!schedule || typeof schedule !== 'object') {
|
|
223
|
+
throw new Error('schedule is required');
|
|
224
|
+
}
|
|
225
|
+
if (schedule.kind === 'hourly') {
|
|
226
|
+
const m = schedule.minute;
|
|
227
|
+
if (!Number.isInteger(m) || m < 0 || m > 59) {
|
|
228
|
+
throw new Error('hourly.minute must be an integer 0-59');
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (schedule.kind === 'daily' || schedule.kind === 'weekdays' || schedule.kind === 'weekly') {
|
|
233
|
+
if (!isValidWallTime(schedule.time)) {
|
|
234
|
+
throw new Error(`Invalid time: ${schedule.time}`);
|
|
235
|
+
}
|
|
236
|
+
if (!isValidTimezone(schedule.timezone)) {
|
|
237
|
+
throw new Error(`Invalid timezone: ${schedule.timezone}`);
|
|
238
|
+
}
|
|
239
|
+
if (schedule.kind === 'weekly') {
|
|
240
|
+
const w = schedule.weekday;
|
|
241
|
+
if (!Number.isInteger(w) || w < 0 || w > 6) {
|
|
242
|
+
throw new Error('weekly.weekday must be 0-6');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
throw new Error(`Unsupported schedule kind: ${schedule.kind}`);
|
|
248
|
+
}
|
|
249
|
+
export function validateTarget(target) {
|
|
250
|
+
if (!target || typeof target !== 'object') {
|
|
251
|
+
throw new Error('target is required');
|
|
252
|
+
}
|
|
253
|
+
if (target.mode === 'create_each_run')
|
|
254
|
+
return;
|
|
255
|
+
if (target.mode === 'reuse') {
|
|
256
|
+
if (!target.projectId || typeof target.projectId !== 'string') {
|
|
257
|
+
throw new Error('Reuse target requires a projectId');
|
|
258
|
+
}
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
throw new Error(`Unsupported routine target mode: ${target.mode}`);
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/routines/schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { RoutinePersistence, RoutineRunHandler, RoutineRunHandlerStart } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Distinguishes "a sibling daemon already won this scheduled slot, or the durable write itself
|
|
4
|
+
* failed" from every other run-handler failure, so the scheduler can retry the same slot instead
|
|
5
|
+
* of silently advancing to the next cadence (which would skip a fire the caller never actually
|
|
6
|
+
* got).
|
|
7
|
+
*/
|
|
8
|
+
export declare class ScheduledRunPersistenceError extends Error {
|
|
9
|
+
readonly routineId: string;
|
|
10
|
+
readonly slotAt: number;
|
|
11
|
+
readonly originalError: unknown;
|
|
12
|
+
constructor(routineId: string, slotAt: number, originalError: unknown);
|
|
13
|
+
}
|
|
14
|
+
export declare class RoutineService {
|
|
15
|
+
private readonly persistence;
|
|
16
|
+
private timers;
|
|
17
|
+
private inflight;
|
|
18
|
+
private runHandler;
|
|
19
|
+
private started;
|
|
20
|
+
constructor(persistence: RoutinePersistence);
|
|
21
|
+
setRunHandler(handler: RoutineRunHandler): void;
|
|
22
|
+
start(): void;
|
|
23
|
+
stop(): void;
|
|
24
|
+
rescheduleAll(): void;
|
|
25
|
+
rescheduleOne(routineId: string): void;
|
|
26
|
+
unschedule(routineId: string): void;
|
|
27
|
+
private scheduleRoutine;
|
|
28
|
+
private retryScheduledSlot;
|
|
29
|
+
private scheduleRoutineAt;
|
|
30
|
+
nextRunAt(routineId: string): Date | null;
|
|
31
|
+
runNow(routineId: string): Promise<RoutineRunHandlerStart>;
|
|
32
|
+
private start_;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/routines/scheduler.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAEV,kBAAkB,EAElB,iBAAiB,EACjB,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAYpB;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IAEnD,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO;gBAFtB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,OAAO;CAKlC;AAMD,qBAAa,cAAc;IAMb,OAAO,CAAC,QAAQ,CAAC,WAAW;IALxC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,QAAQ,CAAsD;IACtE,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,OAAO,CAAS;gBAEK,WAAW,EAAE,kBAAkB;IAE5D,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAI/C,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI;IAMZ,aAAa,IAAI,IAAI;IASrB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAWtC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAQnC,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,iBAAiB;IAmCzB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAInC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;YAIlD,MAAM;CA4KrB"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `RoutineService` — a multi-routine scheduler: a list of user-defined routines, each with its
|
|
3
|
+
* own schedule, that fires a host-registered run handler. Schedule kinds covered: hourly (every
|
|
4
|
+
* hour at minute M), daily (HH:MM in timezone), weekdays (Mon-Fri at HH:MM in timezone), weekly
|
|
5
|
+
* (one weekday at HH:MM in timezone) — see {@link ./schedule.js} for the DST-safe wall-clock math
|
|
6
|
+
* behind `nextRunAtForSchedule`. The run handler is host-owned: it is responsible for whatever
|
|
7
|
+
* "firing a routine" means to a given consumer (project/conversation creation and dispatch into a
|
|
8
|
+
* chat run, for OD) — this engine has no opinion on that, matching `RunLifecycle`'s existing
|
|
9
|
+
* precedent for a kernel-owned, storage-injected service with a host-supplied driver.
|
|
10
|
+
*
|
|
11
|
+
* Ported from OD's `apps/daemon/src/routines.ts` (726 lines) per the porting proposal
|
|
12
|
+
* (`ADS-memory/reports/proposals/PROP-http-route-packs-automation-routines-2026-07-21.md`,
|
|
13
|
+
* Finding 2): "a genuinely clean, already-portable generic scheduling engine... ready to port
|
|
14
|
+
* today as its own small, well-scoped task." Its only import was `node:crypto`'s `randomUUID`
|
|
15
|
+
* (unchanged here); its `Routine`/`RoutineSchedule` types were already a documented local mirror,
|
|
16
|
+
* not a product coupling (now `./types.js`); its `RoutinePersistence` injected port and
|
|
17
|
+
* `RoutineRunHandler` callback are unchanged (see `./types.js`'s doc comments for why
|
|
18
|
+
* `RoutinePersistence` deliberately stays synchronous rather than converted to this package's
|
|
19
|
+
* usual async-port convention). Logic is otherwise unchanged from the OD source — this is a
|
|
20
|
+
* faithful port, not a redesign, per the proposal's own warning against "casually reinventing"
|
|
21
|
+
* the race-safe scheduled-slot claim below.
|
|
22
|
+
*/
|
|
23
|
+
import { randomUUID } from 'node:crypto';
|
|
24
|
+
import { nextRunAtForSchedule } from './schedule.js';
|
|
25
|
+
function clearRoutinePlaceholderId(value) {
|
|
26
|
+
return value.startsWith('routine-pending-') ? '' : value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Distinguishes "a sibling daemon already won this scheduled slot, or the durable write itself
|
|
30
|
+
* failed" from every other run-handler failure, so the scheduler can retry the same slot instead
|
|
31
|
+
* of silently advancing to the next cadence (which would skip a fire the caller never actually
|
|
32
|
+
* got).
|
|
33
|
+
*/
|
|
34
|
+
export class ScheduledRunPersistenceError extends Error {
|
|
35
|
+
routineId;
|
|
36
|
+
slotAt;
|
|
37
|
+
originalError;
|
|
38
|
+
constructor(routineId, slotAt, originalError) {
|
|
39
|
+
super(`Routine ${routineId} scheduled slot ${slotAt} could not be persisted`);
|
|
40
|
+
this.routineId = routineId;
|
|
41
|
+
this.slotAt = slotAt;
|
|
42
|
+
this.originalError = originalError;
|
|
43
|
+
this.name = 'ScheduledRunPersistenceError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function isScheduledRunPersistenceError(error) {
|
|
47
|
+
return error instanceof ScheduledRunPersistenceError;
|
|
48
|
+
}
|
|
49
|
+
export class RoutineService {
|
|
50
|
+
persistence;
|
|
51
|
+
timers = new Map();
|
|
52
|
+
inflight = new Map();
|
|
53
|
+
runHandler = null;
|
|
54
|
+
started = false;
|
|
55
|
+
constructor(persistence) {
|
|
56
|
+
this.persistence = persistence;
|
|
57
|
+
}
|
|
58
|
+
setRunHandler(handler) {
|
|
59
|
+
this.runHandler = handler;
|
|
60
|
+
}
|
|
61
|
+
start() {
|
|
62
|
+
if (this.started)
|
|
63
|
+
return;
|
|
64
|
+
this.started = true;
|
|
65
|
+
this.rescheduleAll();
|
|
66
|
+
}
|
|
67
|
+
stop() {
|
|
68
|
+
for (const entry of this.timers.values())
|
|
69
|
+
clearTimeout(entry.timer);
|
|
70
|
+
this.timers.clear();
|
|
71
|
+
this.started = false;
|
|
72
|
+
}
|
|
73
|
+
rescheduleAll() {
|
|
74
|
+
for (const entry of this.timers.values())
|
|
75
|
+
clearTimeout(entry.timer);
|
|
76
|
+
this.timers.clear();
|
|
77
|
+
if (!this.started)
|
|
78
|
+
return;
|
|
79
|
+
for (const routine of this.persistence.list()) {
|
|
80
|
+
this.scheduleRoutine(routine);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
rescheduleOne(routineId) {
|
|
84
|
+
const existing = this.timers.get(routineId);
|
|
85
|
+
if (existing) {
|
|
86
|
+
clearTimeout(existing.timer);
|
|
87
|
+
this.timers.delete(routineId);
|
|
88
|
+
}
|
|
89
|
+
if (!this.started)
|
|
90
|
+
return;
|
|
91
|
+
const routine = this.persistence.list().find((r) => r.id === routineId);
|
|
92
|
+
if (routine)
|
|
93
|
+
this.scheduleRoutine(routine);
|
|
94
|
+
}
|
|
95
|
+
unschedule(routineId) {
|
|
96
|
+
const existing = this.timers.get(routineId);
|
|
97
|
+
if (existing) {
|
|
98
|
+
clearTimeout(existing.timer);
|
|
99
|
+
this.timers.delete(routineId);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
scheduleRoutine(routine) {
|
|
103
|
+
if (!routine.enabled)
|
|
104
|
+
return;
|
|
105
|
+
const fireAt = nextRunAtForSchedule(routine.schedule);
|
|
106
|
+
if (!fireAt)
|
|
107
|
+
return;
|
|
108
|
+
this.scheduleRoutineAt(routine, fireAt);
|
|
109
|
+
}
|
|
110
|
+
retryScheduledSlot(routineId, fireAt) {
|
|
111
|
+
if (!this.started)
|
|
112
|
+
return;
|
|
113
|
+
const routine = this.persistence.list().find((candidate) => candidate.id === routineId);
|
|
114
|
+
if (!routine?.enabled)
|
|
115
|
+
return;
|
|
116
|
+
this.scheduleRoutineAt(routine, fireAt);
|
|
117
|
+
}
|
|
118
|
+
scheduleRoutineAt(routine, fireAt) {
|
|
119
|
+
// setTimeout can't carry past 2^31 ms (~24.8 days); we cap and use a chained re-schedule.
|
|
120
|
+
// Routines fire within hours/days, but a misconfigured "next month" weekly value could
|
|
121
|
+
// otherwise overflow.
|
|
122
|
+
const delay = Math.max(1_000, Math.min(2_000_000_000, fireAt.getTime() - Date.now()));
|
|
123
|
+
const timer = setTimeout(() => {
|
|
124
|
+
this.timers.delete(routine.id);
|
|
125
|
+
const slotAt = fireAt.getTime();
|
|
126
|
+
this.start_(routine.id, 'scheduled', { scheduledSlotAt: slotAt })
|
|
127
|
+
.then(() => {
|
|
128
|
+
// Always reschedule so a single fire keeps the cadence alive.
|
|
129
|
+
this.rescheduleOne(routine.id);
|
|
130
|
+
})
|
|
131
|
+
.catch((error) => {
|
|
132
|
+
console.error(`[@jini-ai/daemon] routine ${routine.id} scheduled run failed:`, error instanceof ScheduledRunPersistenceError
|
|
133
|
+
? error.originalError instanceof Error
|
|
134
|
+
? error.originalError.message
|
|
135
|
+
: error.originalError
|
|
136
|
+
: error instanceof Error
|
|
137
|
+
? error.message
|
|
138
|
+
: error);
|
|
139
|
+
if (isScheduledRunPersistenceError(error)) {
|
|
140
|
+
this.retryScheduledSlot(routine.id, fireAt);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
this.rescheduleOne(routine.id);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}, delay);
|
|
147
|
+
if (typeof timer.unref === 'function')
|
|
148
|
+
timer.unref();
|
|
149
|
+
this.timers.set(routine.id, { routineId: routine.id, timer, fireAt });
|
|
150
|
+
}
|
|
151
|
+
nextRunAt(routineId) {
|
|
152
|
+
return this.timers.get(routineId)?.fireAt ?? null;
|
|
153
|
+
}
|
|
154
|
+
async runNow(routineId) {
|
|
155
|
+
return this.start_(routineId, 'manual');
|
|
156
|
+
}
|
|
157
|
+
async start_(routineId, trigger, options = {}) {
|
|
158
|
+
if (!this.runHandler)
|
|
159
|
+
throw new Error('Routine run handler is not configured');
|
|
160
|
+
const inflight = this.inflight.get(routineId);
|
|
161
|
+
if (inflight)
|
|
162
|
+
return inflight;
|
|
163
|
+
const routine = this.persistence.list().find((r) => r.id === routineId);
|
|
164
|
+
if (!routine)
|
|
165
|
+
throw new Error(`Routine ${routineId} not found`);
|
|
166
|
+
const startedAt = Date.now();
|
|
167
|
+
const runId = `routine-run-${randomUUID()}`;
|
|
168
|
+
const promise = (async () => {
|
|
169
|
+
const handler = this.runHandler;
|
|
170
|
+
if (!handler)
|
|
171
|
+
throw new Error('Routine run handler is not configured');
|
|
172
|
+
const handlerStart = await handler({ routine, trigger, startedAt, runId });
|
|
173
|
+
const run = {
|
|
174
|
+
id: runId,
|
|
175
|
+
routineId: routine.id,
|
|
176
|
+
trigger,
|
|
177
|
+
status: 'running',
|
|
178
|
+
projectId: handlerStart.projectId,
|
|
179
|
+
conversationId: handlerStart.conversationId,
|
|
180
|
+
agentRunId: handlerStart.agentRunId,
|
|
181
|
+
startedAt,
|
|
182
|
+
completedAt: null,
|
|
183
|
+
summary: null,
|
|
184
|
+
error: null,
|
|
185
|
+
errorCode: null,
|
|
186
|
+
};
|
|
187
|
+
const scheduledSlotAt = options.scheduledSlotAt;
|
|
188
|
+
const wasScheduled = scheduledSlotAt != null;
|
|
189
|
+
const publicProjectId = () => clearRoutinePlaceholderId(run.projectId);
|
|
190
|
+
const publicConversationId = () => clearRoutinePlaceholderId(run.conversationId);
|
|
191
|
+
const publicAgentRunId = () => clearRoutinePlaceholderId(run.agentRunId);
|
|
192
|
+
const scrubRoutinePlaceholders = () => {
|
|
193
|
+
run.projectId = publicProjectId();
|
|
194
|
+
run.conversationId = publicConversationId();
|
|
195
|
+
run.agentRunId = publicAgentRunId();
|
|
196
|
+
};
|
|
197
|
+
// Tear-down to use when the durable routine_run row was never inserted (insertRun threw, or
|
|
198
|
+
// another daemon already won the slot). Prefer the explicit `discardUnstarted` callback
|
|
199
|
+
// when the handler distinguishes the two cases — that one drops the in-memory chat run
|
|
200
|
+
// entirely instead of finalizing it as `canceled`, so duplicate scheduled losers do not
|
|
201
|
+
// surface phantom runs on a run listing. Handlers that do not implement the split still see
|
|
202
|
+
// `discard`.
|
|
203
|
+
const discardUnstarted = handlerStart.discardUnstarted ?? handlerStart.discard;
|
|
204
|
+
let inserted = true;
|
|
205
|
+
try {
|
|
206
|
+
inserted = this.persistence.insertRun(run, options) !== false;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
try {
|
|
210
|
+
discardUnstarted?.();
|
|
211
|
+
}
|
|
212
|
+
catch (discardError) {
|
|
213
|
+
if (wasScheduled) {
|
|
214
|
+
throw new ScheduledRunPersistenceError(routine.id, scheduledSlotAt, discardError);
|
|
215
|
+
}
|
|
216
|
+
throw discardError;
|
|
217
|
+
}
|
|
218
|
+
if (wasScheduled) {
|
|
219
|
+
throw new ScheduledRunPersistenceError(routine.id, scheduledSlotAt, error);
|
|
220
|
+
}
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
if (!inserted) {
|
|
224
|
+
try {
|
|
225
|
+
discardUnstarted?.();
|
|
226
|
+
}
|
|
227
|
+
catch (discardError) {
|
|
228
|
+
if (wasScheduled) {
|
|
229
|
+
throw new ScheduledRunPersistenceError(routine.id, scheduledSlotAt, discardError);
|
|
230
|
+
}
|
|
231
|
+
throw discardError;
|
|
232
|
+
}
|
|
233
|
+
return handlerStart;
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
await handlerStart.prepare?.(run);
|
|
237
|
+
const preparedIdsChanged = run.projectId !== handlerStart.projectId
|
|
238
|
+
|| run.conversationId !== handlerStart.conversationId
|
|
239
|
+
|| run.agentRunId !== handlerStart.agentRunId;
|
|
240
|
+
handlerStart.projectId = run.projectId;
|
|
241
|
+
handlerStart.conversationId = run.conversationId;
|
|
242
|
+
handlerStart.agentRunId = run.agentRunId;
|
|
243
|
+
if (wasScheduled || preparedIdsChanged) {
|
|
244
|
+
this.persistence.updateRun(runId, {
|
|
245
|
+
projectId: run.projectId,
|
|
246
|
+
conversationId: run.conversationId,
|
|
247
|
+
agentRunId: run.agentRunId,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
// Terminate the in-memory chat run created by `handler(...)` so its `completion` promise
|
|
253
|
+
// resolves instead of waiting forever on a run that will never start. Surface any cleanup
|
|
254
|
+
// failure rather than swallow it, but still finalize the persisted row.
|
|
255
|
+
let discardError = null;
|
|
256
|
+
try {
|
|
257
|
+
handlerStart.discard?.();
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
discardError = err;
|
|
261
|
+
}
|
|
262
|
+
if (discardError != null) {
|
|
263
|
+
console.error(`[@jini-ai/daemon] routine ${routine.id} prepare cleanup failed:`, discardError instanceof Error ? discardError.message : discardError);
|
|
264
|
+
}
|
|
265
|
+
// Persist IDs only after `prepare()` has replaced routine placeholders with real
|
|
266
|
+
// resources. If preparation failed before enrichment, clear the sentinels so the terminal
|
|
267
|
+
// row does not point at fabricated project/conversation IDs. For scheduled runs the slot
|
|
268
|
+
// claim was already accepted at `insertRun()`, so retrying the same slot is not
|
|
269
|
+
// appropriate — let the error propagate so the scheduler advances to the next cadence.
|
|
270
|
+
scrubRoutinePlaceholders();
|
|
271
|
+
this.persistence.updateRun(runId, {
|
|
272
|
+
status: 'failed',
|
|
273
|
+
completedAt: Date.now(),
|
|
274
|
+
summary: null,
|
|
275
|
+
error: error instanceof Error ? error.message : String(error),
|
|
276
|
+
errorCode: null,
|
|
277
|
+
projectId: run.projectId,
|
|
278
|
+
conversationId: run.conversationId,
|
|
279
|
+
agentRunId: run.agentRunId,
|
|
280
|
+
});
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
handlerStart.completion
|
|
284
|
+
.then((completion) => {
|
|
285
|
+
this.persistence.updateRun(runId, {
|
|
286
|
+
status: completion.status,
|
|
287
|
+
completedAt: Date.now(),
|
|
288
|
+
summary: completion.summary ?? null,
|
|
289
|
+
error: completion.error ?? null,
|
|
290
|
+
errorCode: completion.errorCode ?? null,
|
|
291
|
+
});
|
|
292
|
+
})
|
|
293
|
+
.catch((error) => {
|
|
294
|
+
this.persistence.updateRun(runId, {
|
|
295
|
+
status: 'failed',
|
|
296
|
+
completedAt: Date.now(),
|
|
297
|
+
summary: null,
|
|
298
|
+
error: error instanceof Error ? error.message : String(error),
|
|
299
|
+
errorCode: null,
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
try {
|
|
303
|
+
handlerStart.start?.();
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
this.persistence.updateRun(runId, {
|
|
307
|
+
status: 'failed',
|
|
308
|
+
completedAt: Date.now(),
|
|
309
|
+
summary: null,
|
|
310
|
+
error: error instanceof Error ? error.message : String(error),
|
|
311
|
+
errorCode: null,
|
|
312
|
+
});
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
return handlerStart;
|
|
316
|
+
})();
|
|
317
|
+
this.inflight.set(routineId, promise);
|
|
318
|
+
// The trailing `finally(...)` returns a new promise that mirrors the original rejection;
|
|
319
|
+
// without `.catch` it would surface as an unhandled rejection (fatal in modern Node) when the
|
|
320
|
+
// handler rejects before producing a start handle. The original `promise` is still returned
|
|
321
|
+
// to callers, who handle the rejection there.
|
|
322
|
+
promise
|
|
323
|
+
.finally(() => {
|
|
324
|
+
this.inflight.delete(routineId);
|
|
325
|
+
})
|
|
326
|
+
.catch(() => { });
|
|
327
|
+
return promise;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/routines/scheduler.ts"],"names":[],"mappings":"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"}
|