@trillboards/edge-sdk 0.2.42 → 0.2.52
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 +76 -0
- package/deploy/docker/connector-entrypoint.sh +1 -1
- package/dist/AudioOnsetDetector.d.ts +211 -0
- package/dist/AudioOnsetDetector.d.ts.map +1 -0
- package/dist/AudioOnsetDetector.js +286 -0
- package/dist/AudioOnsetDetector.js.map +1 -0
- package/dist/CloudSensingManager.d.ts +67 -0
- package/dist/CloudSensingManager.d.ts.map +1 -1
- package/dist/CloudSensingManager.js +185 -17
- package/dist/CloudSensingManager.js.map +1 -1
- package/dist/DurableVlmCandidateSpool.d.ts +99 -0
- package/dist/DurableVlmCandidateSpool.d.ts.map +1 -0
- package/dist/DurableVlmCandidateSpool.js +522 -0
- package/dist/DurableVlmCandidateSpool.js.map +1 -0
- package/dist/EdgeAgent.d.ts.map +1 -1
- package/dist/EdgeAgent.js +20 -2
- package/dist/EdgeAgent.js.map +1 -1
- package/dist/LiteRtVlmProvider.d.ts +66 -1
- package/dist/LiteRtVlmProvider.d.ts.map +1 -1
- package/dist/LiteRtVlmProvider.js +132 -0
- package/dist/LiteRtVlmProvider.js.map +1 -1
- package/dist/SceneChangeDetector.d.ts +62 -6
- package/dist/SceneChangeDetector.d.ts.map +1 -1
- package/dist/SceneChangeDetector.js +61 -5
- package/dist/SceneChangeDetector.js.map +1 -1
- package/dist/VlmAdmissionGate.d.ts +63 -0
- package/dist/VlmAdmissionGate.d.ts.map +1 -1
- package/dist/VlmAdmissionGate.js +64 -0
- package/dist/VlmAdmissionGate.js.map +1 -1
- package/dist/VlmCandidateBuffer.d.ts +17 -0
- package/dist/VlmCandidateBuffer.d.ts.map +1 -1
- package/dist/VlmCandidateBuffer.js +6 -0
- package/dist/VlmCandidateBuffer.js.map +1 -1
- package/dist/attachAudioOnset.d.ts +87 -0
- package/dist/attachAudioOnset.d.ts.map +1 -0
- package/dist/attachAudioOnset.js +87 -0
- package/dist/attachAudioOnset.js.map +1 -0
- package/dist/config.d.ts +83 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/connectorCadence.d.ts +193 -8
- package/dist/connectorCadence.d.ts.map +1 -1
- package/dist/connectorCadence.js +225 -10
- package/dist/connectorCadence.js.map +1 -1
- package/dist/deployedCadence.d.ts +18 -5
- package/dist/deployedCadence.d.ts.map +1 -1
- package/dist/deployedCadence.js +50 -13
- package/dist/deployedCadence.js.map +1 -1
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.js +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/sensingCatchRate.d.ts +105 -3
- package/dist/sensingCatchRate.d.ts.map +1 -1
- package/dist/sensingCatchRate.js +98 -10
- package/dist/sensingCatchRate.js.map +1 -1
- package/dist/sensingRunMode.d.ts.map +1 -1
- package/dist/sensingRunMode.js +100 -4
- package/dist/sensingRunMode.js.map +1 -1
- package/dist/wavEncode.d.ts +29 -0
- package/dist/wavEncode.d.ts.map +1 -0
- package/dist/wavEncode.js +63 -0
- package/dist/wavEncode.js.map +1 -0
- package/package.json +1 -1
package/dist/connectorCadence.js
CHANGED
|
@@ -49,9 +49,18 @@
|
|
|
49
49
|
* is both cheaper and far tighter — 6.0-7.5 s — which is a second,
|
|
50
50
|
* independent reason the two products should not share a cadence.)
|
|
51
51
|
*
|
|
52
|
-
* LOOKING
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* LOOKING costs almost no CPU — 3.6 ms median / 7.1 ms p95 to pull a frame
|
|
53
|
+
* down to ~178x100 grey and run the motion detector, so sixteen
|
|
54
|
+
* feeds looking every 30 s is 0.19% of one core.
|
|
55
|
+
*
|
|
56
|
+
* CORRECTED 2026-08-18: that is the cost AFTER the frame is in
|
|
57
|
+
* hand, and it is NOT the cost of a look. `buildCaptureArgs` spawns
|
|
58
|
+
* one ffmpeg per grab with `-frames:v 1`, so every look also pays a
|
|
59
|
+
* process start, an RTSP handshake and a wait for the next
|
|
60
|
+
* keyframe. Measured through the shipped provider: p50 1 999 ms at
|
|
61
|
+
* a 2 s keyframe interval, 4 005 ms at 4 s. Looking is CHEAP IN CPU
|
|
62
|
+
* and EXPENSIVE IN WALL CLOCK, and it is the wall clock that bounds
|
|
63
|
+
* the cadence — see MEASURED_LOOK_MS and lookIntervalMsForFeedCount.
|
|
55
64
|
*
|
|
56
65
|
* FLOOR on a still scene the motion gate contributes exactly ZERO
|
|
57
66
|
* analyses — verified across byte-identical frames and gaussian
|
|
@@ -74,8 +83,11 @@
|
|
|
74
83
|
* would degrade into reporting empty aisles on time while missing the incident.
|
|
75
84
|
*
|
|
76
85
|
* Two clamps, both from values the system already declares:
|
|
77
|
-
* - never faster than
|
|
78
|
-
*
|
|
86
|
+
* - never faster than MIN_ANALYZE_INTERVAL_MS (30 s). This clamp used to read
|
|
87
|
+
* "never faster than the LOOK interval", which was the same 30 s constant;
|
|
88
|
+
* the two split on 2026-08-18 and this one is the ANALYZE floor. You still
|
|
89
|
+
* cannot analyze more often than you look, but the look cadence is now the
|
|
90
|
+
* faster of the two, so it is no longer what binds here.
|
|
79
91
|
* - never slower than the DOOH default (300 s): this can only make a
|
|
80
92
|
* connector sample MORE often than it does today, never less.
|
|
81
93
|
*
|
|
@@ -95,8 +107,9 @@
|
|
|
95
107
|
* what the operator wants; this says what the machine can deliver.
|
|
96
108
|
*/
|
|
97
109
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
98
|
-
exports.DOOH_PERIODIC_MS = exports.LOOK_INTERVAL_MS = exports.STILL_FLOOR_SLOT_SHARE = exports.MEASURED_LOCAL_ANALYZE_MS = void 0;
|
|
110
|
+
exports.DOOH_PERIODIC_MS = exports.LOOK_INTERVAL_MS = exports.LEGACY_LOOK_INTERVAL_MS = exports.LOOK_CAPTURE_CONCURRENCY = exports.MEASURED_LOOK_MS = exports.MIN_ANALYZE_INTERVAL_MS = exports.STILL_FLOOR_SLOT_SHARE = exports.MEASURED_LOCAL_ANALYZE_MS = void 0;
|
|
99
111
|
exports.periodicIntervalMsForFeedCount = periodicIntervalMsForFeedCount;
|
|
112
|
+
exports.lookIntervalMsForFeedCount = lookIntervalMsForFeedCount;
|
|
100
113
|
exports.stillSceneLoad = stillSceneLoad;
|
|
101
114
|
/**
|
|
102
115
|
* Measured median seconds per on-device analysis, in ms. See the header for the
|
|
@@ -110,10 +123,161 @@ exports.MEASURED_LOCAL_ANALYZE_MS = 7300;
|
|
|
110
123
|
*/
|
|
111
124
|
exports.STILL_FLOOR_SLOT_SHARE = 0.5;
|
|
112
125
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
126
|
+
* ── Two cadences, two different machines ───────────────────────────────────
|
|
127
|
+
*
|
|
128
|
+
* After the 2026-08-18 split, the connector's two cadences are bounded by two
|
|
129
|
+
* DIFFERENT pieces of hardware, and that is why they cannot share a constant:
|
|
130
|
+
*
|
|
131
|
+
* ANALYZE is bounded by the BOX. `MEASURED_LOCAL_ANALYZE_MS` is one machine's
|
|
132
|
+
* per-frame inference cost, and it varies by ~7x across the machines
|
|
133
|
+
* this ships on. `periodicIntervalMsForFeedCount` derives the
|
|
134
|
+
* still-scene heartbeat from it, so a slower box automatically gets a
|
|
135
|
+
* slower heartbeat with no other change.
|
|
136
|
+
*
|
|
137
|
+
* LOOK is bounded by the RECORDER. `MEASURED_LOOK_MS` is an ffmpeg spawn
|
|
138
|
+
* plus an RTSP handshake plus a wait for the camera's next keyframe;
|
|
139
|
+
* none of that is inference and none of it moves when the box gets
|
|
140
|
+
* faster. `lookIntervalMsForFeedCount` derives it from the recorder's
|
|
141
|
+
* capture concurrency.
|
|
142
|
+
*
|
|
143
|
+
* So the look cadence below is NOT a function of the box, and does not need a
|
|
144
|
+
* hardware caveat. Re-measure it when the CAPTURE PATH changes — a persistent
|
|
145
|
+
* RTSP session instead of one process per grab would move it by an order of
|
|
146
|
+
* magnitude, and is the only thing that would.
|
|
147
|
+
*/
|
|
148
|
+
/**
|
|
149
|
+
* The fastest a connector may ANALYZE one feed, in ms.
|
|
150
|
+
*
|
|
151
|
+
* SEPARATE FROM `LOOK_INTERVAL_MS` since 2026-08-18, and the separation is the
|
|
152
|
+
* whole point. Both were 30 000 and one constant did both jobs, so nothing
|
|
153
|
+
* anywhere distinguished "how often do we look at the scene" from "how often
|
|
154
|
+
* may we spend an inference on it" — and the look cadence could not be lowered
|
|
155
|
+
* without dragging the analyze floor down with it and multiplying VLM volume on
|
|
156
|
+
* a 493/hour ceiling.
|
|
157
|
+
*
|
|
158
|
+
* 30 s is not a fresh judgement; it is the value the system already declares in
|
|
159
|
+
* two independent places, now named once:
|
|
160
|
+
* - `faceTriggeredIntervalMs` (`DEFAULT_FACE_MS`, 30 s) is the default for
|
|
161
|
+
* `MotionGate.minAnalyzeIntervalMs` — the floor between two motion-driven
|
|
162
|
+
* analyses of one feed.
|
|
163
|
+
* - `vision_pacing_config.daily_limit_per_screen` is 2 880 for the connector
|
|
164
|
+
* fleet, i.e. 86 400 / 2 880 = one analysis per 30 s, enforced server-side.
|
|
165
|
+
*
|
|
166
|
+
* So a connector that analyzed faster than this would be throttled by the
|
|
167
|
+
* server anyway. Lowering the LOOK cadence must not move this number, and the
|
|
168
|
+
* `analyzeFloorUnmovedByLookCadence` test asserts exactly that.
|
|
169
|
+
*/
|
|
170
|
+
exports.MIN_ANALYZE_INTERVAL_MS = 30000;
|
|
171
|
+
/**
|
|
172
|
+
* Measured wall-clock cost of ONE LOOK, in ms — a real RTSP grab, not the
|
|
173
|
+
* decode-and-detect that follows it.
|
|
174
|
+
*
|
|
175
|
+
* The cascade budget above quotes 3.6 ms for a look. That is the cost AFTER the
|
|
176
|
+
* frame is in hand: pull it down to ~178x100 grey and run the detector. Getting
|
|
177
|
+
* it in hand is a different order of magnitude, because `buildCaptureArgs`
|
|
178
|
+
* spawns ONE ffmpeg per grab with `-frames:v 1` and no `-ss`, so every look pays
|
|
179
|
+
* a process start, a full RTSP DESCRIBE/SETUP/PLAY handshake, and a wait for the
|
|
180
|
+
* next keyframe before anything can be decoded.
|
|
181
|
+
*
|
|
182
|
+
* MEASURED 2026-08-18 through the shipped `RTSPCameraProvider` against mediamtx
|
|
183
|
+
* re-streaming a real CCTV clip at the documented degraded profile
|
|
184
|
+
* (640x360 / 399 kbps), one feed, no contention, p50 of 8 grabs:
|
|
185
|
+
*
|
|
186
|
+
* keyframe interval p50 grab
|
|
187
|
+
* 1 s 1 986 ms
|
|
188
|
+
* 2 s 1 999 - 2 025 ms
|
|
189
|
+
* 4 s 4 005 ms
|
|
190
|
+
*
|
|
191
|
+
* So the cost is `max(~2 s, keyframe interval)`. The floor is the RTSP SESSION,
|
|
192
|
+
* not the process: the same ffmpeg args against a local file complete in
|
|
193
|
+
* 20-30 ms, so ~99% of a look is DESCRIBE/SETUP/PLAY plus the wait for an IDR.
|
|
194
|
+
* That is a property of pulling one frame per session, not of the machine — a
|
|
195
|
+
* faster box does not move it, and a persistent session would remove almost all
|
|
196
|
+
* of it. 2 s is taken as the floor
|
|
197
|
+
* because it is the fastest observed and because a 1-2 s keyframe interval is
|
|
198
|
+
* the common CCTV default.
|
|
199
|
+
*
|
|
200
|
+
* This is why `lookIntervalMsForFeedCount` exists. Asking for a look cadence
|
|
201
|
+
* finer than the capture path can deliver does not produce more looks — the
|
|
202
|
+
* grabs queue on `CaptureAdmission` and `getSensingHealth()` reports a cadence
|
|
203
|
+
* the connector is not running.
|
|
115
204
|
*/
|
|
116
|
-
exports.
|
|
205
|
+
exports.MEASURED_LOOK_MS = 2000;
|
|
206
|
+
/**
|
|
207
|
+
* Concurrent RTSP grabs one physical recorder will take —
|
|
208
|
+
* `DEFAULT_MAX_CONCURRENT_CAPTURES_PER_SOURCE` in `RTSPCameraProvider`, which
|
|
209
|
+
* keys its admission gate on `host:port` because 32 NVR channels are usually
|
|
210
|
+
* one recorder with one session budget.
|
|
211
|
+
*
|
|
212
|
+
* Restated here rather than imported because `edge-sdk` must not depend on a
|
|
213
|
+
* platform package, and asserted against the real constant by
|
|
214
|
+
* `connectorCadence.test.ts` so the two cannot drift.
|
|
215
|
+
*
|
|
216
|
+
* Raising it does NOT buy look throughput: measured at 16 feeds on one recorder,
|
|
217
|
+
* 2 concurrent and 8 concurrent both sustained 1.00 looks/s (the per-grab p50
|
|
218
|
+
* simply rose from 9 962 ms to 9 996 ms). The recorder, not the gate, is the
|
|
219
|
+
* bound.
|
|
220
|
+
*/
|
|
221
|
+
exports.LOOK_CAPTURE_CONCURRENCY = 2;
|
|
222
|
+
/**
|
|
223
|
+
* The look cadence this connector ran until 2026-08-18, kept ONLY as the slow
|
|
224
|
+
* clamp on `lookIntervalMsForFeedCount`.
|
|
225
|
+
*
|
|
226
|
+
* It is numerically equal to `MIN_ANALYZE_INTERVAL_MS` and that is a
|
|
227
|
+
* coincidence of history, not a relationship: they were one constant, and the
|
|
228
|
+
* whole point of the split is that they are free to move independently. Using
|
|
229
|
+
* the analyze floor here would re-create exactly the conflation this change
|
|
230
|
+
* removes — a future PR that lowers the analyze floor would silently speed up
|
|
231
|
+
* the slowest look cadence with it.
|
|
232
|
+
*
|
|
233
|
+
* Its only job is a guarantee: deriving a look cadence can make a connector look
|
|
234
|
+
* MORE often than it used to, never less. A 32-feed host cannot sustain even
|
|
235
|
+
* this (32 feeds want 1.07 looks/s against a measured 1.00), so past ~30 feeds
|
|
236
|
+
* the derivation is pinned here and the grabs queue on `CaptureAdmission` — a
|
|
237
|
+
* pre-existing capacity fact about one recorder, not something a faster look
|
|
238
|
+
* cadence introduces.
|
|
239
|
+
*/
|
|
240
|
+
exports.LEGACY_LOOK_INTERVAL_MS = 30000;
|
|
241
|
+
/**
|
|
242
|
+
* The connector's TARGET look cadence, in ms — how often the motion gate gets a
|
|
243
|
+
* chance to see anything at all.
|
|
244
|
+
*
|
|
245
|
+
* DERIVED FROM THE CATCH-RATE EVAL, not chosen. An event is catchable only if a
|
|
246
|
+
* LOOK lands inside it, so for an event of duration `d` against an
|
|
247
|
+
* event-uncorrelated look cadence `T` the ceiling on catch rate is
|
|
248
|
+
* `E[min(d/T,1)]`. Evaluated over the whole 75,657-event corpus
|
|
249
|
+
* (`eval/sensing-event-corpus.json`), event-weighted per reporting group and
|
|
250
|
+
* UNCAPPED:
|
|
251
|
+
*
|
|
252
|
+
* T Instant Brief Sustained State
|
|
253
|
+
* 30 s 8.4% 18.6% 100% 100%
|
|
254
|
+
* 5 s 50.2% 55.1% 100% 100%
|
|
255
|
+
* 2.44 s 89.1% 71.2% 100% 100%
|
|
256
|
+
* 2 s 95.5% 75.2% 100% 100%
|
|
257
|
+
* 1 s 100.0% 86.6% 100% 100%
|
|
258
|
+
* 0.75 s 100.0% 90.1% 100% 100%
|
|
259
|
+
*
|
|
260
|
+
* Two things fall out of that table and both are load bearing:
|
|
261
|
+
*
|
|
262
|
+
* - The Instant group — "alert me if the door opens after hours", a 2.2 s
|
|
263
|
+
* median event — clears the 90% target at 2.4 s and is at 8.4% today. This
|
|
264
|
+
* is the promise the 30 s cadence was silently failing.
|
|
265
|
+
*
|
|
266
|
+
* - The Brief group does NOT reach 90% until 0.75 s, and 0.75 s is well below
|
|
267
|
+
* the measured cost of a single grab (`MEASURED_LOOK_MS`). So 90% on every
|
|
268
|
+
* shape is NOT reachable by look cadence on the current capture
|
|
269
|
+
* architecture, and this constant does not pretend otherwise. Closing that
|
|
270
|
+
* gap needs a persistent RTSP session — one long-lived ffmpeg per feed
|
|
271
|
+
* instead of one per grab — which is an architecture change, not a number.
|
|
272
|
+
*
|
|
273
|
+
* 2 000 ms is therefore the fastest cadence that is BOTH an eval output and
|
|
274
|
+
* physically deliverable: it is the measured single-grab floor, and at it the
|
|
275
|
+
* Instant group clears the target. Do not lower it without first lowering
|
|
276
|
+
* `MEASURED_LOOK_MS`, and do not raise it without re-running the replay — the
|
|
277
|
+
* `sensing-catch-rate` guard re-reads this constant and fails if it drifts from
|
|
278
|
+
* the cadence the corpus was measured at.
|
|
279
|
+
*/
|
|
280
|
+
exports.LOOK_INTERVAL_MS = 2000;
|
|
117
281
|
/** The DOOH audience default (`DEFAULT_PERIODIC_MS`). The slow end of the clamp. */
|
|
118
282
|
exports.DOOH_PERIODIC_MS = 300000;
|
|
119
283
|
/**
|
|
@@ -131,7 +295,58 @@ function periodicIntervalMsForFeedCount(feedCount) {
|
|
|
131
295
|
if (!Number.isFinite(n) || n < 1)
|
|
132
296
|
return null;
|
|
133
297
|
const required = Math.ceil((Math.trunc(n) * exports.MEASURED_LOCAL_ANALYZE_MS) / exports.STILL_FLOOR_SLOT_SHARE);
|
|
134
|
-
|
|
298
|
+
// MEASURED 2026-08-18, and left as it is ON PURPOSE — see below.
|
|
299
|
+
//
|
|
300
|
+
// The `DOOH_PERIODIC_MS` cap stops honouring `STILL_FLOOR_SLOT_SHARE` past
|
|
301
|
+
// ~20 feeds. `required` crosses 300 s at 21 feeds, and from there the clamp
|
|
302
|
+
// returns a heartbeat FASTER than the budget asks for, so the still-scene
|
|
303
|
+
// floor takes more than its declared half of the single slot and keeps
|
|
304
|
+
// taking: 51.1% at 21 feeds, 77.9% at 32 (replay-catch-rate.mjs
|
|
305
|
+
// --sweep-admission, .github/contracts/sensing-admission-sweep.json).
|
|
306
|
+
//
|
|
307
|
+
// Honouring the share above 20 feeds would mean returning 400 s, 600 s, and
|
|
308
|
+
// so on — which is strictly WORSE for the thing the heartbeat exists to do.
|
|
309
|
+
// `absence` catch rate is E[min(d/H,1)]: at 300 s it is 66.3%, and a slower
|
|
310
|
+
// heartbeat drives it down, on the exact class whose whole point is placing a
|
|
311
|
+
// hazard against a 111-second constructive-notice line. So the clamp is not a
|
|
312
|
+
// bug to fix here; it is the honest edge of what ONE 7.30 s slot can serve,
|
|
313
|
+
// and the fix is a second connector host, which `getSensingHealth()` already
|
|
314
|
+
// reports enough to see. Changing this constant would trade a measurable
|
|
315
|
+
// alert-path regression for a cadence number that reads tidier.
|
|
316
|
+
// Floored at the ANALYZE floor, never at the LOOK cadence. Those were the
|
|
317
|
+
// same constant until 2026-08-18; clamping this at the look cadence now would
|
|
318
|
+
// let a faster look cadence pull the still-scene heartbeat down with it and
|
|
319
|
+
// double the analyses a 1-feed connector runs, which is the exact failure the
|
|
320
|
+
// look/analyze split exists to prevent.
|
|
321
|
+
return Math.min(exports.DOOH_PERIODIC_MS, Math.max(exports.MIN_ANALYZE_INTERVAL_MS, required));
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* The fastest look cadence a connector running `feedCount` feeds against ONE
|
|
325
|
+
* recorder can actually SUSTAIN, in ms.
|
|
326
|
+
*
|
|
327
|
+
* Same shape as `periodicIntervalMsForFeedCount` and for the same reason: a
|
|
328
|
+
* cadence is only real if the machine can deliver it. That function divides one
|
|
329
|
+
* inference slot among N feeds; this one divides one recorder's capture
|
|
330
|
+
* capacity among N feeds.
|
|
331
|
+
*
|
|
332
|
+
* N feeds x (1 look / T) <= LOOK_CAPTURE_CONCURRENCY / MEASURED_LOOK_MS
|
|
333
|
+
* T >= N x MEASURED_LOOK_MS / LOOK_CAPTURE_CONCURRENCY
|
|
334
|
+
*
|
|
335
|
+
* Measured against that formula at 16 feeds on one recorder, GOP 2 s: predicted
|
|
336
|
+
* 16.0 s/feed, observed 16.0 s/feed.
|
|
337
|
+
*
|
|
338
|
+
* Never faster than `LOOK_INTERVAL_MS` (the eval target — looking finer than
|
|
339
|
+
* that buys nothing the corpus can see) and never slower than
|
|
340
|
+
* `LEGACY_LOOK_INTERVAL_MS`, so this can only make a connector look MORE often
|
|
341
|
+
* than it did, never less. Returns `null` on an uncountable feed count so a caller can
|
|
342
|
+
* omit the key rather than derive a cadence from nothing.
|
|
343
|
+
*/
|
|
344
|
+
function lookIntervalMsForFeedCount(feedCount) {
|
|
345
|
+
const n = Number(feedCount);
|
|
346
|
+
if (!Number.isFinite(n) || n < 1)
|
|
347
|
+
return null;
|
|
348
|
+
const sustainable = Math.ceil((Math.trunc(n) * exports.MEASURED_LOOK_MS) / exports.LOOK_CAPTURE_CONCURRENCY);
|
|
349
|
+
return Math.min(exports.LEGACY_LOOK_INTERVAL_MS, Math.max(exports.LOOK_INTERVAL_MS, sustainable));
|
|
135
350
|
}
|
|
136
351
|
/**
|
|
137
352
|
* The still-scene analyses/hour a whole connector demands at a heartbeat, and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectorCadence.js","sourceRoot":"","sources":["../src/connectorCadence.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"connectorCadence.js","sourceRoot":"","sources":["../src/connectorCadence.ts"],"names":[],"mappings":"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"}
|
|
@@ -93,12 +93,24 @@ export declare const MAX_CADENCE_MS: number;
|
|
|
93
93
|
export type CadenceReason =
|
|
94
94
|
/** No deployed cadence to honour — the caller keeps exactly what it had. */
|
|
95
95
|
'no_request'
|
|
96
|
+
/**
|
|
97
|
+
* The profile asked for nothing, so the cadence this machine can AFFORD is
|
|
98
|
+
* used instead of whatever default the manager was constructed with.
|
|
99
|
+
*/
|
|
100
|
+
| 'derived_default'
|
|
96
101
|
/** The operator's request was affordable and is being run verbatim. */
|
|
97
102
|
| 'operator_request'
|
|
98
103
|
/** Slowed to fit the single local inference slot. */
|
|
99
104
|
| 'local_inference_budget'
|
|
100
|
-
/**
|
|
101
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Faster than the connector may ANALYZE one feed.
|
|
107
|
+
*
|
|
108
|
+
* Named `look_interval` until 2026-08-18, when the look cadence and the
|
|
109
|
+
* analyze floor stopped being the same 30 000 ms constant. The old name now
|
|
110
|
+
* describes the wrong quantity: the connector looks every 2 s and this clamp
|
|
111
|
+
* is about the 30 s floor between two inferences.
|
|
112
|
+
*/
|
|
113
|
+
| 'analyze_floor'
|
|
102
114
|
/** SPED UP to `MAX_CADENCE_MS`: the request was slower than a capture loop can express. */
|
|
103
115
|
| 'cadence_ceiling';
|
|
104
116
|
export interface DeployedCadence {
|
|
@@ -117,9 +129,10 @@ export interface DeployedCadence {
|
|
|
117
129
|
/**
|
|
118
130
|
* Reconcile a deployed cadence with what this mode can afford.
|
|
119
131
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
132
|
+
* When the profile requested nothing, returns the cadence this machine can
|
|
133
|
+
* AFFORD (`reason: 'derived_default'`) rather than null — see the branch for
|
|
134
|
+
* the measurement. A bare null from `deployedCadenceSource` still means "nobody
|
|
135
|
+
* answered", and that still leaves a running connector alone.
|
|
123
136
|
*/
|
|
124
137
|
export declare function resolveDeployedCadence(input: {
|
|
125
138
|
requestedMs: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployedCadence.d.ts","sourceRoot":"","sources":["../src/deployedCadence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAQH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,cAAc,QAAmB,CAAC;AAE/C,MAAM,MAAM,aAAa;AACvB,4EAA4E;AAC1E,YAAY;AACd,uEAAuE;GACrE,kBAAkB;AACpB,qDAAqD;GACnD,wBAAwB;AAC1B
|
|
1
|
+
{"version":3,"file":"deployedCadence.d.ts","sourceRoot":"","sources":["../src/deployedCadence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAQH;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,cAAc,QAAmB,CAAC;AAE/C,MAAM,MAAM,aAAa;AACvB,4EAA4E;AAC1E,YAAY;AACd;;;GAGG;GACD,iBAAiB;AACnB,uEAAuE;GACrE,kBAAkB;AACpB,qDAAqD;GACnD,wBAAwB;AAC1B;;;;;;;GAOG;GACD,eAAe;AACjB,2FAA2F;GACzF,iBAAiB,CAAC;AAEtB,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mFAAmF;IACnF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AASD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,eAAe,CAkFlB"}
|
package/dist/deployedCadence.js
CHANGED
|
@@ -98,9 +98,10 @@ function normalizeRequest(value) {
|
|
|
98
98
|
/**
|
|
99
99
|
* Reconcile a deployed cadence with what this mode can afford.
|
|
100
100
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
101
|
+
* When the profile requested nothing, returns the cadence this machine can
|
|
102
|
+
* AFFORD (`reason: 'derived_default'`) rather than null — see the branch for
|
|
103
|
+
* the measurement. A bare null from `deployedCadenceSource` still means "nobody
|
|
104
|
+
* answered", and that still leaves a running connector alone.
|
|
104
105
|
*/
|
|
105
106
|
function resolveDeployedCadence(input) {
|
|
106
107
|
const requestedMs = normalizeRequest(input.requestedMs);
|
|
@@ -109,20 +110,56 @@ function resolveDeployedCadence(input) {
|
|
|
109
110
|
// connector with no countable feeds gets the DOOH default rather than a
|
|
110
111
|
// cadence derived from nothing.
|
|
111
112
|
const floorMs = (0, connectorCadence_1.periodicIntervalMsForFeedCount)(input.feedCount) ?? connectorCadence_1.DOOH_PERIODIC_MS;
|
|
112
|
-
// A cadence finer than the
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
|
|
113
|
+
// A cadence finer than the connector may ANALYZE is not deliverable, so it is
|
|
114
|
+
// a floor in every case. This read `LOOK_INTERVAL_MS` until 2026-08-18, when
|
|
115
|
+
// the two constants split: both were 30 000 ms, so the substitution changes no
|
|
116
|
+
// value today — but the look cadence is now 2 000 ms, and leaving this pointed
|
|
117
|
+
// at it would let a 5 s profile row land a 5 s heartbeat and multiply the
|
|
118
|
+
// still-scene analyses of every connector in the fleet.
|
|
119
|
+
//
|
|
120
|
+
// The ceiling wins over the floor: honouring a floor slower than a whole day
|
|
121
|
+
// would hand a capture loop a delay it cannot express (see MAX_CADENCE_MS) —
|
|
122
|
+
// the one clamp that must never be negotiable.
|
|
123
|
+
const effectiveFloor = Math.min(exports.MAX_CADENCE_MS, Math.max(floorMs, connectorCadence_1.MIN_ANALYZE_INTERVAL_MS));
|
|
118
124
|
if (requestedMs === null) {
|
|
125
|
+
// The profile answered and asked for nothing. Fall back to the cadence this
|
|
126
|
+
// machine can afford, NOT to whatever the manager happened to be built with.
|
|
127
|
+
//
|
|
128
|
+
// WHY THIS CHANGED (2026-08-18). `CloudSensingManager`'s default is
|
|
129
|
+
// `DEFAULT_PERIODIC_MS` = 300 s, and that number was chosen for the DOOH
|
|
130
|
+
// audience product, where five-minute granularity is fine because the
|
|
131
|
+
// question is "who saw this ad". A CCTV connector inheriting it is the
|
|
132
|
+
// still-scene reporting floor for hazards, and 300 s cannot place a hazard
|
|
133
|
+
// on either side of the 111-second constructive-notice line the legal
|
|
134
|
+
// argument turns on.
|
|
135
|
+
//
|
|
136
|
+
// Measured, at 8 feeds over 16 seeds
|
|
137
|
+
// (.github/contracts/sensing-admission-sweep.json): the `absence` shape
|
|
138
|
+
// catches **66.3%** at 300 s and **92.3%** (worst seed 89.8%) at the
|
|
139
|
+
// derived 116.8 s, against a 90% target. The cost is the still-scene floor
|
|
140
|
+
// going from 96 to 240 analyses/hour against the machine's 493/hour
|
|
141
|
+
// ceiling — 19.5% to 48.7% of the single slot, still inside the 50%
|
|
142
|
+
// `STILL_FLOOR_SLOT_SHARE` that connectorCadence.ts already declares for
|
|
143
|
+
// it. Nothing else moves: the admission-layer false-trigger rate is flat at
|
|
144
|
+
// ~52% across the whole sweep, so this buys catch rate at constant
|
|
145
|
+
// admission waste rather than by admitting more indiscriminately.
|
|
146
|
+
//
|
|
147
|
+
// `intervalMs` is no longer null here, so a caller that previously left its
|
|
148
|
+
// cadence alone now adopts the derived one. The DISTINCTION this preserves
|
|
149
|
+
// is the one that matters: `deployedCadenceSource` still returns a bare
|
|
150
|
+
// `null` when NOBODY answered (API down/unreachable), and that path is
|
|
151
|
+
// untouched — an unreachable server must never retune a running connector.
|
|
152
|
+
// This branch is only "answered, asked for nothing".
|
|
153
|
+
//
|
|
154
|
+
// Connector-only by construction: `SensingRunModeName` is `'local'`, so
|
|
155
|
+
// nothing DOOH reaches this resolver.
|
|
119
156
|
return {
|
|
120
|
-
intervalMs:
|
|
157
|
+
intervalMs: effectiveFloor,
|
|
121
158
|
requestedMs: null,
|
|
122
159
|
floorMs: effectiveFloor,
|
|
123
160
|
ceilingMs: exports.MAX_CADENCE_MS,
|
|
124
161
|
clamped: false,
|
|
125
|
-
reason: '
|
|
162
|
+
reason: 'derived_default',
|
|
126
163
|
};
|
|
127
164
|
}
|
|
128
165
|
const intervalMs = Math.min(exports.MAX_CADENCE_MS, Math.max(requestedMs, effectiveFloor));
|
|
@@ -132,8 +169,8 @@ function resolveDeployedCadence(input) {
|
|
|
132
169
|
reason = 'cadence_ceiling';
|
|
133
170
|
}
|
|
134
171
|
else if (clamped) {
|
|
135
|
-
if (effectiveFloor === connectorCadence_1.
|
|
136
|
-
reason = '
|
|
172
|
+
if (effectiveFloor === connectorCadence_1.MIN_ANALYZE_INTERVAL_MS && floorMs <= connectorCadence_1.MIN_ANALYZE_INTERVAL_MS)
|
|
173
|
+
reason = 'analyze_floor';
|
|
137
174
|
else
|
|
138
175
|
reason = 'local_inference_budget';
|
|
139
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployedCadence.js","sourceRoot":"","sources":["../src/deployedCadence.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;;;
|
|
1
|
+
{"version":3,"file":"deployedCadence.js","sourceRoot":"","sources":["../src/deployedCadence.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;;;AA+FH,wDAsFC;AAnLD,yDAI4B;AAU5B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAwC/C,8EAA8E;AAC9E,SAAS,gBAAgB,CAAC,KAAc;IACtC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CAAC,KAItC;IACC,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAExD,sEAAsE;IACtE,0EAA0E;IAC1E,wEAAwE;IACxE,gCAAgC;IAChC,MAAM,OAAO,GAAG,IAAA,iDAA8B,EAAC,KAAK,CAAC,SAAS,CAAC,IAAI,mCAAgB,CAAC;IAEpF,8EAA8E;IAC9E,6EAA6E;IAC7E,+EAA+E;IAC/E,+EAA+E;IAC/E,0EAA0E;IAC1E,wDAAwD;IACxD,EAAE;IACF,6EAA6E;IAC7E,6EAA6E;IAC7E,+CAA+C;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAc,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,0CAAuB,CAAC,CAAC,CAAC;IAE5F,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,4EAA4E;QAC5E,6EAA6E;QAC7E,EAAE;QACF,oEAAoE;QACpE,yEAAyE;QACzE,sEAAsE;QACtE,uEAAuE;QACvE,2EAA2E;QAC3E,sEAAsE;QACtE,qBAAqB;QACrB,EAAE;QACF,qCAAqC;QACrC,wEAAwE;QACxE,qEAAqE;QACrE,2EAA2E;QAC3E,oEAAoE;QACpE,oEAAoE;QACpE,yEAAyE;QACzE,4EAA4E;QAC5E,mEAAmE;QACnE,kEAAkE;QAClE,EAAE;QACF,4EAA4E;QAC5E,2EAA2E;QAC3E,wEAAwE;QACxE,uEAAuE;QACvE,2EAA2E;QAC3E,qDAAqD;QACrD,EAAE;QACF,wEAAwE;QACxE,sCAAsC;QACtC,OAAO;YACL,UAAU,EAAE,cAAc;YAC1B,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,sBAAc;YACzB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,iBAAiB;SAC1B,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAc,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IACnF,MAAM,OAAO,GAAG,UAAU,KAAK,WAAW,CAAC;IAE3C,IAAI,MAAM,GAAkB,kBAAkB,CAAC;IAC/C,IAAI,UAAU,GAAG,WAAW,EAAE,CAAC;QAC7B,MAAM,GAAG,iBAAiB,CAAC;IAC7B,CAAC;SAAM,IAAI,OAAO,EAAE,CAAC;QACnB,IAAI,cAAc,KAAK,0CAAuB,IAAI,OAAO,IAAI,0CAAuB;YAAE,MAAM,GAAG,eAAe,CAAC;;YAC1G,MAAM,GAAG,wBAAwB,CAAC;IACzC,CAAC;IAED,OAAO;QACL,UAAU;QACV,WAAW;QACX,OAAO,EAAE,cAAc;QACvB,SAAS,EAAE,sBAAc;QACzB,OAAO;QACP,MAAM;KACP,CAAC;AACJ,CAAC"}
|
package/dist/diagnose.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export interface DiagnosticReport {
|
|
|
31
31
|
skipped: number;
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
|
-
declare const SDK_VERSION = "0.2.
|
|
34
|
+
declare const SDK_VERSION = "0.2.52";
|
|
35
35
|
declare function checkNodeVersion(): CheckResult;
|
|
36
36
|
declare function checkPlatform(): CheckResult;
|
|
37
37
|
declare function checkMemory(): CheckResult;
|
package/dist/diagnose.js
CHANGED
|
@@ -63,7 +63,7 @@ const localNetworkAccess_1 = require("./localNetworkAccess");
|
|
|
63
63
|
// ---------------------------------------------------------------------------
|
|
64
64
|
// SDK version — mirrors package.json; kept in sync by CI
|
|
65
65
|
// ---------------------------------------------------------------------------
|
|
66
|
-
const SDK_VERSION = '0.2.
|
|
66
|
+
const SDK_VERSION = '0.2.52';
|
|
67
67
|
exports._SDK_VERSION = SDK_VERSION;
|
|
68
68
|
// ---------------------------------------------------------------------------
|
|
69
69
|
// ANSI helpers (no external deps)
|
package/dist/index.d.ts
CHANGED
|
@@ -25,9 +25,16 @@ export type { CloudSensingManagerOptions, SensingLoopDeps, ResolvedFeed, } from
|
|
|
25
25
|
export { VlmAdmissionGate } from './VlmAdmissionGate';
|
|
26
26
|
export type { VlmAdmissionGateOptions, VlmAdmissionStats, VlmAdmissionTicket, } from './VlmAdmissionGate';
|
|
27
27
|
export { VlmCandidateBuffer, DEFAULT_CANDIDATE_TTL_MS } from './VlmCandidateBuffer';
|
|
28
|
+
export { DurableVlmCandidateSpool } from './DurableVlmCandidateSpool';
|
|
29
|
+
export type { DurableVlmCandidateSpoolOptions, DurableVlmCandidateSpoolStats, } from './DurableVlmCandidateSpool';
|
|
28
30
|
export type { VlmCandidate, VlmCandidateBufferOptions, VlmCandidateBufferStats, VlmCandidateFeedStats, VlmCandidateOfferResult, } from './VlmCandidateBuffer';
|
|
29
31
|
export { MotionGate, SceneChangeDetector, isChangeCandidate, decodeGreyFrame, downscaleRgbaToGrey, motionSignature, } from './SceneChangeDetector';
|
|
30
32
|
export type { GreyFrame, MotionBox, MotionDetectResult, MotionGateOptions, MotionGateReason, MotionGateResult, MotionGateStats, SceneChangeDetectorOptions, } from './SceneChangeDetector';
|
|
33
|
+
export { AudioOnsetDetector, rmsDbfs, SILENCE_DBFS } from './AudioOnsetDetector';
|
|
34
|
+
export type { AudioOnsetDetectorOptions, AudioOnsetEvent, AudioOnsetStats, } from './AudioOnsetDetector';
|
|
35
|
+
export { attachAudioOnset } from './attachAudioOnset';
|
|
36
|
+
export type { AudioSensingOptions, AudioOnsetAttachment, AudioOnsetTransport, } from './attachAudioOnset';
|
|
37
|
+
export { encodeWav16, takeMostRecentSeconds, GEMMA_AUDIO_SAMPLE_RATE, GEMMA_AUDIO_MAX_SECONDS, } from './wavEncode';
|
|
31
38
|
export { SharedFrameSource, CropViewProvider } from './MosaicSource';
|
|
32
39
|
export type { CropViewProviderOptions } from './MosaicSource';
|
|
33
40
|
export type { AudienceMetricsPayload, DetectedFace, EdgeQualityReport, VASResult, DeviceCapabilityMatrix, PlatformAdapter, CameraProvider, AudioProvider, EdgeSDKConfig, } from '@trillboards/edge-core';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// Install: npm install @trillboards/edge-sdk
|
|
4
4
|
// Run: npx trillboards-edge start --config trillboards.config.json
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.attachAudioOnset = exports.SILENCE_DBFS = exports.rmsDbfs = exports.AudioOnsetDetector = exports.motionSignature = exports.downscaleRgbaToGrey = exports.decodeGreyFrame = exports.isChangeCandidate = exports.SceneChangeDetector = exports.MotionGate = exports.DurableVlmCandidateSpool = exports.DEFAULT_CANDIDATE_TTL_MS = exports.VlmCandidateBuffer = exports.VlmAdmissionGate = exports.shouldAttemptRecorderAddressRecovery = exports.rewriteStreamHost = exports.normalizeMacAddress = exports.lookupMacAddress = exports.RecorderAddressRecovery = exports.resolveFeeds = exports.classifyRtspFailureClass = exports.buildTiledCameras = exports.buildSensingLoops = exports.CloudSensingManager = exports.defaultHttpPoster = exports.AudienceAnalyzeClient = exports.LOCAL_NETWORK_DENIED_SUMMARY = exports.LOCAL_NETWORK_DENIED_SUGGESTION = exports.decideLocalNetworkVerdict = exports.probeLocalNetworkAccess = exports.describeProxy = exports.resolveProxyForUrl = exports.describeTrustAnchors = exports.resolveTrustAnchors = exports.isTrustFailure = exports.formatTransportFailure = exports.classifyTransportError = exports.TransportFailure = exports.EnterpriseHttpsAgent = exports.resetEnterpriseNetworkCaches = exports.diagnoseTransportError = exports.getEnterpriseAgent = exports.describeNetworkPosture = exports.installEnterpriseNetworking = exports.runDiagnose = exports.runInit = exports.CommandRouter = exports.resolveConfig = exports.loadConfig = exports.EdgeAgent = void 0;
|
|
7
|
+
exports.CropViewProvider = exports.SharedFrameSource = exports.GEMMA_AUDIO_MAX_SECONDS = exports.GEMMA_AUDIO_SAMPLE_RATE = exports.takeMostRecentSeconds = exports.encodeWav16 = void 0;
|
|
7
8
|
var EdgeAgent_1 = require("./EdgeAgent");
|
|
8
9
|
Object.defineProperty(exports, "EdgeAgent", { enumerable: true, get: function () { return EdgeAgent_1.EdgeAgent; } });
|
|
9
10
|
var config_1 = require("./config");
|
|
@@ -69,6 +70,8 @@ Object.defineProperty(exports, "VlmAdmissionGate", { enumerable: true, get: func
|
|
|
69
70
|
var VlmCandidateBuffer_1 = require("./VlmCandidateBuffer");
|
|
70
71
|
Object.defineProperty(exports, "VlmCandidateBuffer", { enumerable: true, get: function () { return VlmCandidateBuffer_1.VlmCandidateBuffer; } });
|
|
71
72
|
Object.defineProperty(exports, "DEFAULT_CANDIDATE_TTL_MS", { enumerable: true, get: function () { return VlmCandidateBuffer_1.DEFAULT_CANDIDATE_TTL_MS; } });
|
|
73
|
+
var DurableVlmCandidateSpool_1 = require("./DurableVlmCandidateSpool");
|
|
74
|
+
Object.defineProperty(exports, "DurableVlmCandidateSpool", { enumerable: true, get: function () { return DurableVlmCandidateSpool_1.DurableVlmCandidateSpool; } });
|
|
72
75
|
var SceneChangeDetector_1 = require("./SceneChangeDetector");
|
|
73
76
|
Object.defineProperty(exports, "MotionGate", { enumerable: true, get: function () { return SceneChangeDetector_1.MotionGate; } });
|
|
74
77
|
Object.defineProperty(exports, "SceneChangeDetector", { enumerable: true, get: function () { return SceneChangeDetector_1.SceneChangeDetector; } });
|
|
@@ -76,6 +79,20 @@ Object.defineProperty(exports, "isChangeCandidate", { enumerable: true, get: fun
|
|
|
76
79
|
Object.defineProperty(exports, "decodeGreyFrame", { enumerable: true, get: function () { return SceneChangeDetector_1.decodeGreyFrame; } });
|
|
77
80
|
Object.defineProperty(exports, "downscaleRgbaToGrey", { enumerable: true, get: function () { return SceneChangeDetector_1.downscaleRgbaToGrey; } });
|
|
78
81
|
Object.defineProperty(exports, "motionSignature", { enumerable: true, get: function () { return SceneChangeDetector_1.motionSignature; } });
|
|
82
|
+
// The acoustic half of the cascade. DSP, not a model: Gemma 4 transcribes
|
|
83
|
+
// speech excellently and does not name acoustic events — measured, see the
|
|
84
|
+
// AudioOnsetDetector header for the full battery.
|
|
85
|
+
var AudioOnsetDetector_1 = require("./AudioOnsetDetector");
|
|
86
|
+
Object.defineProperty(exports, "AudioOnsetDetector", { enumerable: true, get: function () { return AudioOnsetDetector_1.AudioOnsetDetector; } });
|
|
87
|
+
Object.defineProperty(exports, "rmsDbfs", { enumerable: true, get: function () { return AudioOnsetDetector_1.rmsDbfs; } });
|
|
88
|
+
Object.defineProperty(exports, "SILENCE_DBFS", { enumerable: true, get: function () { return AudioOnsetDetector_1.SILENCE_DBFS; } });
|
|
89
|
+
var attachAudioOnset_1 = require("./attachAudioOnset");
|
|
90
|
+
Object.defineProperty(exports, "attachAudioOnset", { enumerable: true, get: function () { return attachAudioOnset_1.attachAudioOnset; } });
|
|
91
|
+
var wavEncode_1 = require("./wavEncode");
|
|
92
|
+
Object.defineProperty(exports, "encodeWav16", { enumerable: true, get: function () { return wavEncode_1.encodeWav16; } });
|
|
93
|
+
Object.defineProperty(exports, "takeMostRecentSeconds", { enumerable: true, get: function () { return wavEncode_1.takeMostRecentSeconds; } });
|
|
94
|
+
Object.defineProperty(exports, "GEMMA_AUDIO_SAMPLE_RATE", { enumerable: true, get: function () { return wavEncode_1.GEMMA_AUDIO_SAMPLE_RATE; } });
|
|
95
|
+
Object.defineProperty(exports, "GEMMA_AUDIO_MAX_SECONDS", { enumerable: true, get: function () { return wavEncode_1.GEMMA_AUDIO_MAX_SECONDS; } });
|
|
79
96
|
// Mosaic tiling: carve one composite ("mosaic"/quad) RTSP feed into per-screen
|
|
80
97
|
// tiles, pulling the source once and cropping each tile in ffmpeg.
|
|
81
98
|
var MosaicSource_1 = require("./MosaicSource");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,6CAA6C;AAC7C,mEAAmE
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,6CAA6C;AAC7C,mEAAmE;;;;AAEnE,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAElB,mCAAqD;AAA5C,oGAAA,UAAU,OAAA;AAAE,uGAAA,aAAa,OAAA;AAClC,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAEtB,+BAAiC;AAAxB,+FAAA,OAAO,OAAA;AAChB,uCAAyC;AAAhC,uGAAA,WAAW,OAAA;AAGpB,8EAA8E;AAC9E,yEAAyE;AACzE,iFAAiF;AACjF,yDAO6B;AAN3B,gIAAA,2BAA2B,OAAA;AAC3B,2HAAA,sBAAsB,OAAA;AACtB,uHAAA,kBAAkB,OAAA;AAClB,2HAAA,sBAAsB,OAAA;AACtB,iIAAA,4BAA4B,OAAA;AAC5B,yHAAA,oBAAoB,OAAA;AAGtB,uDAK4B;AAJ1B,oHAAA,gBAAgB,OAAA;AAChB,0HAAA,sBAAsB,OAAA;AACtB,0HAAA,sBAAsB,OAAA;AACtB,kHAAA,cAAc,OAAA;AAGhB,qDAA8E;AAArE,sHAAA,mBAAmB,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAElD,qDAAsE;AAA7D,qHAAA,kBAAkB,OAAA;AAAE,gHAAA,aAAa,OAAA;AAE1C,4EAA4E;AAC5E,uDAAuD;AACvD,2DAK8B;AAJ5B,6HAAA,uBAAuB,OAAA;AACvB,+HAAA,yBAAyB,OAAA;AACzB,qIAAA,+BAA+B,OAAA;AAC/B,kIAAA,4BAA4B,OAAA;AAS9B,kFAAkF;AAClF,iEAAmF;AAA1E,8HAAA,qBAAqB,OAAA;AAAE,0HAAA,iBAAiB,OAAA;AAWjD,6DAM+B;AAL7B,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,wHAAA,iBAAiB,OAAA;AACjB,+HAAA,wBAAwB,OAAA;AACxB,mHAAA,YAAY,OAAA;AAEd,qEAMmC;AALjC,kIAAA,uBAAuB,OAAA;AACvB,2HAAA,gBAAgB,OAAA;AAChB,8HAAA,mBAAmB,OAAA;AACnB,4HAAA,iBAAiB,OAAA;AACjB,+IAAA,oCAAoC,OAAA;AAStC,+DAA+D;AAC/D,6EAA6E;AAC7E,uBAAuB;AACvB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAMzB,wEAAwE;AACxE,sEAAsE;AACtE,2DAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,8HAAA,wBAAwB,OAAA;AACrD,uEAAsE;AAA7D,oIAAA,wBAAwB,OAAA;AAYjC,6DAO+B;AAN7B,iHAAA,UAAU,OAAA;AACV,0HAAA,mBAAmB,OAAA;AACnB,wHAAA,iBAAiB,OAAA;AACjB,sHAAA,eAAe,OAAA;AACf,0HAAA,mBAAmB,OAAA;AACnB,sHAAA,eAAe,OAAA;AAajB,0EAA0E;AAC1E,2EAA2E;AAC3E,kDAAkD;AAClD,2DAAiF;AAAxE,wHAAA,kBAAkB,OAAA;AAAE,6GAAA,OAAO,OAAA;AAAE,kHAAA,YAAY,OAAA;AAMlD,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AAMzB,yCAKqB;AAJnB,wGAAA,WAAW,OAAA;AACX,kHAAA,qBAAqB,OAAA;AACrB,oHAAA,uBAAuB,OAAA;AACvB,oHAAA,uBAAuB,OAAA;AAEzB,+EAA+E;AAC/E,mEAAmE;AACnE,+CAAqE;AAA5D,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
|