@trillboards/edge-sdk 0.2.40 → 0.2.41
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/README.md +1 -1
- package/deploy/docker/{Dockerfile.cloud-sense → Dockerfile.connector} +52 -39
- package/deploy/docker/README.md +73 -1
- package/deploy/docker/connector-entrypoint.sh +46 -80
- package/deploy/macos/README.md +1 -1
- package/deploy/macos/test-install-pair.sh +9 -9
- package/deploy/systemd/install.sh +16 -1
- package/deploy/systemd/setup-litertlm.sh +201 -0
- package/deploy/systemd/trillboards-edge.service +8 -4
- package/deploy/systemd/trillboards-litertlm.service +46 -0
- package/deploy/windows/register-task.ps1 +6 -3
- package/deploy/windows/run-connector.ps1 +1 -1
- package/deploy/windows/trillboards-edge-task.vbs +5 -1
- package/dist/CloudSensingManager.d.ts +45 -19
- package/dist/CloudSensingManager.d.ts.map +1 -1
- package/dist/CloudSensingManager.js +89 -46
- package/dist/CloudSensingManager.js.map +1 -1
- package/dist/EdgeAgent.js +1 -1
- package/dist/SensingProfileClient.d.ts +9 -0
- package/dist/SensingProfileClient.d.ts.map +1 -1
- package/dist/SensingProfileClient.js +4 -0
- package/dist/SensingProfileClient.js.map +1 -1
- package/dist/SetupSessionClient.d.ts +0 -1
- package/dist/SetupSessionClient.d.ts.map +1 -1
- package/dist/autoSense.d.ts +42 -31
- package/dist/autoSense.d.ts.map +1 -1
- package/dist/autoSense.js +127 -99
- package/dist/autoSense.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +25 -84
- package/dist/cli.js.map +1 -1
- package/dist/combinedSense.d.ts +1 -3
- package/dist/combinedSense.d.ts.map +1 -1
- package/dist/combinedSense.js +0 -1
- package/dist/combinedSense.js.map +1 -1
- package/dist/config.d.ts +17 -64
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -10
- package/dist/config.js.map +1 -1
- package/dist/deployedCadence.d.ts +37 -75
- package/dist/deployedCadence.d.ts.map +1 -1
- package/dist/deployedCadence.js +45 -105
- package/dist/deployedCadence.js.map +1 -1
- package/dist/deployedCadenceSource.d.ts +0 -2
- package/dist/deployedCadenceSource.d.ts.map +1 -1
- package/dist/deployedCadenceSource.js +0 -1
- package/dist/deployedCadenceSource.js.map +1 -1
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.js +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -8
- package/dist/index.js.map +1 -1
- package/dist/localInferenceSchema.d.ts +19 -0
- package/dist/localInferenceSchema.d.ts.map +1 -1
- package/dist/localInferenceSchema.js +23 -0
- package/dist/localInferenceSchema.js.map +1 -1
- package/dist/localSensing.d.ts +48 -107
- package/dist/localSensing.d.ts.map +1 -1
- package/dist/localSensing.js +80 -171
- package/dist/localSensing.js.map +1 -1
- package/dist/sensingCatchRate.d.ts +246 -0
- package/dist/sensingCatchRate.d.ts.map +1 -0
- package/dist/sensingCatchRate.js +514 -0
- package/dist/sensingCatchRate.js.map +1 -0
- package/dist/sensingRunMode.d.ts +14 -11
- package/dist/sensingRunMode.d.ts.map +1 -1
- package/dist/sensingRunMode.js +9 -92
- package/dist/sensingRunMode.js.map +1 -1
- package/dist/setupMode.d.ts +0 -1
- package/dist/setupMode.d.ts.map +1 -1
- package/dist/setupMode.js +5 -3
- package/dist/setupMode.js.map +1 -1
- package/dist/startupDiscovery.d.ts +43 -0
- package/dist/startupDiscovery.d.ts.map +1 -0
- package/dist/startupDiscovery.js +72 -0
- package/dist/startupDiscovery.js.map +1 -0
- package/package.json +1 -1
- package/dist/CloudEscalationPolicy.d.ts +0 -143
- package/dist/CloudEscalationPolicy.d.ts.map +0 -1
- package/dist/CloudEscalationPolicy.js +0 -137
- package/dist/CloudEscalationPolicy.js.map +0 -1
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SAMPLER = exports.TEMPORAL_SHAPES = exports.SHAPE_GROUPS = void 0;
|
|
4
|
+
exports.shapeById = shapeById;
|
|
5
|
+
exports.classifyShape = classifyShape;
|
|
6
|
+
exports.lookCoverage = lookCoverage;
|
|
7
|
+
exports.expectedCatchRate = expectedCatchRate;
|
|
8
|
+
exports.replay = replay;
|
|
9
|
+
exports.reportByShape = reportByShape;
|
|
10
|
+
exports.reportByGroup = reportByGroup;
|
|
11
|
+
exports.requiredLookCadenceS = requiredLookCadenceS;
|
|
12
|
+
/**
|
|
13
|
+
* sensingCatchRate — CATCH RATE as a measured, per-temporal-shape number.
|
|
14
|
+
*
|
|
15
|
+
* ── The question this answers ───────────────────────────────────────────────
|
|
16
|
+
*
|
|
17
|
+
* The product sells ~50 distinct promises ("text me when the line passes 3",
|
|
18
|
+
* "alert me if a vehicle pulls in after closing", "tell me when the yard is
|
|
19
|
+
* full"). Every one of them is a claim that we will NOTICE something. Nothing
|
|
20
|
+
* in the tree measured whether we do.
|
|
21
|
+
*
|
|
22
|
+
* A single blended "catch rate" is worse than none, because the spread is the
|
|
23
|
+
* whole story: at the shipped 30 s look cadence a 2.2 s door-open is caught
|
|
24
|
+
* ~7% of the time and a full car park is caught ~100% of the time. Averaging
|
|
25
|
+
* those produces a number that describes no promise we actually sell. So the
|
|
26
|
+
* unit of measurement here is the TEMPORAL SHAPE, and every rate is reported
|
|
27
|
+
* with its false-trigger rate beside it — a detector that fires constantly has
|
|
28
|
+
* a wonderful catch rate.
|
|
29
|
+
*
|
|
30
|
+
* ── The mechanism, which is OURS and not a model of one ─────────────────────
|
|
31
|
+
*
|
|
32
|
+
* `CloudSensingManager` runs one cadence loop per feed. Each tick is a LOOK:
|
|
33
|
+
* pull a frame, run `MotionGate.evaluate`. Looking is cheap (3.6 ms median —
|
|
34
|
+
* see connectorCadence.ts) and its interval is `faceTriggeredIntervalMs`,
|
|
35
|
+
* `LOOK_INTERVAL_MS` = 30 s. Only when the gate says `analyze` does the frame
|
|
36
|
+
* contend for the single `VlmAdmissionGate` slot, and an analysis costs
|
|
37
|
+
* `MEASURED_LOCAL_ANALYZE_MS` = 7.30 s.
|
|
38
|
+
*
|
|
39
|
+
* The consequence is the entire finding, and it is arithmetic:
|
|
40
|
+
*
|
|
41
|
+
* an event is catchable only if a LOOK lands inside it.
|
|
42
|
+
*
|
|
43
|
+
* A motion gate cannot see motion it did not look at. For an event of duration
|
|
44
|
+
* `d` against a look cadence `T` whose phase is uncorrelated with the event,
|
|
45
|
+
* the probability that at least one look lands inside is `min(d/T, 1)`, so
|
|
46
|
+
*
|
|
47
|
+
* catch rate = E[ min(d/T, 1) ] x P(admitted before the buffer TTL)
|
|
48
|
+
* x P(the model reads the frame right)
|
|
49
|
+
*
|
|
50
|
+
* The first factor dominates and it is bounded by the LOOK cadence — not by
|
|
51
|
+
* the analysis budget everyone reaches for first. That distinction is load
|
|
52
|
+
* bearing: looking 12x more often costs 2.3% of one core across 16 feeds,
|
|
53
|
+
* while analyzing 12x more often is impossible on one 7.30 s slot. The two
|
|
54
|
+
* cadences are separable and today they are not separated.
|
|
55
|
+
*
|
|
56
|
+
* ── Why the closed form is not enough, and the replay exists ────────────────
|
|
57
|
+
*
|
|
58
|
+
* `expectedCatchRate` below IS that closed form and it is used to VALIDATE the
|
|
59
|
+
* replay, never to replace it. The closed form assumes an uncorrelated phase,
|
|
60
|
+
* an always-free admission slot, and a gate that never misses motion it looked
|
|
61
|
+
* at. The replay drops all three: it advances real look ticks against real
|
|
62
|
+
* event intervals, contends for a shared slot at the measured analysis cost,
|
|
63
|
+
* and honours the candidate buffer's TTL. Where they disagree, the disagreement
|
|
64
|
+
* IS the measurement — a shape whose replayed rate sits far below its closed
|
|
65
|
+
* form is starved by the slot, not by the cadence, and that is a different fix.
|
|
66
|
+
*
|
|
67
|
+
* ── What is deliberately NOT scored here ────────────────────────────────────
|
|
68
|
+
*
|
|
69
|
+
* Per-field content accuracy. `scoreFields` in localVlmBench.ts already does
|
|
70
|
+
* that, it is unit-tested, and it deliberately never scores `confidence`.
|
|
71
|
+
* The content layer enters this file only as `fieldAccuracy` — one number per
|
|
72
|
+
* shape, supplied by a scored replay — because a second scorer would drift
|
|
73
|
+
* from the first and the two would disagree about the same frame.
|
|
74
|
+
*/
|
|
75
|
+
const connectorCadence_1 = require("./connectorCadence");
|
|
76
|
+
exports.SHAPE_GROUPS = ['Instant', 'Brief', 'Sustained', 'State'];
|
|
77
|
+
/**
|
|
78
|
+
* Seven shapes. Each `exampleField` is a real `condition_field` present in
|
|
79
|
+
* `sensing_routes` in production — this table is a classification of what we
|
|
80
|
+
* already sell, not a wish list.
|
|
81
|
+
*
|
|
82
|
+
* The duration bands are cut where the FAILURE MODE changes, not on round
|
|
83
|
+
* numbers. Below ~3 s a 30 s look cadence misses the event outright. Between
|
|
84
|
+
* 3 s and 30 s the look lands but the single admission slot (7.30 s) may still
|
|
85
|
+
* lose it. Past 30 s at least one look is guaranteed and the question stops
|
|
86
|
+
* being "did we see it" and becomes "did we fire on the right edge".
|
|
87
|
+
*/
|
|
88
|
+
exports.TEMPORAL_SHAPES = Object.freeze([
|
|
89
|
+
{
|
|
90
|
+
id: 'instant',
|
|
91
|
+
group: 'Instant',
|
|
92
|
+
description: 'A punctual act that is over before the next look. A door opens; a package is put down.',
|
|
93
|
+
minDurationS: 0,
|
|
94
|
+
maxDurationS: 3,
|
|
95
|
+
rulePolicy: 'once_per_episode',
|
|
96
|
+
holdSeconds: 0,
|
|
97
|
+
exampleField: 'package_detected',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'arrival',
|
|
101
|
+
group: 'Instant',
|
|
102
|
+
description: 'An entity crossing a boundary. One alert per NEW entity, so a crowd arriving one-by-one costs one alert.',
|
|
103
|
+
minDurationS: 0,
|
|
104
|
+
maxDurationS: 3,
|
|
105
|
+
rulePolicy: 'per_new_entity',
|
|
106
|
+
holdSeconds: 0,
|
|
107
|
+
exampleField: 'person_entered',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 'interaction',
|
|
111
|
+
group: 'Brief',
|
|
112
|
+
description: 'A bounded interaction between people, or a person and a thing. A purchase; someone waiting at a counter.',
|
|
113
|
+
minDurationS: 3,
|
|
114
|
+
maxDurationS: 30,
|
|
115
|
+
rulePolicy: 'once_per_episode',
|
|
116
|
+
holdSeconds: 0,
|
|
117
|
+
exampleField: 'customer_count',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'excursion',
|
|
121
|
+
group: 'Brief',
|
|
122
|
+
description: 'A count crossing a line and coming back. The queue passes three, then clears.',
|
|
123
|
+
minDurationS: 3,
|
|
124
|
+
maxDurationS: 30,
|
|
125
|
+
rulePolicy: 'on_escalation',
|
|
126
|
+
holdSeconds: 0,
|
|
127
|
+
exampleField: 'person_count',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'dwell',
|
|
131
|
+
group: 'Sustained',
|
|
132
|
+
description: 'Something that only matters once it has HELD. Loitering; a hazard left on the floor.',
|
|
133
|
+
minDurationS: 30,
|
|
134
|
+
maxDurationS: Infinity,
|
|
135
|
+
rulePolicy: 'once_per_episode',
|
|
136
|
+
holdSeconds: 111,
|
|
137
|
+
exampleField: 'loitering_duration_seconds',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: 'condition',
|
|
141
|
+
group: 'State',
|
|
142
|
+
description: 'A level that is simply true for a long time. The yard is full; a vehicle is in the bay after closing.',
|
|
143
|
+
minDurationS: 30,
|
|
144
|
+
maxDurationS: Infinity,
|
|
145
|
+
rulePolicy: 'once_per_episode',
|
|
146
|
+
holdSeconds: 0,
|
|
147
|
+
exampleField: 'vehicle_count',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: 'absence',
|
|
151
|
+
group: 'State',
|
|
152
|
+
description: 'Nothing where something should be. No one on the till; the fire lane is meant to be clear and is not.',
|
|
153
|
+
minDurationS: 30,
|
|
154
|
+
maxDurationS: Infinity,
|
|
155
|
+
rulePolicy: 'nag_until_resolved',
|
|
156
|
+
holdSeconds: 0,
|
|
157
|
+
exampleField: 'fire_lane_violation',
|
|
158
|
+
},
|
|
159
|
+
]);
|
|
160
|
+
const SHAPE_BY_ID = new Map(exports.TEMPORAL_SHAPES.map((s) => [s.id, s]));
|
|
161
|
+
/** Look a shape up by id. `null` — never a throw — for an unknown id. */
|
|
162
|
+
function shapeById(id) {
|
|
163
|
+
return SHAPE_BY_ID.get(id) || null;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The shape of an annotated event.
|
|
167
|
+
*
|
|
168
|
+
* Duration alone does NOT determine the shape: `instant` and `arrival` share a
|
|
169
|
+
* band and are separated by the rule policy, as do `interaction`/`excursion`
|
|
170
|
+
* and `condition`/`absence`. So the corpus must carry the policy, and this
|
|
171
|
+
* function refuses to guess when it is absent rather than silently picking the
|
|
172
|
+
* first band match — a misclassified event lands in the wrong shape's rate and
|
|
173
|
+
* is invisible.
|
|
174
|
+
*/
|
|
175
|
+
function classifyShape(durationS, rulePolicy) {
|
|
176
|
+
if (!Number.isFinite(durationS) || durationS < 0)
|
|
177
|
+
return null;
|
|
178
|
+
for (const shape of exports.TEMPORAL_SHAPES) {
|
|
179
|
+
if (durationS >= shape.minDurationS && durationS < shape.maxDurationS
|
|
180
|
+
&& shape.rulePolicy === rulePolicy)
|
|
181
|
+
return shape;
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
// ---------------------------------------------------------------------------
|
|
186
|
+
// The closed form — used to VALIDATE the replay, never to replace it
|
|
187
|
+
// ---------------------------------------------------------------------------
|
|
188
|
+
/**
|
|
189
|
+
* P(at least one look lands inside an event of `durationS`) for a periodic
|
|
190
|
+
* look cadence of `cadenceS` whose phase is uncorrelated with the event.
|
|
191
|
+
*
|
|
192
|
+
* `min(d/T, 1)`. An event at least as long as the cadence is caught with
|
|
193
|
+
* certainty; a shorter one is caught in proportion to how much of the cadence
|
|
194
|
+
* it occupies. This is the ceiling every other factor multiplies down from.
|
|
195
|
+
*/
|
|
196
|
+
function lookCoverage(durationS, cadenceS) {
|
|
197
|
+
if (!Number.isFinite(durationS) || durationS <= 0)
|
|
198
|
+
return 0;
|
|
199
|
+
if (!Number.isFinite(cadenceS) || cadenceS <= 0)
|
|
200
|
+
return 1;
|
|
201
|
+
return Math.min(durationS / cadenceS, 1);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The closed-form catch rate over a whole duration sample: `E[min(d/T, 1)]`.
|
|
205
|
+
*
|
|
206
|
+
* Note this is driven by the MEAN of the truncated ratio, not by the median
|
|
207
|
+
* duration. A right-skewed duration sample — which every real activity corpus
|
|
208
|
+
* is — has a mean well above its median, so quoting `median/T` understates the
|
|
209
|
+
* rate. That is exactly the arithmetic behind the published baseline: 59,093
|
|
210
|
+
* activities with a 2.4 s median catch at 18.2%, not at 2.4/30 = 8.0%.
|
|
211
|
+
*/
|
|
212
|
+
function expectedCatchRate(durationsS, cadenceS) {
|
|
213
|
+
const clean = (durationsS || []).filter((d) => typeof d === 'number' && Number.isFinite(d) && d >= 0);
|
|
214
|
+
if (clean.length === 0)
|
|
215
|
+
return null;
|
|
216
|
+
let acc = 0;
|
|
217
|
+
for (const d of clean)
|
|
218
|
+
acc += lookCoverage(d, cadenceS);
|
|
219
|
+
return acc / clean.length;
|
|
220
|
+
}
|
|
221
|
+
exports.DEFAULT_SAMPLER = Object.freeze({
|
|
222
|
+
lookCadenceS: connectorCadence_1.LOOK_INTERVAL_MS / 1000,
|
|
223
|
+
heartbeatS: 300,
|
|
224
|
+
maxInFlight: 1,
|
|
225
|
+
analyzeS: connectorCadence_1.MEASURED_LOCAL_ANALYZE_MS / 1000,
|
|
226
|
+
bufferTtlS: 90,
|
|
227
|
+
bufferMaxFrames: 32,
|
|
228
|
+
fieldAccuracy: 1,
|
|
229
|
+
falsePositiveRate: 0,
|
|
230
|
+
});
|
|
231
|
+
/**
|
|
232
|
+
* A tiny deterministic PRNG. Seeded and explicit, because a replay whose
|
|
233
|
+
* numbers move between runs cannot be a regression gate — and because
|
|
234
|
+
* `Math.random()` in an eval is how a flaky CI check gets born.
|
|
235
|
+
*/
|
|
236
|
+
function mulberry32(seed) {
|
|
237
|
+
let a = seed >>> 0;
|
|
238
|
+
return () => {
|
|
239
|
+
a = (a + 0x6D2B79F5) >>> 0;
|
|
240
|
+
let t = Math.imul(a ^ (a >>> 15), 1 | a);
|
|
241
|
+
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
|
242
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Replay an annotated corpus through the shipped scheduling law.
|
|
247
|
+
*
|
|
248
|
+
* The loop is the real one, in the real order:
|
|
249
|
+
* look tick per feed (staggered) -> motion gate -> admission slot ->
|
|
250
|
+
* candidate buffer on denial -> pump when the slot frees.
|
|
251
|
+
*
|
|
252
|
+
* `durationS` is the replay length; events must fall inside it. `seed` fixes
|
|
253
|
+
* the per-feed look PHASE, which is the only stochastic input — and it is the
|
|
254
|
+
* one that matters, because a phase locked to the events would manufacture a
|
|
255
|
+
* catch rate of either 0% or 100%.
|
|
256
|
+
*/
|
|
257
|
+
function replay(events, config = {}, { durationS, seed = 1 }) {
|
|
258
|
+
const cfg = { ...exports.DEFAULT_SAMPLER, ...config };
|
|
259
|
+
const rand = mulberry32(seed);
|
|
260
|
+
const feeds = Array.from(new Set(events.map((e) => e.feed))).sort();
|
|
261
|
+
// Per-feed look phase. `feedStaggerMs` in CloudSensingManager spreads feeds
|
|
262
|
+
// across one cadence so N cameras never grab simultaneously; the random
|
|
263
|
+
// component is the event-uncorrelated part.
|
|
264
|
+
const phase = new Map();
|
|
265
|
+
feeds.forEach((f, i) => {
|
|
266
|
+
const stagger = feeds.length > 0 ? (i * cfg.lookCadenceS) / feeds.length : 0;
|
|
267
|
+
phase.set(f, (stagger + rand() * cfg.lookCadenceS) % cfg.lookCadenceS);
|
|
268
|
+
});
|
|
269
|
+
const byFeed = new Map();
|
|
270
|
+
for (const e of events) {
|
|
271
|
+
if (!byFeed.has(e.feed))
|
|
272
|
+
byFeed.set(e.feed, []);
|
|
273
|
+
byFeed.get(e.feed).push(e);
|
|
274
|
+
}
|
|
275
|
+
// Slot occupancy: the times at which each in-flight analysis frees up.
|
|
276
|
+
const slotFreeAt = new Array(Math.max(1, cfg.maxInFlight)).fill(0);
|
|
277
|
+
const buffer = [];
|
|
278
|
+
const analyzedEvents = new Map(); // eventId -> analysis land time
|
|
279
|
+
let idleAnalyses = 0;
|
|
280
|
+
let analyses = 0;
|
|
281
|
+
let looks = 0;
|
|
282
|
+
// `heartbeatDue` in MotionGate.evaluate is measured from `lastAnalyzedAtMs`,
|
|
283
|
+
// which `markAnalyzed()` sets only AFTER an inference actually lands — never
|
|
284
|
+
// from the last look. A starved feed therefore keeps qualifying for the
|
|
285
|
+
// heartbeat, which is the behaviour that lets the buffer rescue it.
|
|
286
|
+
const lastAnalyzedAt = new Map();
|
|
287
|
+
// Which events have already presented their CHANGE to the gate. The detector
|
|
288
|
+
// is a frame-to-frame differ: a person who arrives and then stands still
|
|
289
|
+
// produces motion on the look that catches the arrival and `stationary`
|
|
290
|
+
// afterwards. Firing `motion` on every look inside a long event would invent
|
|
291
|
+
// analysis demand the real gate never generates, and would then charge the
|
|
292
|
+
// shortfall to slot starvation.
|
|
293
|
+
const changePresented = new Set();
|
|
294
|
+
const everLooked = new Set();
|
|
295
|
+
const slotStarved = new Set();
|
|
296
|
+
/** Events whose frame was HELD in the candidate buffer at least once. */
|
|
297
|
+
const everBuffered = new Set();
|
|
298
|
+
/** Take the earliest-free slot if one is free at `t`. */
|
|
299
|
+
const acquire = (t) => {
|
|
300
|
+
let best = -1;
|
|
301
|
+
for (let i = 0; i < slotFreeAt.length; i += 1) {
|
|
302
|
+
if (slotFreeAt[i] <= t && (best === -1 || slotFreeAt[i] < slotFreeAt[best]))
|
|
303
|
+
best = i;
|
|
304
|
+
}
|
|
305
|
+
return best;
|
|
306
|
+
};
|
|
307
|
+
/** Run the analysis, booking the slot and recording what it found. */
|
|
308
|
+
const runAnalysis = (slot, t, frame) => {
|
|
309
|
+
slotFreeAt[slot] = t + cfg.analyzeS;
|
|
310
|
+
analyses += 1;
|
|
311
|
+
// `markAnalyzed()` — the single commit point. Only a landed inference
|
|
312
|
+
// resets the heartbeat clock.
|
|
313
|
+
lastAnalyzedAt.set(frame.feed, t);
|
|
314
|
+
if (frame.eventId) {
|
|
315
|
+
if (!analyzedEvents.has(frame.eventId))
|
|
316
|
+
analyzedEvents.set(frame.eventId, t);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
idleAnalyses += 1;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
/** Drain the buffer into any free slot. Called after every tick. */
|
|
323
|
+
const pump = (t) => {
|
|
324
|
+
// Expire first — the real pump does `expire()` before it serves.
|
|
325
|
+
for (let i = buffer.length - 1; i >= 0; i -= 1) {
|
|
326
|
+
if (t - buffer[i].capturedAtS > cfg.bufferTtlS)
|
|
327
|
+
buffer.splice(i, 1);
|
|
328
|
+
}
|
|
329
|
+
let slot = acquire(t);
|
|
330
|
+
while (slot !== -1 && buffer.length > 0) {
|
|
331
|
+
const frame = buffer.shift();
|
|
332
|
+
runAnalysis(slot, t, frame);
|
|
333
|
+
slot = acquire(t);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
// Every look tick across every feed, in time order.
|
|
337
|
+
const ticks = [];
|
|
338
|
+
for (const feed of feeds) {
|
|
339
|
+
const p = phase.get(feed);
|
|
340
|
+
for (let t = p; t < durationS; t += cfg.lookCadenceS)
|
|
341
|
+
ticks.push({ t, feed });
|
|
342
|
+
}
|
|
343
|
+
ticks.sort((a, b) => a.t - b.t || a.feed.localeCompare(b.feed));
|
|
344
|
+
for (const { t, feed } of ticks) {
|
|
345
|
+
pump(t);
|
|
346
|
+
looks += 1;
|
|
347
|
+
const active = (byFeed.get(feed) || []).find((e) => t >= e.startS && t < e.endS);
|
|
348
|
+
if (active)
|
|
349
|
+
everLooked.add(active.id);
|
|
350
|
+
// MotionGate decision precedence, in the shipped order:
|
|
351
|
+
// heartbeatDue -> no_motion -> calibrating -> stationary -> motion.
|
|
352
|
+
const hbLast = lastAnalyzedAt.get(feed);
|
|
353
|
+
const heartbeatDue = hbLast === undefined || (t - hbLast) >= cfg.heartbeatS;
|
|
354
|
+
// `motion` only on the look that catches the CHANGE. A still-scene event
|
|
355
|
+
// never presents one at all and is reachable ONLY by the heartbeat — the
|
|
356
|
+
// leaking-cooler case connectorCadence.ts is written about.
|
|
357
|
+
const motion = Boolean(active && active.producesMotion && !changePresented.has(active.id));
|
|
358
|
+
if (!motion && !heartbeatDue)
|
|
359
|
+
continue; // no_motion / stationary -> dropped
|
|
360
|
+
if (motion && active)
|
|
361
|
+
changePresented.add(active.id);
|
|
362
|
+
const frame = {
|
|
363
|
+
eventId: active ? active.id : null,
|
|
364
|
+
feed,
|
|
365
|
+
capturedAtS: t,
|
|
366
|
+
};
|
|
367
|
+
const slot = acquire(t);
|
|
368
|
+
if (slot !== -1) {
|
|
369
|
+
runAnalysis(slot, t, frame);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
// Denied. `isChangeCandidate` holds a real change candidate; a bare
|
|
373
|
+
// heartbeat on a still scene is NOT a candidate and is dropped here.
|
|
374
|
+
if (active)
|
|
375
|
+
slotStarved.add(active.id);
|
|
376
|
+
if (motion && buffer.length < cfg.bufferMaxFrames) {
|
|
377
|
+
buffer.push(frame);
|
|
378
|
+
if (active)
|
|
379
|
+
everBuffered.add(active.id);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
pump(durationS);
|
|
383
|
+
// Content layer. One draw per caught event, from the same seeded stream, so
|
|
384
|
+
// the whole result is reproducible from `seed` alone.
|
|
385
|
+
const outcomes = events.map((e) => {
|
|
386
|
+
const looked = everLooked.has(e.id);
|
|
387
|
+
const landedAt = analyzedEvents.get(e.id);
|
|
388
|
+
const analyzed = landedAt !== undefined;
|
|
389
|
+
let lostTo = null;
|
|
390
|
+
let caught = false;
|
|
391
|
+
if (!looked)
|
|
392
|
+
lostTo = 'never_looked';
|
|
393
|
+
else if (!analyzed) {
|
|
394
|
+
// Order matters: a frame that was HELD and then aged out is a buffer
|
|
395
|
+
// failure; one that was denied and never held is a slot failure; one
|
|
396
|
+
// that was never denied at all was dropped by the GATE — it was looked
|
|
397
|
+
// at and the gate declined to analyse it, which is the still-scene case
|
|
398
|
+
// and is fixed by the heartbeat, not by anything downstream.
|
|
399
|
+
if (everBuffered.has(e.id))
|
|
400
|
+
lostTo = 'buffer_expired';
|
|
401
|
+
else if (slotStarved.has(e.id))
|
|
402
|
+
lostTo = 'slot_starved';
|
|
403
|
+
else
|
|
404
|
+
lostTo = 'gate_dropped';
|
|
405
|
+
}
|
|
406
|
+
else if (rand() < cfg.fieldAccuracy)
|
|
407
|
+
caught = true;
|
|
408
|
+
else
|
|
409
|
+
lostTo = 'model_wrong';
|
|
410
|
+
return {
|
|
411
|
+
id: e.id,
|
|
412
|
+
shapeId: e.shapeId,
|
|
413
|
+
eventClass: e.eventClass,
|
|
414
|
+
looked,
|
|
415
|
+
analyzed,
|
|
416
|
+
caught,
|
|
417
|
+
lostTo,
|
|
418
|
+
latencyS: analyzed ? landedAt - e.startS : null,
|
|
419
|
+
};
|
|
420
|
+
});
|
|
421
|
+
let falseTriggers = 0;
|
|
422
|
+
for (let i = 0; i < idleAnalyses; i += 1) {
|
|
423
|
+
if (rand() < cfg.falsePositiveRate)
|
|
424
|
+
falseTriggers += 1;
|
|
425
|
+
}
|
|
426
|
+
return { outcomes, idleAnalyses, falseTriggers, analyses, looks };
|
|
427
|
+
}
|
|
428
|
+
function medianOf(values) {
|
|
429
|
+
const clean = values.filter((v) => typeof v === 'number' && Number.isFinite(v));
|
|
430
|
+
if (clean.length === 0)
|
|
431
|
+
return null;
|
|
432
|
+
const s = [...clean].sort((a, b) => a - b);
|
|
433
|
+
const mid = Math.floor(s.length / 2);
|
|
434
|
+
return s.length % 2 === 1 ? s[mid] : (s[mid - 1] + s[mid]) / 2;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Group a replay into one row per shape.
|
|
438
|
+
*
|
|
439
|
+
* The false-trigger rate is charged to every shape that was present, because
|
|
440
|
+
* an idle analysis is not attributable to one shape — it happened when NOTHING
|
|
441
|
+
* was in progress. Reporting it per shape anyway is deliberate: an operator
|
|
442
|
+
* reads one row, and a row that hides the noise is the row that sells a
|
|
443
|
+
* detector nobody can live with.
|
|
444
|
+
*/
|
|
445
|
+
function reportByShape(result) {
|
|
446
|
+
const byShape = new Map();
|
|
447
|
+
for (const o of result.outcomes) {
|
|
448
|
+
if (!byShape.has(o.shapeId))
|
|
449
|
+
byShape.set(o.shapeId, []);
|
|
450
|
+
byShape.get(o.shapeId).push(o);
|
|
451
|
+
}
|
|
452
|
+
const reports = [];
|
|
453
|
+
for (const shape of exports.TEMPORAL_SHAPES) {
|
|
454
|
+
const outs = byShape.get(shape.id);
|
|
455
|
+
if (!outs || outs.length === 0)
|
|
456
|
+
continue;
|
|
457
|
+
const caught = outs.filter((o) => o.caught).length;
|
|
458
|
+
const totalFires = caught + result.falseTriggers;
|
|
459
|
+
reports.push({
|
|
460
|
+
shapeId: shape.id,
|
|
461
|
+
group: shape.group,
|
|
462
|
+
events: outs.length,
|
|
463
|
+
lookRate: outs.filter((o) => o.looked).length / outs.length,
|
|
464
|
+
analyzeRate: outs.filter((o) => o.analyzed).length / outs.length,
|
|
465
|
+
catchRate: caught / outs.length,
|
|
466
|
+
falseTriggerRate: totalFires > 0 ? result.falseTriggers / totalFires : 0,
|
|
467
|
+
medianLatencyS: medianOf(outs.filter((o) => o.caught).map((o) => o.latencyS)),
|
|
468
|
+
lost: {
|
|
469
|
+
never_looked: outs.filter((o) => o.lostTo === 'never_looked').length,
|
|
470
|
+
gate_dropped: outs.filter((o) => o.lostTo === 'gate_dropped').length,
|
|
471
|
+
slot_starved: outs.filter((o) => o.lostTo === 'slot_starved').length,
|
|
472
|
+
buffer_expired: outs.filter((o) => o.lostTo === 'buffer_expired').length,
|
|
473
|
+
model_wrong: outs.filter((o) => o.lostTo === 'model_wrong').length,
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
return reports;
|
|
478
|
+
}
|
|
479
|
+
/** Roll the shape rows up to the four reporting groups. */
|
|
480
|
+
function reportByGroup(reports) {
|
|
481
|
+
const out = [];
|
|
482
|
+
for (const group of exports.SHAPE_GROUPS) {
|
|
483
|
+
const rows = reports.filter((r) => r.group === group);
|
|
484
|
+
if (rows.length === 0)
|
|
485
|
+
continue;
|
|
486
|
+
const events = rows.reduce((a, r) => a + r.events, 0);
|
|
487
|
+
if (events === 0)
|
|
488
|
+
continue;
|
|
489
|
+
out.push({
|
|
490
|
+
group,
|
|
491
|
+
events,
|
|
492
|
+
catchRate: rows.reduce((a, r) => a + r.catchRate * r.events, 0) / events,
|
|
493
|
+
falseTriggerRate: rows.reduce((a, r) => a + r.falseTriggerRate * r.events, 0) / events,
|
|
494
|
+
lookRate: rows.reduce((a, r) => a + r.lookRate * r.events, 0) / events,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
return out;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* The look cadence a shape needs to reach `target`.
|
|
501
|
+
*
|
|
502
|
+
* `min(d/T,1) >= target => T <= d/target`. Reported so a red gate carries
|
|
503
|
+
* the fix rather than only the failure: a 2.2 s event at a 90% target needs a
|
|
504
|
+
* 2.44 s look cadence, which is a real, affordable number (looking costs
|
|
505
|
+
* 3.6 ms) and is 12x finer than the 30 s we ship.
|
|
506
|
+
*/
|
|
507
|
+
function requiredLookCadenceS(medianDurationS, target) {
|
|
508
|
+
if (!Number.isFinite(medianDurationS) || medianDurationS <= 0)
|
|
509
|
+
return null;
|
|
510
|
+
if (!Number.isFinite(target) || target <= 0 || target > 1)
|
|
511
|
+
return null;
|
|
512
|
+
return medianDurationS / target;
|
|
513
|
+
}
|
|
514
|
+
//# sourceMappingURL=sensingCatchRate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensingCatchRate.js","sourceRoot":"","sources":["../src/sensingCatchRate.ts"],"names":[],"mappings":"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"}
|
package/dist/sensingRunMode.d.ts
CHANGED
|
@@ -21,13 +21,23 @@ export interface SensingManagerOpts {
|
|
|
21
21
|
* can hold either a real manager or a test fake.
|
|
22
22
|
*/
|
|
23
23
|
export interface SensingManager {
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* `healthOnly` runs the cameras WITHOUT inference: open, prove video, report
|
|
26
|
+
* camera health, analyze nothing. `auto-sense` runs this while it waits for
|
|
27
|
+
* the on-device model so a connector that cannot sense yet is still visibly
|
|
28
|
+
* ALIVE in the portal — see `AutoSenseSupervisor` and the `healthOnlyMode`
|
|
29
|
+
* docs on `CloudSensingManager`.
|
|
30
|
+
*/
|
|
31
|
+
start(opts?: {
|
|
32
|
+
healthOnly?: boolean;
|
|
33
|
+
}): Promise<void>;
|
|
25
34
|
stop(): Promise<void>;
|
|
26
35
|
/**
|
|
27
36
|
* How many frames the ON-DEVICE runtime has produced a result for so far this
|
|
28
|
-
* run (`start()` resets the count).
|
|
29
|
-
*
|
|
30
|
-
*
|
|
37
|
+
* run (`start()` resets the count). Every analysis is now an on-device one —
|
|
38
|
+
* the connector has no cloud path — but the counter stays distinct from the
|
|
39
|
+
* total because it is the supervisor's proof-of-life and must never be
|
|
40
|
+
* advanceable by anything except a completed local inference.
|
|
31
41
|
*
|
|
32
42
|
* OPTIONAL, and structurally satisfied by `CloudSensingManager` already — no
|
|
33
43
|
* manager code changes to supply it. The auto-sense supervisor reads it for
|
|
@@ -116,13 +126,6 @@ export declare function formatSensingHealth(health: ReturnType<CloudSensingManag
|
|
|
116
126
|
export declare function createTransportFailureReporter(io: SensingIo, now?: () => number): {
|
|
117
127
|
report(name: string, error: Error): boolean;
|
|
118
128
|
};
|
|
119
|
-
/**
|
|
120
|
-
* Build (but do NOT start) the thin cloud-sensing manager: RTSP frame → POST
|
|
121
|
-
* /v2/earner/audience-analyze (cloud VLM does the inference). Returns `null`
|
|
122
|
-
* after logging NO_FEEDS_MESSAGE when no feeds are configured — the caller
|
|
123
|
-
* decides how to surface that (the CLI + the supervisor both exit 1).
|
|
124
|
-
*/
|
|
125
|
-
export declare function buildCloudSensingManager(config: EdgeAgentConfig, io?: SensingIo, opts?: SensingManagerOpts): CloudSensingManager | null;
|
|
126
129
|
/**
|
|
127
130
|
* Build (but do NOT start) the on-device LOCAL-sensing manager: RTSP frame →
|
|
128
131
|
* LOCAL VLM (LiteRT-LM serving Gemma) → POST the STRUCTURED result as
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensingRunMode.d.ts","sourceRoot":"","sources":["../src/sensingRunMode.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,
|
|
1
|
+
{"version":3,"file":"sensingRunMode.d.ts","sourceRoot":"","sources":["../src/sensingRunMode.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAGnB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOhD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC/C,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,CAClB,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,KAAK,KACT,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7B;AA0CD;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,gBAAgB,CAAC,IAAI;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB;;;;;;WAMG;QACH,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KACxC,CAAC;CACH;AAED,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,qEAAqE;AACrE,eAAO,MAAM,SAAS,EAAE,SAIvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAEgD,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,QAAgB,CAAC;AAE5D;;;;;;;;;GASG;AACH,eAAO,MAAM,qCAAqC,QAAiB,CAAC;AAmNpE;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,GAC1D,MAAM,CAsCR;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,SAAS,EACb,GAAG,GAAE,MAAM,MAAiB,GAC3B;IAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAA;CAAE,CA+BjD;AAuGD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,eAAe,EACvB,EAAE,GAAE,SAAqB,EACzB,IAAI,CAAC,EAAE,kBAAkB,GACxB,mBAAmB,GAAG,IAAI,CAoF5B"}
|