@stratusagent/gateway 0.4.0 → 0.7.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.
@@ -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.4.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -18,10 +18,11 @@
18
18
  "node": ">=22.13 <23 || >=23.4"
19
19
  },
20
20
  "dependencies": {
21
- "@stratusagent/agents": "0.4.0",
22
- "@stratusagent/core": "0.4.0",
23
- "@stratusagent/executor-local": "0.4.0",
24
- "@stratusagent/state": "0.4.0"
21
+ "@stratusagent/agents": "0.7.0",
22
+ "@stratusagent/executor-local": "0.7.0",
23
+ "@stratusagent/plugins": "0.7.0",
24
+ "@stratusagent/core": "0.7.0",
25
+ "@stratusagent/state": "0.7.0"
25
26
  },
26
27
  "devDependencies": {
27
28
  "@types/node": "^24.6.0",