@trillboards/edge-sdk 0.2.42 → 0.2.49

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.
Files changed (51) hide show
  1. package/README.md +18 -0
  2. package/deploy/docker/connector-entrypoint.sh +1 -1
  3. package/dist/CloudSensingManager.d.ts +18 -0
  4. package/dist/CloudSensingManager.d.ts.map +1 -1
  5. package/dist/CloudSensingManager.js +101 -16
  6. package/dist/CloudSensingManager.js.map +1 -1
  7. package/dist/DurableVlmCandidateSpool.d.ts +99 -0
  8. package/dist/DurableVlmCandidateSpool.d.ts.map +1 -0
  9. package/dist/DurableVlmCandidateSpool.js +522 -0
  10. package/dist/DurableVlmCandidateSpool.js.map +1 -0
  11. package/dist/EdgeAgent.js +1 -1
  12. package/dist/LiteRtVlmProvider.d.ts +12 -1
  13. package/dist/LiteRtVlmProvider.d.ts.map +1 -1
  14. package/dist/LiteRtVlmProvider.js.map +1 -1
  15. package/dist/SceneChangeDetector.d.ts +35 -5
  16. package/dist/SceneChangeDetector.d.ts.map +1 -1
  17. package/dist/SceneChangeDetector.js +19 -5
  18. package/dist/SceneChangeDetector.js.map +1 -1
  19. package/dist/VlmAdmissionGate.d.ts +63 -0
  20. package/dist/VlmAdmissionGate.d.ts.map +1 -1
  21. package/dist/VlmAdmissionGate.js +64 -0
  22. package/dist/VlmAdmissionGate.js.map +1 -1
  23. package/dist/VlmCandidateBuffer.d.ts +17 -0
  24. package/dist/VlmCandidateBuffer.d.ts.map +1 -1
  25. package/dist/VlmCandidateBuffer.js +6 -0
  26. package/dist/VlmCandidateBuffer.js.map +1 -1
  27. package/dist/config.d.ts +37 -4
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js.map +1 -1
  30. package/dist/connectorCadence.d.ts +193 -8
  31. package/dist/connectorCadence.d.ts.map +1 -1
  32. package/dist/connectorCadence.js +225 -10
  33. package/dist/connectorCadence.js.map +1 -1
  34. package/dist/deployedCadence.d.ts +18 -5
  35. package/dist/deployedCadence.d.ts.map +1 -1
  36. package/dist/deployedCadence.js +50 -13
  37. package/dist/deployedCadence.js.map +1 -1
  38. package/dist/diagnose.d.ts +1 -1
  39. package/dist/diagnose.js +1 -1
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +3 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/sensingCatchRate.d.ts +105 -3
  45. package/dist/sensingCatchRate.d.ts.map +1 -1
  46. package/dist/sensingCatchRate.js +98 -10
  47. package/dist/sensingCatchRate.js.map +1 -1
  48. package/dist/sensingRunMode.d.ts.map +1 -1
  49. package/dist/sensingRunMode.js +95 -4
  50. package/dist/sensingRunMode.js.map +1 -1
  51. package/package.json +1 -1
@@ -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 is free and is not the constraint: 3.6 ms median / 7.1 ms p95 to
53
- * pull a frame down to ~178x100 grey and run the motion detector.
54
- * Sixteen feeds looking every 30 s is 0.19% of one core.
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 the LOOK interval (`faceTriggeredIntervalMs`, 30 s):
78
- * you cannot analyze more often than you look.
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
- * The connector's look cadence (`faceTriggeredIntervalMs` default, which is
114
- * also the motion gate's scan interval). A heartbeat can never be finer.
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.LOOK_INTERVAL_MS = 30000;
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
- return Math.min(exports.DOOH_PERIODIC_MS, Math.max(exports.LOOK_INTERVAL_MS, required));
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8FG;;;AAkCH,wEAKC;AAQD,wCAUC;AAvDD;;;;GAIG;AACU,QAAA,yBAAyB,GAAG,IAAK,CAAC;AAE/C;;;GAGG;AACU,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAE1C;;;GAGG;AACU,QAAA,gBAAgB,GAAG,KAAM,CAAC;AAEvC,oFAAoF;AACvE,QAAA,gBAAgB,GAAG,MAAO,CAAC;AAExC;;;;;;;;;GASG;AACH,SAAgB,8BAA8B,CAAC,SAAkB;IAC/D,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,iCAAyB,CAAC,GAAG,8BAAsB,CAAC,CAAC;IACjG,OAAO,IAAI,CAAC,GAAG,CAAC,wBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,wBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAC5B,SAAkB,EAClB,kBAA2B;IAE3B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC/E,MAAM,eAAe,GAAG,CAAC,CAAC,GAAG,OAAS,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,OAAS,GAAG,iCAAyB,CAAC;IAC7D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,GAAG,cAAc,EAAE,CAAC;AAC1E,CAAC"}
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
- /** Faster than the connector ever looks — a cadence finer than a look is meaningless. */
101
- | 'look_interval'
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
- * Returns `intervalMs: null` when the profile requested nothing — the caller
121
- * MUST then leave its current cadence alone, so a connector whose server says
122
- * nothing behaves exactly as it does today.
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,yFAAyF;GACvF,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;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,eAAe,CA8ClB"}
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"}
@@ -98,9 +98,10 @@ function normalizeRequest(value) {
98
98
  /**
99
99
  * Reconcile a deployed cadence with what this mode can afford.
100
100
  *
101
- * Returns `intervalMs: null` when the profile requested nothing — the caller
102
- * MUST then leave its current cadence alone, so a connector whose server says
103
- * nothing behaves exactly as it does today.
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 LOOK interval cannot be delivered by a loop that
113
- // only looks that often, so it is a floor. The ceiling wins over the floor:
114
- // honouring a floor slower than a whole day would hand a capture loop a delay
115
- // it cannot express (see MAX_CADENCE_MS) — the one clamp that must never be
116
- // negotiable.
117
- const effectiveFloor = Math.min(exports.MAX_CADENCE_MS, Math.max(floorMs, connectorCadence_1.LOOK_INTERVAL_MS));
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: null,
157
+ intervalMs: effectiveFloor,
121
158
  requestedMs: null,
122
159
  floorMs: effectiveFloor,
123
160
  ceilingMs: exports.MAX_CADENCE_MS,
124
161
  clamped: false,
125
- reason: 'no_request',
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.LOOK_INTERVAL_MS && floorMs <= connectorCadence_1.LOOK_INTERVAL_MS)
136
- reason = 'look_interval';
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;;;AAkFH,wDAkDC;AAlID,yDAI4B;AAU5B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AA4B/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;;;;;;GAMG;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,4EAA4E;IAC5E,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,cAAc;IACd,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAc,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,mCAAgB,CAAC,CAAC,CAAC;IAErF,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO;YACL,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,sBAAc;YACzB,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,YAAY;SACrB,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,mCAAgB,IAAI,OAAO,IAAI,mCAAgB;YAAE,MAAM,GAAG,eAAe,CAAC;;YAC5F,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"}
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"}
@@ -31,7 +31,7 @@ export interface DiagnosticReport {
31
31
  skipped: number;
32
32
  };
33
33
  }
34
- declare const SDK_VERSION = "0.2.42";
34
+ declare const SDK_VERSION = "0.2.49";
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.42';
66
+ const SDK_VERSION = '0.2.49';
67
67
  exports._SDK_VERSION = SDK_VERSION;
68
68
  // ---------------------------------------------------------------------------
69
69
  // ANSI helpers (no external deps)
package/dist/index.d.ts CHANGED
@@ -25,6 +25,8 @@ 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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACpF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKnD,OAAO,EACL,2BAA2B,EAC3B,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACtE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACnF,YAAY,EACV,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,UAAU,GACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,oCAAoC,GACrC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAChF,YAAY,EACV,0BAA0B,EAC1B,eAAe,EACf,YAAY,GACb,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACpF,YAAY,EACV,YAAY,EACZ,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,SAAS,EACT,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,sBAAsB,EACtB,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,wBAAwB,CAAC"}
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,7 @@
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.CropViewProvider = exports.SharedFrameSource = exports.motionSignature = exports.downscaleRgbaToGrey = exports.decodeGreyFrame = exports.isChangeCandidate = exports.SceneChangeDetector = exports.MotionGate = 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;
6
+ exports.CropViewProvider = exports.SharedFrameSource = 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
7
  var EdgeAgent_1 = require("./EdgeAgent");
8
8
  Object.defineProperty(exports, "EdgeAgent", { enumerable: true, get: function () { return EdgeAgent_1.EdgeAgent; } });
9
9
  var config_1 = require("./config");
@@ -69,6 +69,8 @@ Object.defineProperty(exports, "VlmAdmissionGate", { enumerable: true, get: func
69
69
  var VlmCandidateBuffer_1 = require("./VlmCandidateBuffer");
70
70
  Object.defineProperty(exports, "VlmCandidateBuffer", { enumerable: true, get: function () { return VlmCandidateBuffer_1.VlmCandidateBuffer; } });
71
71
  Object.defineProperty(exports, "DEFAULT_CANDIDATE_TTL_MS", { enumerable: true, get: function () { return VlmCandidateBuffer_1.DEFAULT_CANDIDATE_TTL_MS; } });
72
+ var DurableVlmCandidateSpool_1 = require("./DurableVlmCandidateSpool");
73
+ Object.defineProperty(exports, "DurableVlmCandidateSpool", { enumerable: true, get: function () { return DurableVlmCandidateSpool_1.DurableVlmCandidateSpool; } });
72
74
  var SceneChangeDetector_1 = require("./SceneChangeDetector");
73
75
  Object.defineProperty(exports, "MotionGate", { enumerable: true, get: function () { return SceneChangeDetector_1.MotionGate; } });
74
76
  Object.defineProperty(exports, "SceneChangeDetector", { enumerable: true, get: function () { return SceneChangeDetector_1.SceneChangeDetector; } });
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;;;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;AAQrD,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,+EAA+E;AAC/E,mEAAmE;AACnE,+CAAqE;AAA5D,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
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,+EAA+E;AAC/E,mEAAmE;AACnE,+CAAqE;AAA5D,iHAAA,iBAAiB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}