instar 1.3.233 → 1.3.235
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/dashboard/index.html +140 -0
- package/dist/commands/reflect.d.ts.map +1 -1
- package/dist/commands/reflect.js +5 -0
- package/dist/commands/reflect.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +14 -4
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +22 -2
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +12 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +30 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/types.d.ts +22 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/CommitmentSentinel.d.ts +6 -0
- package/dist/monitoring/CommitmentSentinel.d.ts.map +1 -1
- package/dist/monitoring/CommitmentSentinel.js +46 -1
- package/dist/monitoring/CommitmentSentinel.js.map +1 -1
- package/dist/monitoring/ResourceLedger.d.ts +62 -0
- package/dist/monitoring/ResourceLedger.d.ts.map +1 -1
- package/dist/monitoring/ResourceLedger.js +152 -2
- package/dist/monitoring/ResourceLedger.js.map +1 -1
- package/dist/monitoring/ResourceSampler.d.ts +63 -0
- package/dist/monitoring/ResourceSampler.d.ts.map +1 -0
- package/dist/monitoring/ResourceSampler.js +277 -0
- package/dist/monitoring/ResourceSampler.js.map +1 -0
- package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
- package/dist/monitoring/SessionWatchdog.js +5 -0
- package/dist/monitoring/SessionWatchdog.js.map +1 -1
- package/dist/scaffold/templates.js +4 -4
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +48 -5
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +4 -2
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +43 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +65 -65
- package/src/scaffold/templates.ts +4 -4
- package/upgrades/1.3.234.md +33 -0
- package/upgrades/1.3.235.md +110 -0
- package/upgrades/commitment-bare-continuation-guard.eli16.md +26 -0
- package/upgrades/side-effects/commitment-bare-continuation-guard.md +42 -0
- package/upgrades/side-effects/esm-require-fixes-gate-rearm.md +110 -0
- package/upgrades/side-effects/resource-ledger.md +110 -0
|
@@ -16,8 +16,12 @@
|
|
|
16
16
|
* emission, with a real per-event identity (not a content hash) so legitimate
|
|
17
17
|
* same-millisecond events don't collapse and a restart can't replay-double-count.
|
|
18
18
|
*
|
|
19
|
-
* CPU
|
|
20
|
-
*
|
|
19
|
+
* Phase B adds continuous CPU% + memory sampling (resource_samples) of the
|
|
20
|
+
* agent's OWN server process and its spawned session processes, written by
|
|
21
|
+
* ResourceSampler on a cadence. Same discipline: read-only, fail-open, bounded
|
|
22
|
+
* (retention prune). This closes the "instar tracks zero CPU and zero memory"
|
|
23
|
+
* gap — token usage was well-tracked (TokenLedger) but per-agent CPU/RSS was
|
|
24
|
+
* unaccounted for.
|
|
21
25
|
*
|
|
22
26
|
* Spec: docs/specs/per-agent-resource-ledger.md.
|
|
23
27
|
*/
|
|
@@ -40,10 +44,25 @@ const SCHEMA = [
|
|
|
40
44
|
`CREATE INDEX IF NOT EXISTS idx_rle_ts ON rate_limit_events (ts)`,
|
|
41
45
|
`CREATE INDEX IF NOT EXISTS idx_rle_kind_ts ON rate_limit_events (kind, ts)`,
|
|
42
46
|
`CREATE INDEX IF NOT EXISTS idx_rle_source_ts ON rate_limit_events (source, ts)`,
|
|
47
|
+
// Phase B: continuous CPU% + RSS samples. One row per source per sampling
|
|
48
|
+
// tick (server + each session + an aggregate). No primary key beyond rowid:
|
|
49
|
+
// a sample is a point-in-time reading, not an idempotent event — re-inserts
|
|
50
|
+
// are real data. Bounded by retention prune (pruneOlderThan).
|
|
51
|
+
`CREATE TABLE IF NOT EXISTS resource_samples (
|
|
52
|
+
ts INTEGER NOT NULL,
|
|
53
|
+
source TEXT NOT NULL,
|
|
54
|
+
pid INTEGER,
|
|
55
|
+
cpu_percent REAL NOT NULL DEFAULT 0,
|
|
56
|
+
rss_bytes INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
heap_used_bytes INTEGER
|
|
58
|
+
)`,
|
|
59
|
+
`CREATE INDEX IF NOT EXISTS idx_rs_ts ON resource_samples (ts)`,
|
|
60
|
+
`CREATE INDEX IF NOT EXISTS idx_rs_source_ts ON resource_samples (source, ts)`,
|
|
43
61
|
];
|
|
44
62
|
export class ResourceLedger {
|
|
45
63
|
db;
|
|
46
64
|
insertEvent;
|
|
65
|
+
insertSample;
|
|
47
66
|
closed = false;
|
|
48
67
|
constructor(opts) {
|
|
49
68
|
if (opts.dbPath !== ':memory:') {
|
|
@@ -71,6 +90,9 @@ export class ResourceLedger {
|
|
|
71
90
|
this.insertEvent = this.db.prepare(`INSERT OR IGNORE INTO rate_limit_events
|
|
72
91
|
(id, ts, kind, source, account_key, session_name, reason, detail)
|
|
73
92
|
VALUES (@id, @ts, @kind, @source, @accountKey, @sessionName, @reason, @detail)`);
|
|
93
|
+
this.insertSample = this.db.prepare(`INSERT INTO resource_samples
|
|
94
|
+
(ts, source, pid, cpu_percent, rss_bytes, heap_used_bytes)
|
|
95
|
+
VALUES (@ts, @source, @pid, @cpuPercent, @rssBytes, @heapUsedBytes)`);
|
|
74
96
|
}
|
|
75
97
|
/** Per-event identity: ts + source + seq is unique within a process; the source
|
|
76
98
|
* prefix keeps breaker and sentinel rows from ever colliding. NOT a content
|
|
@@ -150,6 +172,134 @@ export class ResourceLedger {
|
|
|
150
172
|
LIMIT ?`)
|
|
151
173
|
.all(since, limit);
|
|
152
174
|
}
|
|
175
|
+
// ── Phase B: CPU + memory samples ─────────────────────────────────────────
|
|
176
|
+
/** Record one CPU/memory sample. Never throws — observability must not break
|
|
177
|
+
* the observed path. Negative/NaN numbers are clamped so a bad reading can't
|
|
178
|
+
* poison aggregates. */
|
|
179
|
+
record(s) {
|
|
180
|
+
if (this.closed)
|
|
181
|
+
return;
|
|
182
|
+
try {
|
|
183
|
+
this.insertSample.run({
|
|
184
|
+
ts: s.ts,
|
|
185
|
+
source: s.source,
|
|
186
|
+
pid: typeof s.pid === 'number' && Number.isFinite(s.pid) ? Math.trunc(s.pid) : null,
|
|
187
|
+
cpuPercent: ResourceLedger.clampNonNeg(s.cpuPercent),
|
|
188
|
+
rssBytes: ResourceLedger.clampNonNeg(s.rssBytes),
|
|
189
|
+
heapUsedBytes: s.heapUsedBytes == null ? null : ResourceLedger.clampNonNeg(s.heapUsedBytes),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
/* swallow — never break the observed path */
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** Record a batch of samples in one transaction (one tick's worth). Fail-open:
|
|
197
|
+
* a write error rolls back this batch only and is swallowed. */
|
|
198
|
+
recordSamples(samples) {
|
|
199
|
+
if (this.closed || samples.length === 0)
|
|
200
|
+
return;
|
|
201
|
+
try {
|
|
202
|
+
const txn = this.db.transaction((rows) => {
|
|
203
|
+
for (const s of rows)
|
|
204
|
+
this.record(s);
|
|
205
|
+
});
|
|
206
|
+
txn(samples);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
/* swallow */
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
static clampNonNeg(n) {
|
|
213
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Per-source CPU% + RSS rollup over the trailing window: current (latest
|
|
217
|
+
* sample), plus avg/peak across the window, plus the synthetic `aggregate`
|
|
218
|
+
* row if present. Newest-first ordering by recency of last sample.
|
|
219
|
+
*/
|
|
220
|
+
summary(sinceMs) {
|
|
221
|
+
const rows = this.db
|
|
222
|
+
.prepare(`SELECT
|
|
223
|
+
source,
|
|
224
|
+
AVG(cpu_percent) AS avgCpuPercent,
|
|
225
|
+
MAX(cpu_percent) AS peakCpuPercent,
|
|
226
|
+
AVG(rss_bytes) AS avgRssBytes,
|
|
227
|
+
MAX(rss_bytes) AS peakRssBytes,
|
|
228
|
+
COUNT(*) AS sampleCount,
|
|
229
|
+
MAX(ts) AS newestTs
|
|
230
|
+
FROM resource_samples
|
|
231
|
+
WHERE ts >= ?
|
|
232
|
+
GROUP BY source
|
|
233
|
+
ORDER BY newestTs DESC`)
|
|
234
|
+
.all(sinceMs);
|
|
235
|
+
const latest = this.db.prepare(`SELECT cpu_percent AS cpuPercent, rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
|
|
236
|
+
FROM resource_samples
|
|
237
|
+
WHERE source = ? AND ts >= ?
|
|
238
|
+
ORDER BY ts DESC LIMIT 1`);
|
|
239
|
+
return rows.map((r) => {
|
|
240
|
+
const cur = latest.get(String(r.source), sinceMs);
|
|
241
|
+
return {
|
|
242
|
+
source: String(r.source),
|
|
243
|
+
currentCpuPercent: cur ? Number(cur.cpuPercent) : null,
|
|
244
|
+
currentRssBytes: cur ? Number(cur.rssBytes) : null,
|
|
245
|
+
currentHeapUsedBytes: cur && cur.heapUsedBytes != null ? Number(cur.heapUsedBytes) : null,
|
|
246
|
+
avgCpuPercent: +(Number(r.avgCpuPercent ?? 0)).toFixed(2),
|
|
247
|
+
peakCpuPercent: +(Number(r.peakCpuPercent ?? 0)).toFixed(2),
|
|
248
|
+
avgRssBytes: Math.round(Number(r.avgRssBytes ?? 0)),
|
|
249
|
+
peakRssBytes: Math.round(Number(r.peakRssBytes ?? 0)),
|
|
250
|
+
sampleCount: Number(r.sampleCount ?? 0),
|
|
251
|
+
newestTs: r.newestTs ?? null,
|
|
252
|
+
};
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
/** Recent raw samples, newest first (paginated). */
|
|
256
|
+
recentSamples(opts = {}) {
|
|
257
|
+
const limit = Math.min(Math.max(opts.limit ?? 100, 1), 2000);
|
|
258
|
+
const since = opts.sinceMs ?? 0;
|
|
259
|
+
if (opts.source) {
|
|
260
|
+
return this.db
|
|
261
|
+
.prepare(`SELECT ts, source, pid, cpu_percent AS cpuPercent,
|
|
262
|
+
rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
|
|
263
|
+
FROM resource_samples
|
|
264
|
+
WHERE ts >= ? AND source = ?
|
|
265
|
+
ORDER BY ts DESC LIMIT ?`)
|
|
266
|
+
.all(since, opts.source, limit);
|
|
267
|
+
}
|
|
268
|
+
return this.db
|
|
269
|
+
.prepare(`SELECT ts, source, pid, cpu_percent AS cpuPercent,
|
|
270
|
+
rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
|
|
271
|
+
FROM resource_samples
|
|
272
|
+
WHERE ts >= ?
|
|
273
|
+
ORDER BY ts DESC LIMIT ?`)
|
|
274
|
+
.all(since, limit);
|
|
275
|
+
}
|
|
276
|
+
/** Total number of CPU/mem samples stored. */
|
|
277
|
+
sampleCount() {
|
|
278
|
+
try {
|
|
279
|
+
const row = this.db.prepare(`SELECT COUNT(*) AS n FROM resource_samples`).get();
|
|
280
|
+
return Number(row?.n ?? 0);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// @silent-fallback-ok: read-only observability count. A DB read error must
|
|
284
|
+
// never break the observed path; "unknown count" degrades to 0, not a throw.
|
|
285
|
+
return 0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/** Delete samples older than `cutoffMs`. Returns rows deleted. Fail-open. */
|
|
289
|
+
pruneOlderThan(cutoffMs) {
|
|
290
|
+
if (this.closed)
|
|
291
|
+
return 0;
|
|
292
|
+
try {
|
|
293
|
+
const res = this.db.prepare(`DELETE FROM resource_samples WHERE ts < ?`).run(cutoffMs);
|
|
294
|
+
return Number(res.changes ?? 0);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// @silent-fallback-ok: retention prune is best-effort housekeeping. A failed
|
|
298
|
+
// prune just leaves older rows for the next tick; it must not throw into the
|
|
299
|
+
// sampler's hot path.
|
|
300
|
+
return 0;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
153
303
|
close() {
|
|
154
304
|
if (this.closed)
|
|
155
305
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourceLedger.js","sourceRoot":"","sources":["../../src/monitoring/ResourceLedger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ResourceLedger.js","sourceRoot":"","sources":["../../src/monitoring/ResourceLedger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ResourceLedger } from './ResourceLedger.js';
|
|
2
|
+
export interface ResourceSamplerOptions {
|
|
3
|
+
ledger: ResourceLedger;
|
|
4
|
+
/** Returns the live session pane PIDs to sample, keyed by session id. Called
|
|
5
|
+
* each tick; an error/empty result just means "no sessions this tick". */
|
|
6
|
+
getSessionPids: () => Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
pid: number;
|
|
9
|
+
}>;
|
|
10
|
+
/** Active sampling cadence (ms). Defaults to 60_000. */
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
/** Idle sampling cadence (ms) — used when getSessionPids() is empty. Default 5min. */
|
|
13
|
+
idleIntervalMs?: number;
|
|
14
|
+
/** Retention window (ms) — samples older than this are pruned each tick. Default 7d. */
|
|
15
|
+
retentionMs?: number;
|
|
16
|
+
/** Test seam: read this process's CPU usage (microseconds). Defaults to process.cpuUsage. */
|
|
17
|
+
cpuUsageFn?: (previous?: NodeJS.CpuUsage) => NodeJS.CpuUsage;
|
|
18
|
+
/** Test seam: read this process's memory. Defaults to process.memoryUsage. */
|
|
19
|
+
memoryUsageFn?: () => NodeJS.MemoryUsage;
|
|
20
|
+
/** Test seam: monotonic clock (ms). Defaults to Date.now. */
|
|
21
|
+
now?: () => number;
|
|
22
|
+
/** Test seam: sample a batch of OS pids. Defaults to a batched `ps` call. */
|
|
23
|
+
samplePidsFn?: (pids: number[]) => Promise<Map<number, {
|
|
24
|
+
cpuPercent: number;
|
|
25
|
+
rssBytes: number;
|
|
26
|
+
}>>;
|
|
27
|
+
/** Optional error sink (defaults to a single console.warn). */
|
|
28
|
+
onError?: (err: unknown) => void;
|
|
29
|
+
}
|
|
30
|
+
export declare class ResourceSampler {
|
|
31
|
+
private readonly ledger;
|
|
32
|
+
private readonly getSessionPids;
|
|
33
|
+
private readonly intervalMs;
|
|
34
|
+
private readonly idleIntervalMs;
|
|
35
|
+
private readonly retentionMs;
|
|
36
|
+
private readonly cpuUsageFn;
|
|
37
|
+
private readonly memoryUsageFn;
|
|
38
|
+
private readonly now;
|
|
39
|
+
private readonly samplePidsFn;
|
|
40
|
+
private readonly onError;
|
|
41
|
+
private timer;
|
|
42
|
+
private running;
|
|
43
|
+
private started;
|
|
44
|
+
private closed;
|
|
45
|
+
private lastCpu;
|
|
46
|
+
private lastCpuAtMs;
|
|
47
|
+
constructor(opts: ResourceSamplerOptions);
|
|
48
|
+
start(): void;
|
|
49
|
+
stop(): void;
|
|
50
|
+
/** Self-rescheduling timer (NOT setInterval) so the cadence can adapt to
|
|
51
|
+
* idle/active each tick and a slow tick can't stack. unref()'d. */
|
|
52
|
+
private schedule;
|
|
53
|
+
/** Run one sampling pass. Public for tests. Never throws. */
|
|
54
|
+
tick(): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* CPU% for THIS process over the interval since the last tick: the
|
|
57
|
+
* (user+system) microseconds consumed divided by the wall-clock microseconds
|
|
58
|
+
* elapsed, ×100. One fully-busy core reads ~100. Returns 0 when there's no
|
|
59
|
+
* prior baseline yet (first tick) or the clock didn't advance.
|
|
60
|
+
*/
|
|
61
|
+
private computeOwnCpuPercent;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=ResourceSampler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceSampler.d.ts","sourceRoot":"","sources":["../../src/monitoring/ResourceSampler.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,cAAc,CAAC;IACvB;+EAC2E;IAC3E,cAAc,EAAE,MAAM,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;IAC7D,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC,WAAW,CAAC;IACzC,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClG,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2C;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkD;IAC7E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAEuC;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IAEjD,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,WAAW,CAAuB;gBAE9B,IAAI,EAAE,sBAAsB;IAgBxC,KAAK,IAAI,IAAI;IAiBb,IAAI,IAAI,IAAI;IAQZ;wEACoE;IACpE,OAAO,CAAC,QAAQ;IAUhB,6DAA6D;IACvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsG3B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAqB7B"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResourceSampler — Phase B of the per-agent ResourceLedger.
|
|
3
|
+
*
|
|
4
|
+
* A background poller (mirrors TokenLedgerPoller) that, on a cadence, samples:
|
|
5
|
+
* (a) the agent's OWN server process — CPU% via a process.cpuUsage() delta
|
|
6
|
+
* over the tick interval, and RSS + V8 heapUsed via process.memoryUsage();
|
|
7
|
+
* (b) the agent's spawned session processes — by their tracked pane PIDs, via
|
|
8
|
+
* ONE batched `ps -o %cpu=,rss= -p <pid>,<pid>,...` call (tolerating dead
|
|
9
|
+
* PIDs), so the resource tracker is itself cheap (a single child process
|
|
10
|
+
* per tick, no per-PID fork storm);
|
|
11
|
+
* and records each plus an `aggregate` (server + all sessions) into the
|
|
12
|
+
* ResourceLedger. After recording it prunes samples beyond the retention window.
|
|
13
|
+
*
|
|
14
|
+
* Discipline (read-only observability, identical to TokenLedgerPoller):
|
|
15
|
+
* - Strictly off the hot path. A sampling error NEVER throws or crashes — every
|
|
16
|
+
* OS call and DB write is guarded; a failed tick just records nothing and the
|
|
17
|
+
* next tick retries.
|
|
18
|
+
* - It never gates, throttles, or reaches back into any runtime flow. It only
|
|
19
|
+
* reads `ps`/`process.*` and writes the ledger.
|
|
20
|
+
* - The timer is unref()'d so it can never keep the process alive on its own,
|
|
21
|
+
* and backs off while the agent is idle (no running sessions) to keep the
|
|
22
|
+
* idle CPU floor low (Responsible Resource Usage).
|
|
23
|
+
*
|
|
24
|
+
* Spec: docs/specs/per-agent-resource-ledger.md.
|
|
25
|
+
*/
|
|
26
|
+
import { execFile } from 'node:child_process';
|
|
27
|
+
export class ResourceSampler {
|
|
28
|
+
ledger;
|
|
29
|
+
getSessionPids;
|
|
30
|
+
intervalMs;
|
|
31
|
+
idleIntervalMs;
|
|
32
|
+
retentionMs;
|
|
33
|
+
cpuUsageFn;
|
|
34
|
+
memoryUsageFn;
|
|
35
|
+
now;
|
|
36
|
+
samplePidsFn;
|
|
37
|
+
onError;
|
|
38
|
+
timer = null;
|
|
39
|
+
running = false;
|
|
40
|
+
started = false;
|
|
41
|
+
closed = false;
|
|
42
|
+
// CPU% for the OWN process is a delta: (cpuMicros now - last) / (wallMs * 1000).
|
|
43
|
+
lastCpu = null;
|
|
44
|
+
lastCpuAtMs = null;
|
|
45
|
+
constructor(opts) {
|
|
46
|
+
this.ledger = opts.ledger;
|
|
47
|
+
this.getSessionPids = opts.getSessionPids;
|
|
48
|
+
this.intervalMs = opts.intervalMs && opts.intervalMs > 0 ? opts.intervalMs : 60_000;
|
|
49
|
+
this.idleIntervalMs =
|
|
50
|
+
opts.idleIntervalMs && opts.idleIntervalMs > 0 ? opts.idleIntervalMs : 5 * 60_000;
|
|
51
|
+
this.retentionMs =
|
|
52
|
+
opts.retentionMs && opts.retentionMs > 0 ? opts.retentionMs : 7 * 24 * 60 * 60 * 1000;
|
|
53
|
+
this.cpuUsageFn = opts.cpuUsageFn ?? ((prev) => process.cpuUsage(prev));
|
|
54
|
+
this.memoryUsageFn = opts.memoryUsageFn ?? (() => process.memoryUsage());
|
|
55
|
+
this.now = opts.now ?? (() => Date.now());
|
|
56
|
+
this.samplePidsFn = opts.samplePidsFn ?? ((pids) => samplePidsViaPs(pids));
|
|
57
|
+
this.onError =
|
|
58
|
+
opts.onError ?? ((err) => console.warn('[resource-ledger] sample error:', err));
|
|
59
|
+
}
|
|
60
|
+
start() {
|
|
61
|
+
if (this.started || this.closed)
|
|
62
|
+
return;
|
|
63
|
+
this.started = true;
|
|
64
|
+
// Prime the CPU baseline so the first real tick has a delta to compare.
|
|
65
|
+
try {
|
|
66
|
+
this.lastCpu = this.cpuUsageFn();
|
|
67
|
+
this.lastCpuAtMs = this.now();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// @silent-fallback-ok: priming the CPU baseline is best-effort. If cpuUsage
|
|
71
|
+
// is unavailable we leave the baseline null so the first real tick reports
|
|
72
|
+
// 0% rather than crashing the sampler at start.
|
|
73
|
+
this.lastCpu = null;
|
|
74
|
+
this.lastCpuAtMs = null;
|
|
75
|
+
}
|
|
76
|
+
this.schedule(this.intervalMs);
|
|
77
|
+
}
|
|
78
|
+
stop() {
|
|
79
|
+
this.started = false;
|
|
80
|
+
if (this.timer) {
|
|
81
|
+
clearTimeout(this.timer);
|
|
82
|
+
this.timer = null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/** Self-rescheduling timer (NOT setInterval) so the cadence can adapt to
|
|
86
|
+
* idle/active each tick and a slow tick can't stack. unref()'d. */
|
|
87
|
+
schedule(delayMs) {
|
|
88
|
+
if (!this.started || this.closed)
|
|
89
|
+
return;
|
|
90
|
+
const t = setTimeout(() => {
|
|
91
|
+
this.timer = null;
|
|
92
|
+
void this.tick();
|
|
93
|
+
}, delayMs);
|
|
94
|
+
t.unref?.();
|
|
95
|
+
this.timer = t;
|
|
96
|
+
}
|
|
97
|
+
/** Run one sampling pass. Public for tests. Never throws. */
|
|
98
|
+
async tick() {
|
|
99
|
+
if (this.running) {
|
|
100
|
+
// A previous tick is still in flight (slow `ps`); skip and reschedule.
|
|
101
|
+
this.schedule(this.intervalMs);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.running = true;
|
|
105
|
+
let nextDelay = this.intervalMs;
|
|
106
|
+
try {
|
|
107
|
+
const ts = this.now();
|
|
108
|
+
const samples = [];
|
|
109
|
+
// (a) Own server process — CPU% from the cpuUsage delta over wall time.
|
|
110
|
+
const ownCpuPercent = this.computeOwnCpuPercent(ts);
|
|
111
|
+
let ownRss = 0;
|
|
112
|
+
let ownHeap = null;
|
|
113
|
+
try {
|
|
114
|
+
const mem = this.memoryUsageFn();
|
|
115
|
+
ownRss = mem.rss;
|
|
116
|
+
ownHeap = mem.heapUsed;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
/* memoryUsage failed — record zero rather than skip the whole tick */
|
|
120
|
+
}
|
|
121
|
+
let aggCpu = ownCpuPercent;
|
|
122
|
+
let aggRss = ownRss;
|
|
123
|
+
samples.push({
|
|
124
|
+
ts,
|
|
125
|
+
source: 'agent-server',
|
|
126
|
+
pid: process.pid,
|
|
127
|
+
cpuPercent: ownCpuPercent,
|
|
128
|
+
rssBytes: ownRss,
|
|
129
|
+
heapUsedBytes: ownHeap,
|
|
130
|
+
});
|
|
131
|
+
// (b) Spawned session processes — one batched ps call for ALL pids.
|
|
132
|
+
let sessions = [];
|
|
133
|
+
try {
|
|
134
|
+
sessions = this.getSessionPids() ?? [];
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
sessions = [];
|
|
138
|
+
}
|
|
139
|
+
if (sessions.length > 0) {
|
|
140
|
+
const pids = sessions
|
|
141
|
+
.map((s) => s.pid)
|
|
142
|
+
.filter((p) => Number.isInteger(p) && p > 0);
|
|
143
|
+
let measured = new Map();
|
|
144
|
+
if (pids.length > 0) {
|
|
145
|
+
try {
|
|
146
|
+
measured = await this.samplePidsFn(pids);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
measured = new Map();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
for (const s of sessions) {
|
|
153
|
+
const m = measured.get(s.pid);
|
|
154
|
+
if (!m)
|
|
155
|
+
continue; // dead/unmeasurable pid — tolerate, skip
|
|
156
|
+
aggCpu += m.cpuPercent;
|
|
157
|
+
aggRss += m.rssBytes;
|
|
158
|
+
samples.push({
|
|
159
|
+
ts,
|
|
160
|
+
source: `session:${s.id}`,
|
|
161
|
+
pid: s.pid,
|
|
162
|
+
cpuPercent: m.cpuPercent,
|
|
163
|
+
rssBytes: m.rssBytes,
|
|
164
|
+
heapUsedBytes: null, // heapUsed is only knowable for our own V8
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// No running sessions → idle. Back off the cadence to keep the idle
|
|
170
|
+
// CPU floor low (Responsible Resource Usage).
|
|
171
|
+
nextDelay = this.idleIntervalMs;
|
|
172
|
+
}
|
|
173
|
+
// Aggregate = server + all sampled sessions.
|
|
174
|
+
samples.push({
|
|
175
|
+
ts,
|
|
176
|
+
source: 'aggregate',
|
|
177
|
+
pid: 0,
|
|
178
|
+
cpuPercent: +aggCpu.toFixed(2),
|
|
179
|
+
rssBytes: aggRss,
|
|
180
|
+
heapUsedBytes: null,
|
|
181
|
+
});
|
|
182
|
+
this.ledger.recordSamples(samples);
|
|
183
|
+
// Bounded retention — prune off the same cadence (cheap single DELETE).
|
|
184
|
+
try {
|
|
185
|
+
this.ledger.pruneOlderThan(ts - this.retentionMs);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
/* swallow */
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
// @silent-fallback-ok: a sampling error NEVER crashes the poller — log once
|
|
193
|
+
// and keep going; the next tick retries. Observability must not break the
|
|
194
|
+
// observed path.
|
|
195
|
+
try {
|
|
196
|
+
this.onError(err);
|
|
197
|
+
}
|
|
198
|
+
catch { /* ignore */ }
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
this.running = false;
|
|
202
|
+
this.schedule(nextDelay);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* CPU% for THIS process over the interval since the last tick: the
|
|
207
|
+
* (user+system) microseconds consumed divided by the wall-clock microseconds
|
|
208
|
+
* elapsed, ×100. One fully-busy core reads ~100. Returns 0 when there's no
|
|
209
|
+
* prior baseline yet (first tick) or the clock didn't advance.
|
|
210
|
+
*/
|
|
211
|
+
computeOwnCpuPercent(nowMs) {
|
|
212
|
+
let cpu;
|
|
213
|
+
try {
|
|
214
|
+
cpu = this.cpuUsageFn();
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// @silent-fallback-ok: a CPU reading we can't take degrades to 0% for this
|
|
218
|
+
// tick (read-only observability); it must never throw into the sample loop.
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
const prev = this.lastCpu;
|
|
222
|
+
const prevAt = this.lastCpuAtMs;
|
|
223
|
+
this.lastCpu = cpu;
|
|
224
|
+
this.lastCpuAtMs = nowMs;
|
|
225
|
+
if (!prev || prevAt == null)
|
|
226
|
+
return 0;
|
|
227
|
+
const wallMs = nowMs - prevAt;
|
|
228
|
+
if (wallMs <= 0)
|
|
229
|
+
return 0;
|
|
230
|
+
const cpuMicros = cpu.user + cpu.system - (prev.user + prev.system);
|
|
231
|
+
const wallMicros = wallMs * 1000;
|
|
232
|
+
const pct = (cpuMicros / wallMicros) * 100;
|
|
233
|
+
return pct > 0 && Number.isFinite(pct) ? +pct.toFixed(2) : 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Batch-sample OS pids with ONE `ps` call. macOS + Linux both support
|
|
238
|
+
* `ps -o %cpu=,rss= -p <pid>[,<pid>...]`; the `=` suffix suppresses headers so
|
|
239
|
+
* the output is just rows of "<cpu> <rss>" aligned with `-p` order... except
|
|
240
|
+
* `ps` reorders by pid, so we ask for pid too and key the result map by pid.
|
|
241
|
+
* rss is reported in KiB → bytes. Dead pids are simply absent from the output
|
|
242
|
+
* (no error). Returns an empty map on any failure (fail-open).
|
|
243
|
+
*/
|
|
244
|
+
function samplePidsViaPs(pids) {
|
|
245
|
+
return new Promise((resolve) => {
|
|
246
|
+
const out = new Map();
|
|
247
|
+
if (pids.length === 0) {
|
|
248
|
+
resolve(out);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const pidList = pids.join(',');
|
|
252
|
+
execFile('ps', ['-o', 'pid=,%cpu=,rss=', '-p', pidList], { timeout: 5000, maxBuffer: 1024 * 1024 }, (err, stdout) => {
|
|
253
|
+
// `ps` exits non-zero when ALL pids are dead; that's not an error for us.
|
|
254
|
+
if (!stdout) {
|
|
255
|
+
resolve(out);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
for (const line of stdout.split('\n')) {
|
|
259
|
+
const m = line.trim().match(/^(\d+)\s+([\d.]+)\s+(\d+)$/);
|
|
260
|
+
if (!m)
|
|
261
|
+
continue;
|
|
262
|
+
const pid = Number(m[1]);
|
|
263
|
+
const cpuPercent = Number(m[2]);
|
|
264
|
+
const rssKib = Number(m[3]);
|
|
265
|
+
if (!Number.isFinite(pid))
|
|
266
|
+
continue;
|
|
267
|
+
out.set(pid, {
|
|
268
|
+
cpuPercent: Number.isFinite(cpuPercent) && cpuPercent > 0 ? cpuPercent : 0,
|
|
269
|
+
rssBytes: Number.isFinite(rssKib) && rssKib > 0 ? rssKib * 1024 : 0,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
void err; // already tolerated
|
|
273
|
+
resolve(out);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=ResourceSampler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceSampler.js","sourceRoot":"","sources":["../../src/monitoring/ResourceSampler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionWatchdog.d.ts","sourceRoot":"","sources":["../../src/monitoring/SessionWatchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAe3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"SessionWatchdog.d.ts","sourceRoot":"","sources":["../../src/monitoring/SessionWatchdog.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,11 @@ import { evaluateThrottleSettle, RATE_LIMIT_SETTLED_CAPTURE_LINES, RATE_LIMIT_DE
|
|
|
22
22
|
function shellExec(cmd, timeout = 5000) {
|
|
23
23
|
return spawnSync('/bin/sh', ['-c', cmd], { encoding: 'utf-8', timeout }).stdout ?? '';
|
|
24
24
|
}
|
|
25
|
+
import { createRequire } from 'node:module';
|
|
26
|
+
// ESM module: a bare CJS `require` is undefined and throws at runtime. Bind a
|
|
27
|
+
// real require via createRequire so the lazy load below is genuinely ESM-legal
|
|
28
|
+
// (mirrors NativeModuleHealer.ts).
|
|
29
|
+
const require = createRequire(import.meta.url);
|
|
25
30
|
export var EscalationLevel;
|
|
26
31
|
(function (EscalationLevel) {
|
|
27
32
|
EscalationLevel[EscalationLevel["Monitoring"] = 0] = "Monitoring";
|