@stratusagent/gateway 0.6.0 → 0.8.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/index.d.ts +74 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +214 -8
- package/dist/index.js.map +1 -1
- package/dist/schedules.d.ts +137 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +427 -0
- package/dist/schedules.js.map +1 -0
- package/package.json +8 -7
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { chmodSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
5
|
+
import { canonicalDestination, nextFireAfter, SCHEDULE_ID_METADATA_KEY, SCHEDULED_TURN_METADATA_KEY, } from '@stratusagent/agents';
|
|
6
|
+
/**
|
|
7
|
+
* Durable schedules, in the same database sessions live in — a schedule
|
|
8
|
+
* survives a restart the way a parked approval does, and an operator has
|
|
9
|
+
* one file to back up, not two.
|
|
10
|
+
*
|
|
11
|
+
* Its own connection rather than a second table grown through
|
|
12
|
+
* `SqliteSessionStore`, because the CLI opens this store *without* a
|
|
13
|
+
* gateway: `stratus schedules` lists and cancels against the daemon's
|
|
14
|
+
* database directly, and WAL mode is what makes two processes on one file
|
|
15
|
+
* routine. The `next_fire_at` column exists so the due scan every tick
|
|
16
|
+
* runs reads no JSON body; the empty string means "spent" (a one-shot that
|
|
17
|
+
* fired, kept only until the turn it pre-authorized finishes) and sorts
|
|
18
|
+
* before every real timestamp, which is why the scan compares both ends.
|
|
19
|
+
*/
|
|
20
|
+
export class SqliteScheduleStore {
|
|
21
|
+
db;
|
|
22
|
+
constructor(filePath) {
|
|
23
|
+
// Same posture as the session store sharing this file: the directory
|
|
24
|
+
// and the database must not be readable by other local users, and the
|
|
25
|
+
// sidecar chmods cover databases created under a looser umask.
|
|
26
|
+
mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
27
|
+
this.db = new DatabaseSync(filePath);
|
|
28
|
+
try {
|
|
29
|
+
chmodSync(filePath, 0o600);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error.code !== 'ENOENT') {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.db.exec('PRAGMA journal_mode = WAL');
|
|
37
|
+
// WAL serializes writers to one at a time across the whole file, and
|
|
38
|
+
// this database is shared between two processes: the daemon claims
|
|
39
|
+
// slots and saves sessions while `stratus schedules cancel` deletes a
|
|
40
|
+
// row from another connection. Without a busy timeout the loser of that
|
|
41
|
+
// lock throws `database is locked` immediately — a cancel that silently
|
|
42
|
+
// failed would leave the schedule (and its destination grant) live.
|
|
43
|
+
// Wait for the writer instead.
|
|
44
|
+
this.db.exec('PRAGMA busy_timeout = 5000');
|
|
45
|
+
this.db.exec(`
|
|
46
|
+
CREATE TABLE IF NOT EXISTS schedules (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
agent_id TEXT NOT NULL,
|
|
49
|
+
next_fire_at TEXT NOT NULL,
|
|
50
|
+
body TEXT NOT NULL,
|
|
51
|
+
created_at TEXT NOT NULL
|
|
52
|
+
)
|
|
53
|
+
`);
|
|
54
|
+
for (const sensitive of [filePath, `${filePath}-wal`, `${filePath}-shm`, `${filePath}-journal`]) {
|
|
55
|
+
try {
|
|
56
|
+
chmodSync(sensitive, 0o600);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error.code !== 'ENOENT') {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
insert(record) {
|
|
66
|
+
this.db
|
|
67
|
+
.prepare('INSERT INTO schedules (id, agent_id, next_fire_at, body, created_at) VALUES (?, ?, ?, ?, ?)')
|
|
68
|
+
.run(record.id, record.agentId, record.nextFireAt ?? '', JSON.stringify(record), record.createdAt);
|
|
69
|
+
}
|
|
70
|
+
get(id) {
|
|
71
|
+
const row = this.db.prepare('SELECT body FROM schedules WHERE id = ?').get(id);
|
|
72
|
+
return row ? JSON.parse(row.body) : undefined;
|
|
73
|
+
}
|
|
74
|
+
/** Every schedule, oldest first — the operator's audit list. */
|
|
75
|
+
list(agentId) {
|
|
76
|
+
const rows = (agentId !== undefined
|
|
77
|
+
? this.db.prepare('SELECT body FROM schedules WHERE agent_id = ? ORDER BY created_at ASC').all(agentId)
|
|
78
|
+
: this.db.prepare('SELECT body FROM schedules ORDER BY created_at ASC').all());
|
|
79
|
+
return rows.map((row) => JSON.parse(row.body));
|
|
80
|
+
}
|
|
81
|
+
/** Schedules whose slot has arrived. ISO strings order lexicographically. */
|
|
82
|
+
due(nowIso) {
|
|
83
|
+
const rows = this.db
|
|
84
|
+
.prepare("SELECT body FROM schedules WHERE next_fire_at != '' AND next_fire_at <= ? ORDER BY next_fire_at ASC")
|
|
85
|
+
.all(nowIso);
|
|
86
|
+
return rows.map((row) => JSON.parse(row.body));
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Consume a slot, atomically: the write the double-run guarantee rests
|
|
90
|
+
* on, executed BEFORE the dispatch so a daemon that dies mid-firing
|
|
91
|
+
* restarts to a row whose window is already spent.
|
|
92
|
+
*
|
|
93
|
+
* Conditional on the slot still being the one the tick read, because
|
|
94
|
+
* the read and this write are separated by real time and the CLI
|
|
95
|
+
* deletes rows from another process: a schedule cancelled in that gap
|
|
96
|
+
* must stay cancelled — `stratus schedules cancel` revoking the grant
|
|
97
|
+
* but the prompt running anyway would be the worst of both. False means
|
|
98
|
+
* the row is gone or its slot moved, and the caller fires nothing.
|
|
99
|
+
*/
|
|
100
|
+
claimSlot(record, expectedNextFireAt) {
|
|
101
|
+
return this.db
|
|
102
|
+
.prepare('UPDATE schedules SET next_fire_at = ?, body = ? WHERE id = ? AND next_fire_at = ?')
|
|
103
|
+
.run(record.nextFireAt ?? '', JSON.stringify(record), record.id, expectedNextFireAt)
|
|
104
|
+
.changes > 0;
|
|
105
|
+
}
|
|
106
|
+
delete(id) {
|
|
107
|
+
return this.db.prepare('DELETE FROM schedules WHERE id = ?').run(id).changes > 0;
|
|
108
|
+
}
|
|
109
|
+
close() {
|
|
110
|
+
this.db.close();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The session-id namespace scheduled firings live in — `schedule:<id>:<slot>`.
|
|
115
|
+
*
|
|
116
|
+
* Reserved: the gateway refuses an *external* dispatch (a control-API
|
|
117
|
+
* message post, a channel) that names a session id in this space, so the
|
|
118
|
+
* only turns that ever run on a firing's session are the firing itself.
|
|
119
|
+
* That is the load-bearing half of the destination carve-out being
|
|
120
|
+
* unforgeable — the id is derivable from `GET /schedules`, so keeping it
|
|
121
|
+
* out of an attacker's reach depends on nobody but the scheduler being
|
|
122
|
+
* allowed to dispatch into it, not on it being secret.
|
|
123
|
+
*/
|
|
124
|
+
export const SCHEDULE_SESSION_ID_PREFIX = 'schedule:';
|
|
125
|
+
/** Whether a session id belongs to the reserved scheduled-firing namespace. */
|
|
126
|
+
export const isScheduleSessionId = (sessionId) => sessionId.startsWith(SCHEDULE_SESSION_ID_PREFIX);
|
|
127
|
+
const DEFAULT_MIN_INTERVAL_MS = 60_000;
|
|
128
|
+
const DEFAULT_MAX_CONCURRENT_PER_AGENT = 1;
|
|
129
|
+
const DEFAULT_TICK_MS = 1_000;
|
|
130
|
+
export const createSchedulerRuntime = (options) => {
|
|
131
|
+
const { store, dispatch, validateDestination, sessionStatus, hasAgent, log, warn } = options;
|
|
132
|
+
const minIntervalMs = options.limits?.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;
|
|
133
|
+
const maxConcurrentPerAgent = options.limits?.maxConcurrentPerAgent ?? DEFAULT_MAX_CONCURRENT_PER_AGENT;
|
|
134
|
+
const tickMs = options.limits?.tickMs ?? DEFAULT_TICK_MS;
|
|
135
|
+
let stopped = false;
|
|
136
|
+
let timer;
|
|
137
|
+
const inflight = new Set();
|
|
138
|
+
const runningPerAgent = new Map();
|
|
139
|
+
/**
|
|
140
|
+
* `${scheduleId}:${slot}` pairs a concurrency-cap deferral has already
|
|
141
|
+
* logged, so a firing that outlasts its cadence warns once per deferred
|
|
142
|
+
* slot rather than once per tick. Cleared when the slot finally fires or
|
|
143
|
+
* is skipped — the same slot recurs on every tick until then.
|
|
144
|
+
*/
|
|
145
|
+
const deferralsWarned = new Set();
|
|
146
|
+
/**
|
|
147
|
+
* Session ids of firings THIS scheduler started and has not seen settle.
|
|
148
|
+
*
|
|
149
|
+
* The unforgeable half of the destination carve-out. Metadata alone
|
|
150
|
+
* cannot be it: the control API forwards caller-supplied metadata into
|
|
151
|
+
* new sessions, so a client could stamp a live schedule's id onto a
|
|
152
|
+
* dispatch of its own and borrow the grant. Membership here is minted
|
|
153
|
+
* only by `fireOrSkip`, in memory, so the only sessions that can pass
|
|
154
|
+
* are the ones the scheduler itself dispatched — and a message queued
|
|
155
|
+
* into a firing's session from outside runs after the firing settles
|
|
156
|
+
* (single-flight), by which point the id is gone from this set.
|
|
157
|
+
*
|
|
158
|
+
* Deliberately not durable: a firing recovered after a restart (parked
|
|
159
|
+
* on some other approval, which only happens where a human is
|
|
160
|
+
* reachable) finishes without the grant and simply asks — losing a
|
|
161
|
+
* convenience is the right failure direction for a security scope.
|
|
162
|
+
*/
|
|
163
|
+
const activeFirings = new Set();
|
|
164
|
+
const enforceFloor = (input) => {
|
|
165
|
+
const { cadence } = input;
|
|
166
|
+
if (cadence.kind === 'every' && cadence.intervalMs < minIntervalMs) {
|
|
167
|
+
throw new Error(`Schedules may not run more often than every ${Math.round(minIntervalMs / 1000)}s; ${Math.round(cadence.intervalMs / 1000)}s is below the floor.`);
|
|
168
|
+
}
|
|
169
|
+
if (cadence.kind === 'cron') {
|
|
170
|
+
// The first observed gap. Five-field cron cannot express anything
|
|
171
|
+
// under a minute, so with the default floor this refuses nothing —
|
|
172
|
+
// it exists for an operator who RAISES the floor, where `* * * * *`
|
|
173
|
+
// must not slip past just for being spelled as a cron. An irregular
|
|
174
|
+
// expression with one tight pair elsewhere still can — the
|
|
175
|
+
// per-agent concurrency cap is the backstop that bounds the cost.
|
|
176
|
+
const first = nextFireAfter(cadence, new Date());
|
|
177
|
+
const second = first ? nextFireAfter(cadence, first) : undefined;
|
|
178
|
+
if (first && second && second.getTime() - first.getTime() < minIntervalMs) {
|
|
179
|
+
throw new Error(`Schedules may not run more often than every ${Math.round(minIntervalMs / 1000)}s; "${cadence.expression}" fires more often than that.`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const handle = {
|
|
184
|
+
async create(input) {
|
|
185
|
+
if (!hasAgent(input.agentId)) {
|
|
186
|
+
throw new Error(`Agent not found: ${input.agentId}`);
|
|
187
|
+
}
|
|
188
|
+
enforceFloor(input);
|
|
189
|
+
const now = new Date();
|
|
190
|
+
const next = nextFireAfter(input.cadence, now);
|
|
191
|
+
if (!next) {
|
|
192
|
+
throw new Error('This schedule would never fire — check the cadence.');
|
|
193
|
+
}
|
|
194
|
+
if (input.destination) {
|
|
195
|
+
// Refused NOW, while a person is present to hear why — never
|
|
196
|
+
// accepted and then silently unable to report at 6am.
|
|
197
|
+
await validateDestination(input.agentId, input.destination);
|
|
198
|
+
}
|
|
199
|
+
const record = {
|
|
200
|
+
id: randomUUID(),
|
|
201
|
+
agentId: input.agentId,
|
|
202
|
+
cadence: input.cadence,
|
|
203
|
+
prompt: input.prompt,
|
|
204
|
+
...(input.destination ? { destination: input.destination } : {}),
|
|
205
|
+
createdAt: now.toISOString(),
|
|
206
|
+
...(input.createdBy ? { createdBy: input.createdBy } : {}),
|
|
207
|
+
nextFireAt: next.toISOString(),
|
|
208
|
+
};
|
|
209
|
+
store.insert(record);
|
|
210
|
+
log(`schedule ${record.id} created for ${record.agentId} — first firing ${record.nextFireAt}${record.destination ? `, reports to ${canonicalDestination(record.destination)}` : ''}`);
|
|
211
|
+
return record;
|
|
212
|
+
},
|
|
213
|
+
async list(agentId) {
|
|
214
|
+
return store.list(agentId);
|
|
215
|
+
},
|
|
216
|
+
async cancel(agentId, scheduleId) {
|
|
217
|
+
const record = store.get(scheduleId);
|
|
218
|
+
if (!record || record.agentId !== agentId) {
|
|
219
|
+
// Ownership before existence: an agent probing ids learns nothing
|
|
220
|
+
// about other agents' schedules.
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
const deleted = store.delete(scheduleId);
|
|
224
|
+
if (deleted) {
|
|
225
|
+
log(`schedule ${scheduleId} cancelled by ${agentId}`);
|
|
226
|
+
}
|
|
227
|
+
return deleted;
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* The first slot strictly after `now`, skipping every window that passed
|
|
232
|
+
* while the daemon was down — in closed form, so downtime never costs a
|
|
233
|
+
* loop. For an interval this stays phase-aligned to the original slot
|
|
234
|
+
* (the cadence keeps its offset); for a cron it is the next matching time
|
|
235
|
+
* after now, which one bounded search already finds. A one-shot never
|
|
236
|
+
* reaches here — a passed `at` has no following occurrence to skip.
|
|
237
|
+
*/
|
|
238
|
+
const skipToFuture = (cadence, slotDate, now) => {
|
|
239
|
+
if (cadence.kind === 'every') {
|
|
240
|
+
const elapsed = now.getTime() - slotDate.getTime();
|
|
241
|
+
const jumps = Math.floor(elapsed / cadence.intervalMs) + 1;
|
|
242
|
+
return new Date(slotDate.getTime() + jumps * cadence.intervalMs);
|
|
243
|
+
}
|
|
244
|
+
return nextFireAfter(cadence, now);
|
|
245
|
+
};
|
|
246
|
+
/** `record` with its slot replaced — or removed, for a spent one-shot. */
|
|
247
|
+
const withNextFire = (record, next, extra = {}) => {
|
|
248
|
+
const { nextFireAt: _spent, ...rest } = record;
|
|
249
|
+
return { ...rest, ...extra, ...(next ? { nextFireAt: next.toISOString() } : {}) };
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Fire one due schedule: consume the slot durably, then dispatch.
|
|
253
|
+
*
|
|
254
|
+
* The catch-up rule is inline rather than a separate restart path,
|
|
255
|
+
* because a restart is just a tick that sees an old slot: a slot whose
|
|
256
|
+
* *following* occurrence has also passed is a window gone entirely —
|
|
257
|
+
* advance past it with a log line, never replay. Anything else fires,
|
|
258
|
+
* which on time is the normal case and late is the single catch-up.
|
|
259
|
+
*/
|
|
260
|
+
const fireOrSkip = (record, now) => {
|
|
261
|
+
const slot = record.nextFireAt;
|
|
262
|
+
if (!slot) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const slotDate = new Date(slot);
|
|
266
|
+
const following = nextFireAfter(record.cadence, slotDate);
|
|
267
|
+
if (following && following.getTime() <= now.getTime()) {
|
|
268
|
+
// Window passed entirely. Jump straight to the first slot after now —
|
|
269
|
+
// in closed form, never by stepping one interval at a time. A daemon
|
|
270
|
+
// down for a year against an `every 1m` schedule would otherwise spin
|
|
271
|
+
// ~525k iterations here, synchronously inside the awaited start(),
|
|
272
|
+
// stalling the whole boot. (A concurrent cancel makes the claim
|
|
273
|
+
// no-op, which is fine: skipped and gone both mean "not replayed".)
|
|
274
|
+
const next = skipToFuture(record.cadence, slotDate, now);
|
|
275
|
+
log(`schedule ${record.id}: missed firing(s) while the daemon was down; skipping to ${next ? next.toISOString() : 'never'}`);
|
|
276
|
+
store.claimSlot(withNextFire(record, next), slot);
|
|
277
|
+
deferralsWarned.delete(`${record.id}:${slot}`);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const running = runningPerAgent.get(record.agentId) ?? 0;
|
|
281
|
+
if (running >= maxConcurrentPerAgent) {
|
|
282
|
+
// Deferred, not dropped: the slot stays due and the next tick
|
|
283
|
+
// retries. Warned once per deferred slot, not once per tick — a
|
|
284
|
+
// firing that outlasts its cadence would otherwise repeat the same
|
|
285
|
+
// line every tickMs (~1/s) into a log CLAUDE.md keeps as a minimal
|
|
286
|
+
// trace. The entry clears when the slot finally fires or is skipped.
|
|
287
|
+
const deferralKey = `${record.id}:${slot}`;
|
|
288
|
+
if (!deferralsWarned.has(deferralKey)) {
|
|
289
|
+
deferralsWarned.add(deferralKey);
|
|
290
|
+
warn(`schedule ${record.id}: ${record.agentId} already has ${running} scheduled turn(s) running; deferring this firing (slot ${slot})`);
|
|
291
|
+
}
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
deferralsWarned.delete(`${record.id}:${slot}`);
|
|
295
|
+
const firedAt = now.toISOString();
|
|
296
|
+
const sessionId = `${SCHEDULE_SESSION_ID_PREFIX}${record.id}:${slot}`;
|
|
297
|
+
// Advance from the scheduled slot, not from now: `following` is the
|
|
298
|
+
// occurrence after this one, and the branch above proved it is still in
|
|
299
|
+
// the future (a passed-entirely window was skipped there). Computing it
|
|
300
|
+
// from `now` instead would push every future firing later by whatever
|
|
301
|
+
// scheduler or event-loop delay this one suffered, permanently drifting
|
|
302
|
+
// an `every 1h` cadence by the lateness of its first slightly-late tick.
|
|
303
|
+
const next = following;
|
|
304
|
+
// The slot is spent BEFORE the dispatch — the double-run guarantee —
|
|
305
|
+
// and spent ATOMICALLY against the slot this tick read: a schedule
|
|
306
|
+
// cancelled between the due scan and here is gone, and its prompt
|
|
307
|
+
// must not run on a grant that was just revoked.
|
|
308
|
+
if (!store.claimSlot(withNextFire(record, next, { lastFiredAt: firedAt, lastSessionId: sessionId }), slot)) {
|
|
309
|
+
log(`schedule ${record.id}: slot ${slot} was cancelled or already claimed; not firing`);
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
runningPerAgent.set(record.agentId, running + 1);
|
|
313
|
+
activeFirings.add(sessionId);
|
|
314
|
+
const firing = dispatch({
|
|
315
|
+
sessionId,
|
|
316
|
+
agentId: record.agentId,
|
|
317
|
+
userMessage: record.prompt,
|
|
318
|
+
metadata: {
|
|
319
|
+
[SCHEDULED_TURN_METADATA_KEY]: true,
|
|
320
|
+
[SCHEDULE_ID_METADATA_KEY]: record.id,
|
|
321
|
+
},
|
|
322
|
+
}).then(() => {
|
|
323
|
+
log(`schedule ${record.id} fired — session ${sessionId} completed`);
|
|
324
|
+
}, (error) => {
|
|
325
|
+
warn(`schedule ${record.id} firing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
326
|
+
}).finally(() => {
|
|
327
|
+
activeFirings.delete(sessionId);
|
|
328
|
+
const count = (runningPerAgent.get(record.agentId) ?? 1) - 1;
|
|
329
|
+
if (count > 0) {
|
|
330
|
+
runningPerAgent.set(record.agentId, count);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
runningPerAgent.delete(record.agentId);
|
|
334
|
+
}
|
|
335
|
+
// A spent one-shot's row outlives its firing only as the approval's
|
|
336
|
+
// scope; once the turn is over, retire it.
|
|
337
|
+
if (record.cadence.kind === 'at') {
|
|
338
|
+
store.delete(record.id);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
inflight.add(firing);
|
|
342
|
+
void firing.finally(() => inflight.delete(firing));
|
|
343
|
+
};
|
|
344
|
+
const tick = () => {
|
|
345
|
+
if (stopped) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const now = new Date();
|
|
350
|
+
for (const record of store.due(now.toISOString())) {
|
|
351
|
+
if (stopped) {
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
fireOrSkip(record, now);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
warn(`scheduler tick failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
359
|
+
}
|
|
360
|
+
if (!stopped) {
|
|
361
|
+
// Deliberately NOT unref'd, for the approval timer's reason: a
|
|
362
|
+
// stored schedule is real outstanding work — the daemon owes its
|
|
363
|
+
// next firing — and this timer is the only thing that will ever
|
|
364
|
+
// start it. Shutdown belongs to stop(), which clears it.
|
|
365
|
+
timer = setTimeout(tick, tickMs);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return {
|
|
369
|
+
handle,
|
|
370
|
+
isPreauthorized(session, destination) {
|
|
371
|
+
// A live firing of this scheduler's, first: session metadata is
|
|
372
|
+
// written by whoever dispatches, so on its own it proves nothing —
|
|
373
|
+
// see `activeFirings`. The row checks then bind the grant to the
|
|
374
|
+
// schedule the human approved, re-read per call so a cancel revokes
|
|
375
|
+
// mid-turn.
|
|
376
|
+
if (!activeFirings.has(session.id)) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
const scheduleId = session.metadata?.[SCHEDULE_ID_METADATA_KEY];
|
|
380
|
+
if (typeof scheduleId !== 'string') {
|
|
381
|
+
return false;
|
|
382
|
+
}
|
|
383
|
+
const record = store.get(scheduleId);
|
|
384
|
+
return record !== undefined
|
|
385
|
+
&& record.agentId === session.agent.id
|
|
386
|
+
&& record.destination !== undefined
|
|
387
|
+
&& canonicalDestination(record.destination) === destination;
|
|
388
|
+
},
|
|
389
|
+
list() {
|
|
390
|
+
return store.list();
|
|
391
|
+
},
|
|
392
|
+
cancel(scheduleId) {
|
|
393
|
+
const deleted = store.delete(scheduleId);
|
|
394
|
+
if (deleted) {
|
|
395
|
+
log(`schedule ${scheduleId} cancelled`);
|
|
396
|
+
}
|
|
397
|
+
return deleted;
|
|
398
|
+
},
|
|
399
|
+
async start() {
|
|
400
|
+
// Spent one-shots first: a row with no next slot is only the
|
|
401
|
+
// approval scope of a firing that may still be parked on a human.
|
|
402
|
+
// Turn over — or turn gone — means the row's work is done.
|
|
403
|
+
for (const record of store.list()) {
|
|
404
|
+
if (record.nextFireAt || record.cadence.kind !== 'at') {
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const status = record.lastSessionId ? await sessionStatus(record.lastSessionId) : undefined;
|
|
408
|
+
if (status !== 'pending_approval') {
|
|
409
|
+
store.delete(record.id);
|
|
410
|
+
log(`schedule ${record.id}: one-shot already fired; removing`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
tick();
|
|
414
|
+
},
|
|
415
|
+
stop() {
|
|
416
|
+
stopped = true;
|
|
417
|
+
if (timer) {
|
|
418
|
+
clearTimeout(timer);
|
|
419
|
+
timer = undefined;
|
|
420
|
+
}
|
|
421
|
+
},
|
|
422
|
+
async drain() {
|
|
423
|
+
await Promise.allSettled([...inflight]);
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
};
|
|
427
|
+
//# sourceMappingURL=schedules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedules.js","sourceRoot":"","sources":["../src/schedules.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratusagent/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,15 +18,16 @@
|
|
|
18
18
|
"node": ">=22.13 <23 || >=23.4"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@stratusagent/agents": "0.
|
|
22
|
-
"@stratusagent/
|
|
23
|
-
"@stratusagent/
|
|
24
|
-
"@stratusagent/
|
|
25
|
-
"@stratusagent/state": "0.
|
|
21
|
+
"@stratusagent/agents": "0.8.0",
|
|
22
|
+
"@stratusagent/plugins": "0.8.0",
|
|
23
|
+
"@stratusagent/executor-local": "0.8.0",
|
|
24
|
+
"@stratusagent/core": "0.8.0",
|
|
25
|
+
"@stratusagent/state": "0.8.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^24.6.0",
|
|
29
|
-
"typescript": "^5.9.3"
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"@stratusagent/permissions": "0.8.0"
|
|
30
31
|
},
|
|
31
32
|
"license": "MIT",
|
|
32
33
|
"repository": {
|