@camstack/addon-post-analysis 1.2.622 → 1.2.623
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/THIRD_PARTY_MODELS.md +2 -2
- package/dist/{clip-model-registry-EDTOCKN9.mjs → clip-model-registry-C58fyELd.mjs} +181 -65
- package/dist/{clip-model-registry-MHJ9BSUV.js → clip-model-registry-KKT83z9U.js} +192 -64
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DAyVukQp.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-_ahOxwNA.mjs} +3 -3
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-V5-s2hmZ.mjs +26 -0
- package/dist/pipeline-analytics/{_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CssYIiFD.mjs → _virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B1HZu0i3.mjs} +1 -1
- package/dist/pipeline-analytics/{hostInit-C4-dCKYR.mjs → hostInit-CdRVx4vF.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +335 -86
- package/dist/pipeline-analytics/index.mjs +335 -86
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CTvx3PDS.mjs +0 -26
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_clip_model_registry = require("../clip-model-registry-
|
|
5
|
+
const require_clip_model_registry = require("../clip-model-registry-KKT83z9U.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_clip_model_registry.__toESM(node_fs, 1);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -5414,41 +5414,106 @@ var NC_TRACKS_AT_INSTANT_LIMIT = 25;
|
|
|
5414
5414
|
*/
|
|
5415
5415
|
var NC_TRACK_LIFE_SLACK_MS = 200;
|
|
5416
5416
|
/**
|
|
5417
|
+
* A position this close to the instant is drawn as it is: one detection tick,
|
|
5418
|
+
* the same notion as {@link NC_TRACK_LIFE_SLACK_MS}. Anything farther is a
|
|
5419
|
+
* position of a MOVED subject, so it is either interpolated (a position on
|
|
5420
|
+
* each side inside the tolerance) or the track is left out — never drawn at a
|
|
5421
|
+
* later place than it was at the picture's instant.
|
|
5422
|
+
*/
|
|
5423
|
+
var NC_BOX_EXACT_MS = NC_TRACK_LIFE_SLACK_MS;
|
|
5424
|
+
/** The box at `timestamp`: a near position as is, else the bracketing pair interpolated. */
|
|
5425
|
+
function boxAt(positions, timestamp, toleranceMs) {
|
|
5426
|
+
let nearest = null;
|
|
5427
|
+
let before = null;
|
|
5428
|
+
let after = null;
|
|
5429
|
+
for (const p of positions) {
|
|
5430
|
+
const d = p.timestamp - timestamp;
|
|
5431
|
+
if (nearest === null || Math.abs(d) < Math.abs(nearest.timestamp - timestamp)) nearest = p;
|
|
5432
|
+
if (d <= 0 && (before === null || p.timestamp > before.timestamp)) before = p;
|
|
5433
|
+
if (d >= 0 && (after === null || p.timestamp < after.timestamp)) after = p;
|
|
5434
|
+
}
|
|
5435
|
+
if (nearest === null) return null;
|
|
5436
|
+
const dt = nearest.timestamp - timestamp;
|
|
5437
|
+
if (Math.abs(dt) <= NC_BOX_EXACT_MS) return {
|
|
5438
|
+
bbox: nearest.bbox,
|
|
5439
|
+
score: nearest.score,
|
|
5440
|
+
dtMs: dt,
|
|
5441
|
+
interpolated: false
|
|
5442
|
+
};
|
|
5443
|
+
if (before === null || after === null || timestamp - before.timestamp > toleranceMs || after.timestamp - timestamp > toleranceMs) return null;
|
|
5444
|
+
const span = after.timestamp - before.timestamp;
|
|
5445
|
+
const f = span === 0 ? 0 : (timestamp - before.timestamp) / span;
|
|
5446
|
+
const lerp = (a, b) => a + (b - a) * f;
|
|
5447
|
+
return {
|
|
5448
|
+
bbox: {
|
|
5449
|
+
x: lerp(before.bbox.x, after.bbox.x),
|
|
5450
|
+
y: lerp(before.bbox.y, after.bbox.y),
|
|
5451
|
+
w: lerp(before.bbox.w, after.bbox.w),
|
|
5452
|
+
h: lerp(before.bbox.h, after.bbox.h)
|
|
5453
|
+
},
|
|
5454
|
+
score: nearest.score,
|
|
5455
|
+
dtMs: dt,
|
|
5456
|
+
interpolated: true
|
|
5457
|
+
};
|
|
5458
|
+
}
|
|
5459
|
+
/**
|
|
5417
5460
|
* Every source track ALIVE at `timestamp` (± {@link NC_TRACK_LIFE_SLACK_MS})
|
|
5418
|
-
* with a
|
|
5419
|
-
*
|
|
5420
|
-
*
|
|
5461
|
+
* with a box AT that instant: a trail position within {@link NC_BOX_EXACT_MS},
|
|
5462
|
+
* else the linear interpolation of the positions bracketing it (each within
|
|
5463
|
+
* `toleranceMs`). A track with neither is not drawn — `onDrop` names it.
|
|
5464
|
+
* Deduplicated by track id (a live copy and a persisted copy are one track).
|
|
5465
|
+
* Pure.
|
|
5421
5466
|
*/
|
|
5422
|
-
function tracksAtInstant(sources, timestamp, toleranceMs, fallbackDims) {
|
|
5467
|
+
function tracksAtInstant(sources, timestamp, toleranceMs, fallbackDims, onDrop) {
|
|
5423
5468
|
const out = /* @__PURE__ */ new Map();
|
|
5424
5469
|
for (const track of sources) {
|
|
5425
5470
|
if (out.has(track.trackId)) continue;
|
|
5426
|
-
if (track.firstSeen > timestamp + NC_TRACK_LIFE_SLACK_MS || track.lastSeen < timestamp - NC_TRACK_LIFE_SLACK_MS)
|
|
5471
|
+
if (track.firstSeen > timestamp + NC_TRACK_LIFE_SLACK_MS || track.lastSeen < timestamp - NC_TRACK_LIFE_SLACK_MS) {
|
|
5472
|
+
onDrop?.({
|
|
5473
|
+
trackId: track.trackId,
|
|
5474
|
+
className: track.className,
|
|
5475
|
+
reason: "outside-life"
|
|
5476
|
+
});
|
|
5477
|
+
continue;
|
|
5478
|
+
}
|
|
5427
5479
|
const w = track.frameWidth ?? fallbackDims?.w ?? 0;
|
|
5428
5480
|
const h = track.frameHeight ?? fallbackDims?.h ?? 0;
|
|
5429
|
-
if (w <= 0 || h <= 0)
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5481
|
+
if (w <= 0 || h <= 0) {
|
|
5482
|
+
onDrop?.({
|
|
5483
|
+
trackId: track.trackId,
|
|
5484
|
+
className: track.className,
|
|
5485
|
+
reason: "no-frame-dims"
|
|
5486
|
+
});
|
|
5487
|
+
continue;
|
|
5488
|
+
}
|
|
5489
|
+
const at = boxAt(track.positions, timestamp, toleranceMs);
|
|
5490
|
+
if (at === null) {
|
|
5491
|
+
const nearestDtMs = track.positions.reduce((best, p) => {
|
|
5492
|
+
const d = p.timestamp - timestamp;
|
|
5493
|
+
return best === void 0 || Math.abs(d) < Math.abs(best) ? d : best;
|
|
5494
|
+
}, void 0);
|
|
5495
|
+
onDrop?.({
|
|
5496
|
+
trackId: track.trackId,
|
|
5497
|
+
className: track.className,
|
|
5498
|
+
reason: "no-position-near-instant",
|
|
5499
|
+
...nearestDtMs !== void 0 ? { nearestDtMs } : {}
|
|
5500
|
+
});
|
|
5501
|
+
continue;
|
|
5438
5502
|
}
|
|
5439
|
-
if (best === null || bestDelta > toleranceMs) continue;
|
|
5440
5503
|
const label = track.subLabel ?? track.label;
|
|
5441
5504
|
out.set(track.trackId, {
|
|
5442
5505
|
trackId: track.trackId,
|
|
5443
5506
|
className: track.className,
|
|
5444
5507
|
...label !== void 0 && label !== track.className ? { label } : {},
|
|
5445
|
-
...
|
|
5508
|
+
...at.score !== void 0 ? { confidence: at.score } : {},
|
|
5446
5509
|
bbox: {
|
|
5447
|
-
x:
|
|
5448
|
-
y:
|
|
5449
|
-
w:
|
|
5450
|
-
h:
|
|
5451
|
-
}
|
|
5510
|
+
x: at.bbox.x / w,
|
|
5511
|
+
y: at.bbox.y / h,
|
|
5512
|
+
w: at.bbox.w / w,
|
|
5513
|
+
h: at.bbox.h / h
|
|
5514
|
+
},
|
|
5515
|
+
dtMs: at.dtMs,
|
|
5516
|
+
interpolated: at.interpolated
|
|
5452
5517
|
});
|
|
5453
5518
|
}
|
|
5454
5519
|
return [...out.values()];
|
|
@@ -19350,11 +19415,16 @@ var DebugNoteArchiveStore = class {
|
|
|
19350
19415
|
};
|
|
19351
19416
|
//#endregion
|
|
19352
19417
|
//#region src/pipeline-analytics/store/event-ledger-collection.ts
|
|
19418
|
+
/**
|
|
19419
|
+
* One event ledger (motion, audio, sensor, faces, plates …) over its
|
|
19420
|
+
* `ctx.records` kind. Every node has `ctx.records`, so there is no other path.
|
|
19421
|
+
*/
|
|
19353
19422
|
/** Matches {@link EventStore.LEDGER_PAGE_SIZE} — kept local to avoid a circular import. */
|
|
19354
19423
|
var LEDGER_PAGE_SIZE = 500;
|
|
19355
19424
|
var EventLedgerCollection = class EventLedgerCollection {
|
|
19356
19425
|
collection;
|
|
19357
19426
|
kind;
|
|
19427
|
+
records;
|
|
19358
19428
|
autoIntegerId;
|
|
19359
19429
|
legacyAtField;
|
|
19360
19430
|
deviceIdMode;
|
|
@@ -19370,6 +19440,7 @@ var EventLedgerCollection = class EventLedgerCollection {
|
|
|
19370
19440
|
this.logger = deps.logger;
|
|
19371
19441
|
this.deriveBody = deps.deriveBody;
|
|
19372
19442
|
this.indexFields = deps.definition.declaration.indexes.map((i) => i.fields);
|
|
19443
|
+
this.records = deps.records;
|
|
19373
19444
|
const handle = deps.records.kind(deps.definition);
|
|
19374
19445
|
this.kind = handle;
|
|
19375
19446
|
}
|
|
@@ -19388,6 +19459,31 @@ var EventLedgerCollection = class EventLedgerCollection {
|
|
|
19388
19459
|
}
|
|
19389
19460
|
await this.kind.put(put);
|
|
19390
19461
|
}
|
|
19462
|
+
/**
|
|
19463
|
+
* `upsertRow` as an op of {@link EventLedgerCollection.transact}. A row that
|
|
19464
|
+
* cannot be mapped THROWS here: inside a transaction a silently skipped write
|
|
19465
|
+
* would let the rest of the call commit without it.
|
|
19466
|
+
*/
|
|
19467
|
+
async txUpsert(id, value) {
|
|
19468
|
+
const put = this.buildRecordPut(id, value);
|
|
19469
|
+
if (put === null) throw new require_clip_model_registry.InvalidRecordError(`${this.collection}/${id}: the record could not be mapped`);
|
|
19470
|
+
return this.kind.txPut(put);
|
|
19471
|
+
}
|
|
19472
|
+
/** `update` as an op of {@link EventLedgerCollection.transact}. */
|
|
19473
|
+
txUpdate(id, patch) {
|
|
19474
|
+
return this.kind.txPatch(id, this.derived(patch, "patch"));
|
|
19475
|
+
}
|
|
19476
|
+
/** `deleteKey` as an op of {@link EventLedgerCollection.transact}. */
|
|
19477
|
+
txDelete(id) {
|
|
19478
|
+
return this.kind.txDelete(id);
|
|
19479
|
+
}
|
|
19480
|
+
/**
|
|
19481
|
+
* Run ops (built by the `tx*` methods of ledgers whose kinds share a
|
|
19482
|
+
* `transactFamily`) in ONE transaction: all land or none does.
|
|
19483
|
+
*/
|
|
19484
|
+
transact(ops) {
|
|
19485
|
+
return this.records.transact(ops);
|
|
19486
|
+
}
|
|
19391
19487
|
async insert(record) {
|
|
19392
19488
|
const idNum = this.autoIntegerId ? await this.kind.allocateId() : null;
|
|
19393
19489
|
const id = idNum !== null ? String(idNum) : typeof record["id"] === "string" ? record["id"] : null;
|
|
@@ -22329,8 +22425,9 @@ var RetrainAnnotationStore = class {
|
|
|
22329
22425
|
* The old rows' deletion, the new rows, the frame's `dismissed` set and its
|
|
22330
22426
|
* bumped `revision` run under a per-frame commit lock, guarded by
|
|
22331
22427
|
* `commit.fromRevision`: a concurrent save in this process leaves one winner
|
|
22332
|
-
* and one `conflict` — never a blend. The
|
|
22333
|
-
*
|
|
22428
|
+
* and one `conflict` — never a blend. The deletion, the new rows and the frame
|
|
22429
|
+
* row are ONE records `transact` (the four retrain kinds share a family): a
|
|
22430
|
+
* failure leaves the frame exactly as it was.
|
|
22334
22431
|
*
|
|
22335
22432
|
* Returns the persisted rows so the caller renders ids it can address.
|
|
22336
22433
|
*/
|
|
@@ -22447,21 +22544,14 @@ var RetrainAnnotationStore = class {
|
|
|
22447
22544
|
}
|
|
22448
22545
|
return stamped;
|
|
22449
22546
|
}
|
|
22450
|
-
/**
|
|
22451
|
-
|
|
22452
|
-
|
|
22453
|
-
|
|
22454
|
-
|
|
22455
|
-
|
|
22456
|
-
|
|
22457
|
-
|
|
22458
|
-
meta: {
|
|
22459
|
-
annotationId: row.id,
|
|
22460
|
-
error: String(err)
|
|
22461
|
-
}
|
|
22462
|
-
});
|
|
22463
|
-
}
|
|
22464
|
-
return rows.length;
|
|
22547
|
+
/**
|
|
22548
|
+
* The delete ops of every annotation of a frame, for ONE transaction with
|
|
22549
|
+
* the frame row and its memberships (RetrainService.removeFrame). A failed
|
|
22550
|
+
* read THROWS: "no annotations" must never be the answer to an unreadable
|
|
22551
|
+
* store, because the frame row would then be deleted over live boxes.
|
|
22552
|
+
*/
|
|
22553
|
+
async deleteOpsForFrame(mediaKey) {
|
|
22554
|
+
return (await this.annotations.query({ where: { mediaKey } })).map((row) => this.annotations.txDelete(row.id));
|
|
22465
22555
|
}
|
|
22466
22556
|
async replaceForFrameOnRecords(mediaKey, rows, commit, nextRevision) {
|
|
22467
22557
|
const frame = await this.frames.get(mediaKey);
|
|
@@ -22474,12 +22564,14 @@ var RetrainAnnotationStore = class {
|
|
|
22474
22564
|
kind: "conflict",
|
|
22475
22565
|
currentRevision
|
|
22476
22566
|
};
|
|
22477
|
-
|
|
22478
|
-
for (const
|
|
22479
|
-
await this.
|
|
22567
|
+
const ops = [];
|
|
22568
|
+
for (const existing of await this.annotations.query({ where: { mediaKey } })) ops.push(this.annotations.txDelete(existing.id));
|
|
22569
|
+
for (const row of rows) ops.push(await this.annotations.txUpsert(row.id, this.toRecord(row)));
|
|
22570
|
+
ops.push(await this.frames.txUpdate(mediaKey, {
|
|
22480
22571
|
revision: nextRevision,
|
|
22481
22572
|
...commit.dismissed !== void 0 ? { dismissed: [...commit.dismissed] } : {}
|
|
22482
|
-
});
|
|
22573
|
+
}));
|
|
22574
|
+
await this.frames.transact(ops);
|
|
22483
22575
|
return {
|
|
22484
22576
|
kind: "saved",
|
|
22485
22577
|
rows,
|
|
@@ -22497,8 +22589,10 @@ var RetrainAnnotationStore = class {
|
|
|
22497
22589
|
kind: "conflict",
|
|
22498
22590
|
currentRevision
|
|
22499
22591
|
};
|
|
22500
|
-
|
|
22501
|
-
await this.
|
|
22592
|
+
const ops = [];
|
|
22593
|
+
for (const row of eligible) ops.push(await this.annotations.txUpdate(row.id, { origin: origins.get(row.id) ?? null }));
|
|
22594
|
+
ops.push(await this.frames.txUpdate(mediaKey, { revision: nextRevision }));
|
|
22595
|
+
await this.frames.transact(ops);
|
|
22502
22596
|
return {
|
|
22503
22597
|
kind: "updated",
|
|
22504
22598
|
updated: eligible.length,
|
|
@@ -22669,16 +22763,16 @@ var RetrainCollectionStore = class {
|
|
|
22669
22763
|
}, counts.get(input.id) ?? 0)
|
|
22670
22764
|
};
|
|
22671
22765
|
}
|
|
22672
|
-
/** Remove the collection and its memberships
|
|
22673
|
-
*
|
|
22766
|
+
/** Remove the collection and its memberships in ONE transaction: a failure
|
|
22767
|
+
* leaves the collection with all its members, never memberships pointing at
|
|
22768
|
+
* a name that no longer exists, nor a collection that silently lost some. */
|
|
22674
22769
|
async delete(id) {
|
|
22675
22770
|
if (await this.readRow(id) === null) return {
|
|
22676
22771
|
deleted: false,
|
|
22677
22772
|
memberFrameIds: []
|
|
22678
22773
|
};
|
|
22679
22774
|
const members = await this.memberships.query({ where: { collectionId: id } });
|
|
22680
|
-
|
|
22681
|
-
await this.collections.deleteKey(id);
|
|
22775
|
+
await this.collections.transact([...members.map((m) => this.memberships.txDelete(m.id)), this.collections.txDelete(id)]);
|
|
22682
22776
|
this.logger.info("retrain collection deleted", { meta: {
|
|
22683
22777
|
collectionId: id,
|
|
22684
22778
|
members: members.length
|
|
@@ -22707,11 +22801,29 @@ var RetrainCollectionStore = class {
|
|
|
22707
22801
|
await this.memberships.deleteKey(key);
|
|
22708
22802
|
return true;
|
|
22709
22803
|
}
|
|
22710
|
-
/**
|
|
22711
|
-
|
|
22712
|
-
|
|
22713
|
-
|
|
22714
|
-
|
|
22804
|
+
/**
|
|
22805
|
+
* The delete ops of every membership of a frame, for ONE transaction with
|
|
22806
|
+
* the frame row and its annotations (RetrainService.removeFrame). A failed
|
|
22807
|
+
* read THROWS: the frame row must not be deleted over memberships nobody
|
|
22808
|
+
* could list.
|
|
22809
|
+
*/
|
|
22810
|
+
async forgetFrameOps(frameId) {
|
|
22811
|
+
return (await this.memberships.query({ where: { frameId } })).map((r) => this.memberships.txDelete(r.id));
|
|
22812
|
+
}
|
|
22813
|
+
/**
|
|
22814
|
+
* The op that adds a frame to a collection, for ONE transaction with the
|
|
22815
|
+
* frame's own row (a still stored from the recording). `null` when it is
|
|
22816
|
+
* already a member: there is nothing to write.
|
|
22817
|
+
*/
|
|
22818
|
+
async addFrameOp(input) {
|
|
22819
|
+
const key = membershipKey(input.collectionId, input.frameId);
|
|
22820
|
+
if (await this.memberships.get(key) !== null) return null;
|
|
22821
|
+
return this.memberships.txUpsert(key, {
|
|
22822
|
+
collectionId: input.collectionId,
|
|
22823
|
+
frameId: input.frameId,
|
|
22824
|
+
deviceId: input.deviceId,
|
|
22825
|
+
addedAt: this.now()
|
|
22826
|
+
});
|
|
22715
22827
|
}
|
|
22716
22828
|
/** The frames of a collection, in the order they were added. */
|
|
22717
22829
|
async listFrameIds(collectionId) {
|
|
@@ -23303,7 +23415,7 @@ var RetrainFrameStore = class {
|
|
|
23303
23415
|
* returned untouched; the blob lands before the row; a refusal is named.
|
|
23304
23416
|
* `capturedAt` IS the instant — the camera saw this frame then.
|
|
23305
23417
|
*/
|
|
23306
|
-
async storeRecordingStill(input) {
|
|
23418
|
+
async storeRecordingStill(input, withRow = []) {
|
|
23307
23419
|
const frameId = recordingFrameId(input.deviceId, input.epochMs);
|
|
23308
23420
|
const existing = await this.get(frameId);
|
|
23309
23421
|
if (existing !== null) return {
|
|
@@ -23350,7 +23462,7 @@ var RetrainFrameStore = class {
|
|
|
23350
23462
|
relativePath: path,
|
|
23351
23463
|
data: input.bytes
|
|
23352
23464
|
});
|
|
23353
|
-
await this.ledger.
|
|
23465
|
+
const row = await this.ledger.txUpsert(frameId, {
|
|
23354
23466
|
deviceId: frame.deviceId,
|
|
23355
23467
|
trackId: "",
|
|
23356
23468
|
sourceMediaId: 0,
|
|
@@ -23367,6 +23479,7 @@ var RetrainFrameStore = class {
|
|
|
23367
23479
|
origin: "recording",
|
|
23368
23480
|
epochMs: input.epochMs
|
|
23369
23481
|
});
|
|
23482
|
+
await this.ledger.transact([row, ...withRow]);
|
|
23370
23483
|
};
|
|
23371
23484
|
try {
|
|
23372
23485
|
if (this.writeGate) await this.writeGate.run(persist);
|
|
@@ -23420,22 +23533,33 @@ var RetrainFrameStore = class {
|
|
|
23420
23533
|
/**
|
|
23421
23534
|
* Drop a copy and its blob — the operator un-selecting a frame.
|
|
23422
23535
|
*
|
|
23423
|
-
* The
|
|
23424
|
-
*
|
|
23425
|
-
*
|
|
23536
|
+
* The ROW goes first, in one transaction with `withRow` (the frame's
|
|
23537
|
+
* annotations and collection memberships, which the caller builds): a failure
|
|
23538
|
+
* leaves the frame, its boxes and its memberships all in place, and throws.
|
|
23539
|
+
* The blob goes after: if that fails the row is already gone and the bytes
|
|
23540
|
+
* are reclaimable junk, logged, never a row pointing at missing media.
|
|
23426
23541
|
*/
|
|
23427
|
-
async deleteFrame(frame) {
|
|
23542
|
+
async deleteFrame(frame, withRow = []) {
|
|
23428
23543
|
const remove = async () => {
|
|
23544
|
+
try {
|
|
23545
|
+
await this.ledger.transact([...withRow, this.ledger.txDelete(frame.frameId)]);
|
|
23546
|
+
} catch (err) {
|
|
23547
|
+
this.logger.error("retrain frame delete failed; nothing was removed", {
|
|
23548
|
+
tags: { deviceId: frame.deviceId },
|
|
23549
|
+
meta: {
|
|
23550
|
+
frameId: frame.frameId,
|
|
23551
|
+
error: String(err)
|
|
23552
|
+
}
|
|
23553
|
+
});
|
|
23554
|
+
throw err;
|
|
23555
|
+
}
|
|
23429
23556
|
try {
|
|
23430
23557
|
await this.storage.delete({
|
|
23431
23558
|
location: frame.locationId ?? LEGACY_RETRAIN_MEDIA_LOCATION,
|
|
23432
23559
|
relativePath: framePath(frame)
|
|
23433
23560
|
});
|
|
23434
|
-
} catch {}
|
|
23435
|
-
try {
|
|
23436
|
-
await this.ledger.deleteKey(frame.frameId);
|
|
23437
23561
|
} catch (err) {
|
|
23438
|
-
this.logger.warn("
|
|
23562
|
+
this.logger.warn("retrain frame removed but its blob could not be deleted", {
|
|
23439
23563
|
tags: { deviceId: frame.deviceId },
|
|
23440
23564
|
meta: {
|
|
23441
23565
|
frameId: frame.frameId,
|
|
@@ -28431,7 +28555,9 @@ function incomingFromSystemEvent(event, lookup) {
|
|
|
28431
28555
|
const blindForMs = numberField(data, "blindForMs");
|
|
28432
28556
|
if (deviceId === void 0 || blindForMs === void 0) return null;
|
|
28433
28557
|
const identity = lookup(deviceId);
|
|
28434
|
-
const
|
|
28558
|
+
const motionMs = numberField(data, "motionMs") ?? blindForMs;
|
|
28559
|
+
const sessions = numberField(data, "sessions") ?? 1;
|
|
28560
|
+
const minutes = Math.max(1, Math.round(motionMs / 6e4));
|
|
28435
28561
|
return systemSubject({
|
|
28436
28562
|
facts,
|
|
28437
28563
|
kind: "detection-blind",
|
|
@@ -28440,13 +28566,39 @@ function incomingFromSystemEvent(event, lookup) {
|
|
|
28440
28566
|
bodyKey: "system.detection-blind.body",
|
|
28441
28567
|
textParams: {
|
|
28442
28568
|
...deviceTextParams(deviceId, identity),
|
|
28443
|
-
minutes: String(minutes)
|
|
28569
|
+
minutes: String(minutes),
|
|
28570
|
+
sessions: String(sessions)
|
|
28444
28571
|
},
|
|
28445
28572
|
textCount: minutes,
|
|
28446
28573
|
deviceId,
|
|
28447
28574
|
...identity !== void 0 ? { deviceType: identity.type } : {}
|
|
28448
28575
|
});
|
|
28449
28576
|
}
|
|
28577
|
+
case "pipeline.motion-noisy":
|
|
28578
|
+
case "pipeline.motion-calm": {
|
|
28579
|
+
const deviceId = numberField(data, "deviceId");
|
|
28580
|
+
const dutyPct = numberField(data, "dutyPct");
|
|
28581
|
+
const sessions = numberField(data, "sessions");
|
|
28582
|
+
const windowMs = numberField(data, "windowMs");
|
|
28583
|
+
if (deviceId === void 0 || dutyPct === void 0 || sessions === void 0 || windowMs === void 0) return null;
|
|
28584
|
+
const noisy = event.category === "pipeline.motion-noisy";
|
|
28585
|
+
const identity = lookup(deviceId);
|
|
28586
|
+
return systemSubject({
|
|
28587
|
+
facts,
|
|
28588
|
+
kind: noisy ? "motion-noisy" : "motion-calm",
|
|
28589
|
+
subject: `motion-noise:${deviceId}`,
|
|
28590
|
+
titleKey: noisy ? "system.motion-noisy.title" : "system.motion-calm.title",
|
|
28591
|
+
bodyKey: noisy ? "system.motion-noisy.body" : "system.motion-calm.body",
|
|
28592
|
+
textParams: {
|
|
28593
|
+
...deviceTextParams(deviceId, identity),
|
|
28594
|
+
minutes: String(Math.max(1, Math.round(windowMs / 6e4))),
|
|
28595
|
+
duty: String(dutyPct),
|
|
28596
|
+
sessions: String(sessions)
|
|
28597
|
+
},
|
|
28598
|
+
deviceId,
|
|
28599
|
+
...identity !== void 0 ? { deviceType: identity.type } : {}
|
|
28600
|
+
});
|
|
28601
|
+
}
|
|
28450
28602
|
case "recording.health.stalled": {
|
|
28451
28603
|
const deviceId = numberField(data, "deviceId");
|
|
28452
28604
|
const idleMs = numberField(data, "idleMs");
|
|
@@ -28564,7 +28716,7 @@ function incomingFromSystemEvent(event, lookup) {
|
|
|
28564
28716
|
case "system.restarting": return incomingFromNodeRestarting(facts, data);
|
|
28565
28717
|
case "recording.export.completed": return incomingFromExportCompleted(facts, data);
|
|
28566
28718
|
case "backup.run-completed": return incomingFromBackupCompleted(facts, data);
|
|
28567
|
-
case "alert.episode": return incomingFromAlertEpisode(facts);
|
|
28719
|
+
case "alert.episode": return incomingFromAlertEpisode(facts, lookup);
|
|
28568
28720
|
default: return null;
|
|
28569
28721
|
}
|
|
28570
28722
|
}
|
|
@@ -28580,9 +28732,11 @@ function incomingFromSystemEvent(event, lookup) {
|
|
|
28580
28732
|
* Whether an edge is notified at all (once per episode, reconciled from the
|
|
28581
28733
|
* alerts store) is decided before this point, by `NcAlertEpisodeLedger`.
|
|
28582
28734
|
*/
|
|
28583
|
-
function incomingFromAlertEpisode(facts) {
|
|
28735
|
+
function incomingFromAlertEpisode(facts, lookup) {
|
|
28584
28736
|
const payload = require_clip_model_registry.parseAlertEpisodePayload(facts.data);
|
|
28585
28737
|
if (payload === null) return null;
|
|
28738
|
+
const attention = incomingFromDeviceAttention(facts, payload, lookup);
|
|
28739
|
+
if (attention !== null) return attention;
|
|
28586
28740
|
const kind = require_clip_model_registry.alertEpisodeKind(payload.severity, payload.phase);
|
|
28587
28741
|
if (kind === null) return null;
|
|
28588
28742
|
return systemSubject({
|
|
@@ -28603,6 +28757,38 @@ function incomingFromAlertEpisode(facts) {
|
|
|
28603
28757
|
...payload.nodeId !== void 0 ? { nodeId: payload.nodeId } : {}
|
|
28604
28758
|
});
|
|
28605
28759
|
}
|
|
28760
|
+
/**
|
|
28761
|
+
* A CRITICAL alert whose source is a DEVICE (D911) is announced in the devices
|
|
28762
|
+
* family — `device-attention-required` / `-resolved`, carrying the device id so
|
|
28763
|
+
* a rule's device filters apply — and NOT as `alert-critical`, so one alert
|
|
28764
|
+
* never notifies twice through two families. A device source whose id is not a
|
|
28765
|
+
* device id falls through to the generic alert kinds.
|
|
28766
|
+
*/
|
|
28767
|
+
function incomingFromDeviceAttention(facts, payload, lookup) {
|
|
28768
|
+
if (payload.sourceType !== "device" || payload.sourceId === void 0) return null;
|
|
28769
|
+
const kind = require_clip_model_registry.deviceAttentionKind(payload.severity, payload.phase);
|
|
28770
|
+
if (kind === null) return null;
|
|
28771
|
+
const deviceId = Number(payload.sourceId);
|
|
28772
|
+
if (!Number.isInteger(deviceId)) return null;
|
|
28773
|
+
const identity = lookup?.(deviceId);
|
|
28774
|
+
return systemSubject({
|
|
28775
|
+
facts,
|
|
28776
|
+
kind,
|
|
28777
|
+
subject: `alert:${payload.episodeId}`,
|
|
28778
|
+
titleKey: `system.${kind}.title`,
|
|
28779
|
+
bodyKey: `system.${kind}.body`,
|
|
28780
|
+
textParams: {
|
|
28781
|
+
...deviceTextParams(deviceId, identity),
|
|
28782
|
+
title: payload.title,
|
|
28783
|
+
message: payload.message,
|
|
28784
|
+
category: payload.category,
|
|
28785
|
+
actionUrl: payload.actionUrl ?? ""
|
|
28786
|
+
},
|
|
28787
|
+
deviceId,
|
|
28788
|
+
...identity !== void 0 ? { deviceType: identity.type } : {},
|
|
28789
|
+
...payload.nodeId !== void 0 ? { nodeId: payload.nodeId } : {}
|
|
28790
|
+
});
|
|
28791
|
+
}
|
|
28606
28792
|
/** The shells whose update has its own sentence. Anything else gets the plain
|
|
28607
28793
|
* one: a body that names a shell nobody observed is worse than a vague body. */
|
|
28608
28794
|
var WRAPPER_BODY_KINDS = new Set([
|
|
@@ -30593,9 +30779,13 @@ var en_default = {
|
|
|
30593
30779
|
"system.addon-crash-loop.body": "The {{addons}} addon on node {{nodeId}} crashed {{count}} times in a row and will NOT be restarted. Everything it provides is offline until it is repaired.",
|
|
30594
30780
|
"system.detection-blind.title": "Detecting nothing — {{deviceName}}",
|
|
30595
30781
|
"system.detection-blind.body": {
|
|
30596
|
-
"one": "Camera {{deviceName}}
|
|
30597
|
-
"other": "Camera {{deviceName}}
|
|
30782
|
+
"one": "Camera {{deviceName}} moved for {{minutes}} minute over {{sessions}} sessions and the detector produced nothing at all, not even a weak candidate",
|
|
30783
|
+
"other": "Camera {{deviceName}} moved for {{minutes}} minutes over {{sessions}} sessions and the detector produced nothing at all, not even a weak candidate"
|
|
30598
30784
|
},
|
|
30785
|
+
"system.motion-noisy.title": "Constant motion, no subject — {{deviceName}}",
|
|
30786
|
+
"system.motion-noisy.body": "Camera {{deviceName}} has been in motion {{duty}}% of the last {{minutes}} minutes ({{sessions}} sessions) without a single detection. The detector is fine — tune this camera's motion zones or sensitivity.",
|
|
30787
|
+
"system.motion-calm.title": "Motion calm again — {{deviceName}}",
|
|
30788
|
+
"system.motion-calm.body": "Camera {{deviceName}} is no longer in constant motion ({{duty}}% of the last {{minutes}} minutes, {{sessions}} sessions)",
|
|
30599
30789
|
"system.recording-stalled.title": "Recording stalled — {{deviceName}}",
|
|
30600
30790
|
"system.recording-stalled.body": {
|
|
30601
30791
|
"one": "Camera {{deviceName}} has not written a recording segment for {{minutes}} minute",
|
|
@@ -30605,6 +30795,10 @@ var en_default = {
|
|
|
30605
30795
|
"system.recording-healthy.body": "Camera {{deviceName}} is writing recording segments again",
|
|
30606
30796
|
"system.recording-degraded.title": "Recording degraded — {{deviceName}}",
|
|
30607
30797
|
"system.recording-degraded.body": "Camera {{deviceName}} exhausted its writer restart budget ({{message}})",
|
|
30798
|
+
"system.device-attention-required.title": "{{title}}",
|
|
30799
|
+
"system.device-attention-required.body": "{{message}}",
|
|
30800
|
+
"system.device-attention-resolved.title": "Resolved: {{title}}",
|
|
30801
|
+
"system.device-attention-resolved.body": "{{deviceName}} no longer needs attention",
|
|
30608
30802
|
"system.storage-location-low.title": "Storage low — {{locationName}}",
|
|
30609
30803
|
"system.storage-location-low.body": "Location {{locationName}} is down to {{freePercent}}% free ({{reason}})",
|
|
30610
30804
|
"system.storage-location-critical.title": "Storage critical — {{locationName}}",
|
|
@@ -30993,6 +31187,10 @@ var it_default = {
|
|
|
30993
31187
|
"system.recording-healthy.body": "La camera {{deviceName}} scrive di nuovo i segmenti",
|
|
30994
31188
|
"system.recording-degraded.title": "Registrazione degradata — {{deviceName}}",
|
|
30995
31189
|
"system.recording-degraded.body": "La camera {{deviceName}} ha esaurito i riavvii del writer ({{message}})",
|
|
31190
|
+
"system.device-attention-required.title": "{{title}}",
|
|
31191
|
+
"system.device-attention-required.body": "{{message}}",
|
|
31192
|
+
"system.device-attention-resolved.title": "Risolto: {{title}}",
|
|
31193
|
+
"system.device-attention-resolved.body": "{{deviceName}} non richiede più intervento",
|
|
30996
31194
|
"system.storage-location-low.title": "Storage basso — {{locationName}}",
|
|
30997
31195
|
"system.storage-location-low.body": "La location {{locationName}} è al {{freePercent}}% libero ({{reason}})",
|
|
30998
31196
|
"system.storage-location-critical.title": "Storage critico — {{locationName}}",
|
|
@@ -31001,9 +31199,13 @@ var it_default = {
|
|
|
31001
31199
|
"system.storage-location-ok.body": "La location {{locationName}} ha recuperato spazio libero",
|
|
31002
31200
|
"system.detection-blind.title": "Senza detection — {{deviceName}}",
|
|
31003
31201
|
"system.detection-blind.body": {
|
|
31004
|
-
"one": "La camera {{deviceName}}
|
|
31005
|
-
"other": "La camera {{deviceName}}
|
|
31202
|
+
"one": "La camera {{deviceName}} ha avuto movimento per {{minutes}} minuto in {{sessions}} sessioni e il detector non ha prodotto nulla, nemmeno un candidato debole",
|
|
31203
|
+
"other": "La camera {{deviceName}} ha avuto movimento per {{minutes}} minuti in {{sessions}} sessioni e il detector non ha prodotto nulla, nemmeno un candidato debole"
|
|
31006
31204
|
},
|
|
31205
|
+
"system.motion-noisy.title": "Movimento continuo senza soggetto — {{deviceName}}",
|
|
31206
|
+
"system.motion-noisy.body": "La camera {{deviceName}} è stata in movimento il {{duty}}% degli ultimi {{minutes}} minuti ({{sessions}} sessioni) senza alcun rilevamento. Il detector funziona — regola le zone di movimento o la sensibilità di questa camera.",
|
|
31207
|
+
"system.motion-calm.title": "Movimento di nuovo calmo — {{deviceName}}",
|
|
31208
|
+
"system.motion-calm.body": "La camera {{deviceName}} non è più in movimento continuo ({{duty}}% degli ultimi {{minutes}} minuti, {{sessions}} sessioni)",
|
|
31007
31209
|
"system.addon-update-available.title": {
|
|
31008
31210
|
"one": "{{count}} aggiornamento addon disponibile",
|
|
31009
31211
|
"other": "{{count}} aggiornamenti addon disponibili"
|
|
@@ -33563,6 +33765,7 @@ function systemEventSubject(kind, scope) {
|
|
|
33563
33765
|
if (kind === "node-online" || kind === "node-offline") return `node:${scope.nodeId ?? "hub"}`;
|
|
33564
33766
|
if (kind === "node-inference-unavailable") return `node-inference:${scope.nodeId ?? "hub"}`;
|
|
33565
33767
|
if (kind === "detection-blind") return `detection-blind:${scope.deviceId ?? 0}`;
|
|
33768
|
+
if (kind === "motion-noisy" || kind === "motion-calm") return `motion-noise:${scope.deviceId ?? 0}`;
|
|
33566
33769
|
if (kind === "addon-crash-loop") return `addon-crash:${scope.nodeId ?? "hub"}:${TEST_CRASHED_RUNNER}`;
|
|
33567
33770
|
if (kind === "addon-update-available" || kind === "server-update-available") return `package:${scope.packageName ?? "@camstack/server"}`;
|
|
33568
33771
|
if (kind === "wrapper-update-available") return `wrapper:${scope.nodeId ?? "hub"}`;
|
|
@@ -33708,6 +33911,8 @@ function planRuleTest(input) {
|
|
|
33708
33911
|
seconds: "30",
|
|
33709
33912
|
devices: "cuda:0",
|
|
33710
33913
|
minutes: "15",
|
|
33914
|
+
duty: "55",
|
|
33915
|
+
sessions: "96",
|
|
33711
33916
|
addons: TEST_CRASHED_RUNNER,
|
|
33712
33917
|
list: "@camstack/addon-pipeline 1.0.1 (current 1.0.0)",
|
|
33713
33918
|
nodes: "hub",
|
|
@@ -40365,7 +40570,17 @@ var NcNotificationImageStage = class {
|
|
|
40365
40570
|
...subjectBox,
|
|
40366
40571
|
label: imageLabelText(payload.subject.label ?? payload.subject.className, payload.subject.confidence)
|
|
40367
40572
|
} : null;
|
|
40368
|
-
const
|
|
40573
|
+
const othersDrawn = mode === "scene-boxes" ? otherTracks(await this.tracksAt(camera, source.timestamp), subjectTrackId, subjectBox, payload.subject.className) : [];
|
|
40574
|
+
if (mode === "scene-boxes") this.deps.logger.info("scene-boxes: other boxes drawn", {
|
|
40575
|
+
tags: { deviceId: camera },
|
|
40576
|
+
meta: {
|
|
40577
|
+
ruleId: entry.ruleId,
|
|
40578
|
+
recordId: entry.recordId,
|
|
40579
|
+
instant: source.timestamp,
|
|
40580
|
+
drawn: othersDrawn.map((t) => `${t.trackId}/${t.className}/dt=${t.dtMs ?? "?"}ms/${t.interpolated === true ? "interpolated" : "exact"}`).join(",")
|
|
40581
|
+
}
|
|
40582
|
+
});
|
|
40583
|
+
const others = mode === "scene-boxes" ? othersDrawn.map((t) => ({
|
|
40369
40584
|
...t.bbox,
|
|
40370
40585
|
label: imageLabelText(t.label ?? t.className, t.confidence),
|
|
40371
40586
|
...t.confidence !== void 0 ? { confidence: t.confidence } : {}
|
|
@@ -87732,7 +87947,12 @@ var RetrainCollectionService = class {
|
|
|
87732
87947
|
reason: "unknown-collection"
|
|
87733
87948
|
};
|
|
87734
87949
|
}
|
|
87735
|
-
const
|
|
87950
|
+
const membershipOp = await this.deps.collections.addFrameOp({
|
|
87951
|
+
collectionId: input.collectionId,
|
|
87952
|
+
frameId: recordingFrameId(input.deviceId, input.epochMs),
|
|
87953
|
+
deviceId: input.deviceId
|
|
87954
|
+
});
|
|
87955
|
+
const stored = await this.storeStill(input.deviceId, input.epochMs, membershipOp === null ? [] : [membershipOp]);
|
|
87736
87956
|
if (stored.kind === "refused") {
|
|
87737
87957
|
this.deps.logger.info("retrain collection add refused", {
|
|
87738
87958
|
tags,
|
|
@@ -87744,7 +87964,7 @@ var RetrainCollectionService = class {
|
|
|
87744
87964
|
});
|
|
87745
87965
|
return stored;
|
|
87746
87966
|
}
|
|
87747
|
-
await this.deps.collections.addFrame({
|
|
87967
|
+
if (stored.reused) await this.deps.collections.addFrame({
|
|
87748
87968
|
collectionId: input.collectionId,
|
|
87749
87969
|
frameId: stored.frame.frameId,
|
|
87750
87970
|
deviceId: input.deviceId
|
|
@@ -87809,7 +88029,7 @@ var RetrainCollectionService = class {
|
|
|
87809
88029
|
const ids = await this.deps.collections.listFrameIds(input.collectionId);
|
|
87810
88030
|
return this.deps.retrain.toWireFrames(await this.deps.frames.getMany(ids));
|
|
87811
88031
|
}
|
|
87812
|
-
async storeStill(deviceId, epochMs) {
|
|
88032
|
+
async storeStill(deviceId, epochMs, withRow) {
|
|
87813
88033
|
const existing = await this.deps.frames.get(recordingFrameId(deviceId, epochMs));
|
|
87814
88034
|
if (existing !== null) return {
|
|
87815
88035
|
kind: "stored",
|
|
@@ -87829,7 +88049,7 @@ var RetrainCollectionService = class {
|
|
|
87829
88049
|
deviceId,
|
|
87830
88050
|
epochMs,
|
|
87831
88051
|
bytes: still.jpeg
|
|
87832
|
-
});
|
|
88052
|
+
}, withRow);
|
|
87833
88053
|
return stored.kind === "copied" ? {
|
|
87834
88054
|
kind: "stored",
|
|
87835
88055
|
frame: stored.frame,
|
|
@@ -90152,9 +90372,9 @@ var RetrainService = class {
|
|
|
90152
90372
|
...this.frameUrls(updated.frameId)
|
|
90153
90373
|
};
|
|
90154
90374
|
}
|
|
90155
|
-
/** Un-select:
|
|
90156
|
-
* an annotation whose frame is gone is unopenable
|
|
90157
|
-
*
|
|
90375
|
+
/** Un-select: the frame row, its annotations and its collection memberships
|
|
90376
|
+
* leave in one transaction (an annotation whose frame is gone is unopenable
|
|
90377
|
+
* and unfixable, so they never part); the blob is deleted after the row. */
|
|
90158
90378
|
async deselectFrame(input) {
|
|
90159
90379
|
const frame = await this.deps.frames.get(input.frameId);
|
|
90160
90380
|
if (frame === null) {
|
|
@@ -90173,11 +90393,16 @@ var RetrainService = class {
|
|
|
90173
90393
|
removedAnnotations: await this.removeFrame(frame)
|
|
90174
90394
|
};
|
|
90175
90395
|
}
|
|
90176
|
-
/**
|
|
90396
|
+
/**
|
|
90397
|
+
* Remove a frame from the dataset. The frame row, its annotations and its
|
|
90398
|
+
* collection memberships leave in ONE transaction (a failure removes nothing
|
|
90399
|
+
* and throws); the blob is deleted after the row, never before.
|
|
90400
|
+
*/
|
|
90177
90401
|
async removeFrame(frame) {
|
|
90178
|
-
const
|
|
90179
|
-
await this.deps.memberships?.
|
|
90180
|
-
await this.deps.frames.deleteFrame(frame);
|
|
90402
|
+
const annotationOps = await this.deps.annotations.deleteOpsForFrame(frame.frameId);
|
|
90403
|
+
const membershipOps = await this.deps.memberships?.forgetFrameOps(frame.frameId) ?? [];
|
|
90404
|
+
await this.deps.frames.deleteFrame(frame, [...annotationOps, ...membershipOps]);
|
|
90405
|
+
const removedAnnotations = annotationOps.length;
|
|
90181
90406
|
this.deps.logger.info("retrain frame removed from the dataset", {
|
|
90182
90407
|
tags: { deviceId: frame.deviceId },
|
|
90183
90408
|
meta: {
|
|
@@ -90371,7 +90596,8 @@ var RetrainService = class {
|
|
|
90371
90596
|
* The guarded replace. A caller that names the revision it saw gets exactly
|
|
90372
90597
|
* one attempt: a different current revision is a conflict, never a retry —
|
|
90373
90598
|
* the point is that it must look again. A caller that names none asked for
|
|
90374
|
-
* last-write-wins, so a race lost between our read and the
|
|
90599
|
+
* last-write-wins, so a race lost between our revision read and the records
|
|
90600
|
+
* `transact` that commits the save (a per-frame lock serialises the two) is
|
|
90375
90601
|
* retried on the fresh revision, a bounded number of times.
|
|
90376
90602
|
*/
|
|
90377
90603
|
async replaceGuarded(frame, input, drafts, dismissed) {
|
|
@@ -103998,6 +104224,8 @@ var NC_SYSTEM_EVENT_CATEGORIES = [
|
|
|
103998
104224
|
require_clip_model_registry.EventCategory.WorkerOffline,
|
|
103999
104225
|
require_clip_model_registry.EventCategory.PipelineNodeInferenceUnavailable,
|
|
104000
104226
|
require_clip_model_registry.EventCategory.PipelineDetectionBlind,
|
|
104227
|
+
require_clip_model_registry.EventCategory.PipelineMotionNoisy,
|
|
104228
|
+
require_clip_model_registry.EventCategory.PipelineMotionCalm,
|
|
104001
104229
|
require_clip_model_registry.EventCategory.RecordingHealthStalled,
|
|
104002
104230
|
require_clip_model_registry.EventCategory.RecordingHealthOk,
|
|
104003
104231
|
require_clip_model_registry.EventCategory.RecordingHealthDegraded,
|
|
@@ -107016,6 +107244,18 @@ Object.freeze({
|
|
|
107016
107244
|
"empty"
|
|
107017
107245
|
]
|
|
107018
107246
|
},
|
|
107247
|
+
{
|
|
107248
|
+
"path": "filterCleaningDue",
|
|
107249
|
+
"valueType": "boolean"
|
|
107250
|
+
},
|
|
107251
|
+
{
|
|
107252
|
+
"path": "machineCareDue",
|
|
107253
|
+
"valueType": "boolean"
|
|
107254
|
+
},
|
|
107255
|
+
{
|
|
107256
|
+
"path": "machineCareRemainingRuns",
|
|
107257
|
+
"valueType": "number"
|
|
107258
|
+
},
|
|
107019
107259
|
{
|
|
107020
107260
|
"path": "halfLoad",
|
|
107021
107261
|
"valueType": "boolean"
|
|
@@ -116310,7 +116550,16 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_clip_m
|
|
|
116310
116550
|
since: timestamp - toleranceMs,
|
|
116311
116551
|
limit: NC_TRACKS_AT_INSTANT_LIMIT
|
|
116312
116552
|
});
|
|
116313
|
-
return tracksAtInstant([...live, ...persisted.tracks], timestamp, toleranceMs, this.lastFrameDimsByDevice.get(deviceId))
|
|
116553
|
+
return tracksAtInstant([...live, ...persisted.tracks], timestamp, toleranceMs, this.lastFrameDimsByDevice.get(deviceId), (drop) => this.ctx.logger.info("scene-boxes: other track not drawn", {
|
|
116554
|
+
tags: { deviceId },
|
|
116555
|
+
meta: {
|
|
116556
|
+
trackId: drop.trackId,
|
|
116557
|
+
className: drop.className,
|
|
116558
|
+
reason: drop.reason,
|
|
116559
|
+
instant: timestamp,
|
|
116560
|
+
...drop.nearestDtMs !== void 0 ? { nearestDtMs: drop.nearestDtMs } : {}
|
|
116561
|
+
}
|
|
116562
|
+
}));
|
|
116314
116563
|
},
|
|
116315
116564
|
getDeviceName,
|
|
116316
116565
|
getDeviceLocation,
|