@trillboards/edge-sdk 0.2.39 → 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.
Files changed (82) hide show
  1. package/README.md +1 -1
  2. package/deploy/docker/{Dockerfile.cloud-sense → Dockerfile.connector} +52 -39
  3. package/deploy/docker/README.md +73 -1
  4. package/deploy/docker/connector-entrypoint.sh +46 -80
  5. package/deploy/macos/README.md +1 -1
  6. package/deploy/macos/test-install-pair.sh +9 -9
  7. package/deploy/systemd/install.sh +16 -1
  8. package/deploy/systemd/setup-litertlm.sh +201 -0
  9. package/deploy/systemd/trillboards-edge.service +8 -4
  10. package/deploy/systemd/trillboards-litertlm.service +46 -0
  11. package/deploy/windows/register-task.ps1 +6 -3
  12. package/deploy/windows/run-connector.ps1 +1 -1
  13. package/deploy/windows/trillboards-edge-task.vbs +5 -1
  14. package/dist/CloudSensingManager.d.ts +45 -19
  15. package/dist/CloudSensingManager.d.ts.map +1 -1
  16. package/dist/CloudSensingManager.js +89 -46
  17. package/dist/CloudSensingManager.js.map +1 -1
  18. package/dist/EdgeAgent.js +1 -1
  19. package/dist/SensingProfileClient.d.ts +9 -0
  20. package/dist/SensingProfileClient.d.ts.map +1 -1
  21. package/dist/SensingProfileClient.js +4 -0
  22. package/dist/SensingProfileClient.js.map +1 -1
  23. package/dist/SetupSessionClient.d.ts +0 -1
  24. package/dist/SetupSessionClient.d.ts.map +1 -1
  25. package/dist/autoSense.d.ts +42 -31
  26. package/dist/autoSense.d.ts.map +1 -1
  27. package/dist/autoSense.js +127 -99
  28. package/dist/autoSense.js.map +1 -1
  29. package/dist/cli.d.ts.map +1 -1
  30. package/dist/cli.js +25 -84
  31. package/dist/cli.js.map +1 -1
  32. package/dist/combinedSense.d.ts +1 -3
  33. package/dist/combinedSense.d.ts.map +1 -1
  34. package/dist/combinedSense.js +0 -1
  35. package/dist/combinedSense.js.map +1 -1
  36. package/dist/config.d.ts +17 -64
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +0 -10
  39. package/dist/config.js.map +1 -1
  40. package/dist/deployedCadence.d.ts +37 -75
  41. package/dist/deployedCadence.d.ts.map +1 -1
  42. package/dist/deployedCadence.js +45 -105
  43. package/dist/deployedCadence.js.map +1 -1
  44. package/dist/deployedCadenceSource.d.ts +0 -2
  45. package/dist/deployedCadenceSource.d.ts.map +1 -1
  46. package/dist/deployedCadenceSource.js +0 -1
  47. package/dist/deployedCadenceSource.js.map +1 -1
  48. package/dist/diagnose.d.ts +1 -1
  49. package/dist/diagnose.js +1 -1
  50. package/dist/index.d.ts +0 -3
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +1 -8
  53. package/dist/index.js.map +1 -1
  54. package/dist/localInferenceSchema.d.ts +19 -0
  55. package/dist/localInferenceSchema.d.ts.map +1 -1
  56. package/dist/localInferenceSchema.js +23 -0
  57. package/dist/localInferenceSchema.js.map +1 -1
  58. package/dist/localSensing.d.ts +48 -107
  59. package/dist/localSensing.d.ts.map +1 -1
  60. package/dist/localSensing.js +80 -171
  61. package/dist/localSensing.js.map +1 -1
  62. package/dist/sensingCatchRate.d.ts +246 -0
  63. package/dist/sensingCatchRate.d.ts.map +1 -0
  64. package/dist/sensingCatchRate.js +514 -0
  65. package/dist/sensingCatchRate.js.map +1 -0
  66. package/dist/sensingRunMode.d.ts +14 -11
  67. package/dist/sensingRunMode.d.ts.map +1 -1
  68. package/dist/sensingRunMode.js +9 -92
  69. package/dist/sensingRunMode.js.map +1 -1
  70. package/dist/setupMode.d.ts +0 -1
  71. package/dist/setupMode.d.ts.map +1 -1
  72. package/dist/setupMode.js +5 -3
  73. package/dist/setupMode.js.map +1 -1
  74. package/dist/startupDiscovery.d.ts +43 -0
  75. package/dist/startupDiscovery.d.ts.map +1 -0
  76. package/dist/startupDiscovery.js +72 -0
  77. package/dist/startupDiscovery.js.map +1 -0
  78. package/package.json +1 -1
  79. package/dist/CloudEscalationPolicy.d.ts +0 -143
  80. package/dist/CloudEscalationPolicy.d.ts.map +0 -1
  81. package/dist/CloudEscalationPolicy.js +0 -137
  82. package/dist/CloudEscalationPolicy.js.map +0 -1
@@ -3,15 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LocalSensingClient = void 0;
4
4
  exports.fieldSetForProfileType = fieldSetForProfileType;
5
5
  exports.isAlertWorthy = isAlertWorthy;
6
- exports.alertSignature = alertSignature;
7
- exports.isCloudEscalationEnabled = isCloudEscalationEnabled;
8
6
  exports.buildLocalSensingLoops = buildLocalSensingLoops;
9
7
  const AudienceAnalyzeClient_1 = require("./AudienceAnalyzeClient");
10
8
  const LiteRtVlmProvider_1 = require("./LiteRtVlmProvider");
11
9
  const SensingProfileClient_1 = require("./SensingProfileClient");
12
10
  const CloudSensingManager_1 = require("./CloudSensingManager");
13
11
  const localInferenceSchema_1 = require("./localInferenceSchema");
14
- const CloudEscalationPolicy_1 = require("./CloudEscalationPolicy");
15
12
  const legacyRecorderProfile_1 = require("./legacyRecorderProfile");
16
13
  /** How long a fetched profile is cached before the connector re-checks for a new alert. */
17
14
  const DEFAULT_PROFILE_TTL_MS = 5 * 60 * 1000;
@@ -85,92 +82,80 @@ const NON_DISCRIMINATIVE_KEYS = new Set(['source', 'captured_at', 'confidence',
85
82
  * Non-discriminative keys (source, captured_at, confidence, scene_description)
86
83
  * are ignored — see NON_DISCRIMINATIVE_KEYS for why.
87
84
  *
88
- * KNOWN BOUNDARY (deliberate privacy tradeoff): a route that alerts on ABSENCE
89
- * — `person_count lte 0`, `people_present eq false`, `shelf_state eq "empty"` —
90
- * fires on a genuinely empty scene, which this gate suppresses by design (a
91
- * blank-room frame is exactly the privacy harm the gate exists to prevent). The
92
- * server owns the route predicates and can request a frame for those routes;
93
- * operators who want every frame can disable the gate (attachEvidenceFrame).
85
+ * ABSENCE (`absenceWatchedFields`) — the empty-shelf half. The rule above answers
86
+ * "is anything HERE?", which is the right question for people and the WRONG one for
87
+ * stock: "the shelf is empty" is a positive finding about a subject that IS in frame,
88
+ * and the operator asked to be told about it. So a field named in `absenceWatchedFields`
89
+ * flips: its EMPTY reading (`shelf_state: 'empty'`, `stock_level: 0`,
90
+ * `product_available: false`, `[]`, `{}`) counts as signal.
91
+ *
92
+ * That set is not guessed from the field's spelling and is not an allowlist of stock
93
+ * words. The server derives it per screen from the operator's OWN saved route
94
+ * conditions — a field is in it only when an enabled route would actually FIRE on that
95
+ * field's empty reading (`shelf_state eq 'empty'`). So `smoking_activity_detected: false`
96
+ * on an empty scene stays suppressed, because no route targets its absence, and a
97
+ * profile with no absence-targeting route behaves byte-for-byte as before.
98
+ *
99
+ * The privacy FLOOR is unconditional: `DEFAULT_SCENE_FIELD_KEYS` — the presence
100
+ * primitives and the DOOH audience block, i.e. every field whose subject IS the people
101
+ * in front of the camera — can NEVER be unlocked this way, even by a route that
102
+ * explicitly targets them (`person_count lte 0`). Absence of PEOPLE is the blank-room
103
+ * frame the gate exists to prevent; absence of STOCK is the operator's finding. That is
104
+ * the whole distinction, and it is enforced structurally rather than by tuning.
105
+ * Operators who want every frame regardless can still disable the gate
106
+ * (attachEvidenceFrame).
94
107
  */
95
- function isAlertWorthy(result) {
108
+ function isAlertWorthy(result, absenceWatchedFields) {
96
109
  if (!result || typeof result !== 'object')
97
110
  return false;
111
+ const watched = absenceWatchedFields instanceof Set
112
+ ? absenceWatchedFields
113
+ : new Set(Array.isArray(absenceWatchedFields) ? absenceWatchedFields : []);
98
114
  for (const [key, value] of Object.entries(result)) {
99
115
  if (NON_DISCRIMINATIVE_KEYS.has(key))
100
116
  continue;
117
+ // Absence is signal ONLY for an operator-declared subject the operator's own route
118
+ // watches for absence. Never for a scene-occupancy field — see the floor above.
119
+ const absenceIsSignal = watched.has(key) && !localInferenceSchema_1.DEFAULT_SCENE_FIELD_KEYS.has(key);
101
120
  if (value === true)
102
121
  return true;
122
+ if (value === false) {
123
+ if (absenceIsSignal)
124
+ return true;
125
+ continue;
126
+ }
103
127
  if (typeof value === 'number') {
104
128
  if (Number.isFinite(value) && value > 0)
105
129
  return true;
130
+ if (absenceIsSignal && Number.isFinite(value) && value === 0)
131
+ return true;
106
132
  continue;
107
133
  }
108
134
  if (typeof value === 'string') {
109
135
  const v = value.trim().toLowerCase();
110
136
  if (v.length > 0 && !EMPTY_SCENE_SENTINELS.has(v))
111
137
  return true;
138
+ if (absenceIsSignal)
139
+ return true; // '' / 'empty' / 'none' / 'unknown' IS the finding
112
140
  continue;
113
141
  }
114
142
  if (Array.isArray(value)) {
115
143
  if (value.length > 0)
116
144
  return true;
145
+ if (absenceIsSignal)
146
+ return true;
117
147
  continue;
118
148
  }
119
149
  if (value && typeof value === 'object') {
120
150
  if (Object.keys(value).length > 0)
121
151
  return true;
152
+ if (absenceIsSignal)
153
+ return true;
122
154
  continue;
123
155
  }
124
156
  }
125
157
  return false;
126
158
  }
127
- /**
128
- * A stable fingerprint of the ALERT-BEARING state of one result — "has the
129
- * operator-visible situation changed?" in one comparable string.
130
- *
131
- * Built from EXACTLY the keys `isAlertWorthy` judges (NON_DISCRIMINATIVE_KEYS
132
- * excluded), so the two can never drift: the same fields that decide whether a
133
- * frame carries signal decide whether that signal is NEW. Keys are sorted so
134
- * the model's property order cannot manufacture a change, and values are
135
- * compared as emitted — a `queue_length` of 3 and of 4 are genuinely different
136
- * facts and an operator route may key on exactly that boundary, so this
137
- * deliberately does NOT bucket numbers into invented bands.
138
- *
139
- * Used by CloudEscalationPolicy's novelty bound: an unchanged signature means a
140
- * verdict the cloud has already adjudicated, so the frame stays on-premises.
141
- */
142
- function alertSignature(result) {
143
- if (!result || typeof result !== 'object')
144
- return '';
145
- const parts = [];
146
- for (const key of Object.keys(result).sort()) {
147
- if (NON_DISCRIMINATIVE_KEYS.has(key))
148
- continue;
149
- const value = result[key];
150
- // Arrays/objects (a `list` / `distribution` custom field) serialize
151
- // structurally; scalars stringify. Undefined is elided so an absent key and
152
- // an explicitly-undefined key read the same.
153
- if (value === undefined)
154
- continue;
155
- parts.push(`${key}=${typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value)}`);
156
- }
157
- return parts.join('|');
158
- }
159
- /**
160
- * Is cloud escalation actually ON for this local-sensing configuration?
161
- *
162
- * TWO settings decide it, and this is the ONLY place that combines them:
163
- * `cloudEscalation.enabled` opts in, and `attachEvidenceFrame: false` — the
164
- * operator's "no frame ever leaves this machine" switch — outranks it, because
165
- * escalation sends a frame. `LocalSensingClient` enforces the rule and the
166
- * startup banner reports it; they must read the same expression or the banner
167
- * will one day claim an egress posture the client is not running.
168
- */
169
- function isCloudEscalationEnabled(options) {
170
- if (!options)
171
- return false;
172
- return options.cloudEscalation?.enabled === true && options.attachEvidenceFrame !== false;
173
- }
174
159
  /**
175
160
  * LocalSensingClient — the SensingClient the cadence loop uses in LOCAL mode.
176
161
  * It runs the VLM ON-DEVICE (LiteRtVlmProvider — Gemma 4 on LiteRT-LM via
@@ -194,45 +179,45 @@ function isCloudEscalationEnabled(options) {
194
179
  * gating local-inferred data out of the sold bidstream while still firing the
195
180
  * operator's Sense-Anything routes.
196
181
  *
197
- * ── CLOUD ESCALATION (opt-in, Phase 6d) ─────────────────────────────────────
198
- * Local Gemma is the always-on gate; the CLOUD is the judge for the frames it
199
- * flags. When `cloudEscalation.enabled` and the policy admits this frame, the
200
- * SAME JPEG is POSTed through the SAME upload client's `analyze()` — the cloud
201
- * path the connector already owns — and the cloud VLM's verdict becomes the
202
- * observation. Three properties are load-bearing:
182
+ * ── THERE IS NO CLOUD PATH ─────────────────────────────────────────────────
183
+ * This client once had three doors to the cloud VLM: `cloudFallbackOnError` (a
184
+ * per-frame degrade when local inference threw), `cloudEscalation` (Phase 6d —
185
+ * local Gemma gates, the cloud adjudicates the candidates it flags), and the
186
+ * whole-mode `allowCloudFallback` in auto-sense. All three are gone, and this
187
+ * supersedes the escalation architecture from #11971 ("local Gemma decides
188
+ * *when* to look, the cloud decides *what* it saw").
203
189
  *
204
- * 1. ONE FRAME, ONE OBSERVATION. An escalated frame does NOT also post its
205
- * local `preAnalyzed` result. Posting both would double-count the same
206
- * physical frame and put two verdicts for one moment in the stream —
207
- * exactly the dual write the codebase forbids. The cloud verdict
208
- * supersedes; the local one was a sampling decision, not a datum.
209
- * 2. NO PROVENANCE LAUNDERING. What lands is what the CLOUD inferred from a
210
- * real frame, so the server's normal cloud provenance is the truthful
211
- * stamp — identical to `cloud-sense` and to the existing
212
- * `cloudFallbackOnError` frame. Nothing the local model produced enters
213
- * that record, so `ingest_source='local_connector'` (which exists to keep
214
- * operator-forgeable structured input out of the sold bidstream) does not
215
- * apply and is not evaded: there IS no local structured input on this path.
216
- * 3. THE PRIVACY GATE IS UNCHANGED. Escalation reuses `isAlertWorthy`, so the
217
- * set of frames that can leave the premises is exactly the set that
218
- * already leaves as evidence photos — and `attachEvidenceFrame: false`
219
- * (the operator's "no frame ever leaves" switch) disables escalation
220
- * outright. An empty scene never escalates.
190
+ * The reason is arithmetic, not architecture. Measured 2026-08-12 over 255,812
191
+ * image-bearing cloud VLM calls: $0.007008 per analyzed frame. At a 30s cadence
192
+ * that is ~$605/camera/month, so a 16-camera store cost ~$9,688/month against a
193
+ * $99-500 subscription — about 10x underwater. Escalation narrowed WHICH frames
194
+ * went, and the earlier plan (plans/cctv-byo-sensing-plan.md:26) narrowed HOW
195
+ * OFTEN; neither changes the sign. A path that meters per frame does not belong
196
+ * in a flat-rate product, so the path is removed rather than rate-limited.
221
197
  *
222
- * A failed cloud call falls back to posting the local result, so an escalation
223
- * can degrade the ACCURACY of one frame but can never LOSE it.
198
+ * What replaces it: nothing on the frame path. A frame the on-device runtime
199
+ * cannot analyze is dropped and the fault is surfaced (see the catch in
200
+ * `analyze`), and a connector with no usable runtime WAITS and beacons its
201
+ * `waiting` state rather than silently spending.
224
202
  */
225
203
  class LocalSensingClient {
226
204
  constructor(localProvider, uploadClient, options = {}) {
227
205
  this.localProvider = localProvider;
228
206
  this.uploadClient = uploadClient;
207
+ /**
208
+ * Fields whose ABSENT reading an operator route on this screen fires on, from the
209
+ * deployed profile (see SensingProfileClient.absenceWatchedFields). Refreshed on the
210
+ * SAME cadence as the schema, because a route saved after the last poll must not be
211
+ * able to change the gate before the model is even emitting its field. Empty until a
212
+ * profile fetch succeeds, so the gate's default is the strict pre-existing behavior.
213
+ */
214
+ this.cachedAbsenceWatchedFields = new Set();
229
215
  this.lastProfileFetchMs = 0;
230
216
  /**
231
217
  * Frames the ON-DEVICE runtime actually produced a result for.
232
218
  *
233
219
  * Counted at the one place that knows — immediately after `localProvider
234
- * .analyze()` RETURNS — so a `cloudFallbackOnError` frame (local threw, the
235
- * cloud answered) and an escalated frame are both excluded. `auto-sense`
220
+ * .analyze()` RETURNS. `auto-sense`
236
221
  * reads this through `getSensingHealth().localInferences` as the only
237
222
  * positive proof that a `litert-lm serve` too busy to answer `/v1/models` is
238
223
  * busy rather than dead; a counter that a cloud call could advance would make
@@ -254,19 +239,6 @@ class LocalSensingClient {
254
239
  this.cachedSchema = this.baseSchema;
255
240
  this.cachedPrompt = this.basePrompt;
256
241
  this.attachEvidenceFrame = options.attachEvidenceFrame !== false;
257
- this.cloudFallbackOnError = options.cloudFallbackOnError === true;
258
- this.feedName = options.feedName || 'local-sense';
259
- // `attachEvidenceFrame: false` is the operator saying NO frame may ever
260
- // leave this machine, and escalation sends a frame — isCloudEscalationEnabled
261
- // is the one expression that resolves the pair (the startup banner reads the
262
- // same one, so the two can never disagree).
263
- this.escalationPolicy = new CloudEscalationPolicy_1.CloudEscalationPolicy({
264
- ...(options.cloudEscalation || {}),
265
- enabled: isCloudEscalationEnabled({
266
- attachEvidenceFrame: this.attachEvidenceFrame,
267
- cloudEscalation: options.cloudEscalation,
268
- }),
269
- });
270
242
  }
271
243
  getEndpoint() {
272
244
  return this.uploadClient.getEndpoint();
@@ -295,6 +267,7 @@ class LocalSensingClient {
295
267
  if (profile === null)
296
268
  return; // transient error — keep last-good schema
297
269
  this.activeProfileName = profile.profileName;
270
+ this.cachedAbsenceWatchedFields = new Set(profile.absenceWatchedFields || []);
298
271
  const fieldSet = fieldSetForProfileType(profile.profileType);
299
272
  this.activeFieldSet = fieldSet;
300
273
  if (fieldSet === 'operator' || profile.fields.length > 0) {
@@ -317,16 +290,6 @@ class LocalSensingClient {
317
290
  getAcceleratorHealth() {
318
291
  return this.localProvider.getAcceleratorHealth();
319
292
  }
320
- /**
321
- * Cloud-escalation counters for this feed — how many candidate frames were
322
- * adjudicated by the cloud VLM, and why the rest were not. Read by
323
- * `CloudSensingManager.getSensingHealth()` so escalation shows up on the
324
- * operator's periodic capacity line: sending frames off-premises must be
325
- * VISIBLE, not merely documented.
326
- */
327
- getEscalationStats() {
328
- return this.escalationPolicy.getStats();
329
- }
330
293
  /** Frames the on-device runtime produced a result for. See the field docs. */
331
294
  getLocalInferenceStats() {
332
295
  return { completed: this.localInferencesCompleted };
@@ -352,25 +315,17 @@ class LocalSensingClient {
352
315
  });
353
316
  }
354
317
  catch (err) {
355
- if (!this.cloudFallbackOnError)
356
- throw err;
357
- // Per-frame degrade: on-device inference threw for THIS frame, so ship it
358
- // to the cloud VLM instead of dropping it. Reuses the SAME upload client —
359
- // the cloud path the connector already has — so no new provider/logic. The
360
- // server provenance-gates a cloud-served frame exactly like cloud-sense.
361
- // eslint-disable-next-line no-console
362
- console.warn(`[local-sense] on-device inference failed for a frame (${err.message}) — ` +
363
- 'falling back to the cloud VLM for this frame');
364
- return this.uploadClient.analyze({
365
- jpeg: request.jpeg,
366
- capturedAt: Date.now(),
367
- captureMode: request.captureMode,
368
- ...frameDimensions,
369
- });
318
+ // LOCAL-INFERENCE ONLY: a frame the on-device runtime could not analyze is
319
+ // DROPPED, not metered. This branch used to POST the frame to the cloud
320
+ // VLM (`cloudFallbackOnError`) at $0.007008 each — the per-frame cost this
321
+ // whole change exists to remove. The capture loop's own cadence is the
322
+ // resilience: the next frame is seconds away, and a runtime that keeps
323
+ // throwing is a fault to surface, not a bill to pay.
324
+ throw err;
370
325
  }
371
326
  // The on-device runtime returned a result: the ONLY event that proves it is
372
- // alive. Counted here, past every throw and before any cloud path below, so
373
- // no cloud call can advance it.
327
+ // alive. Counted here, past every throw, so nothing but a real on-device
328
+ // inference can advance it.
374
329
  this.localInferencesCompleted += 1;
375
330
  // Connector-controlled provenance + time (don't trust the model for these).
376
331
  const capturedAtMs = Date.now();
@@ -379,48 +334,7 @@ class LocalSensingClient {
379
334
  // alert-worthy. Empty/uninteresting scenes send results only — no frame.
380
335
  // Evaluate over the raw model output (not the provenance-stamped `result`,
381
336
  // though both yield the same gate since source/captured_at are strings).
382
- const hasSignal = isAlertWorthy(structured);
383
- // ESCALATION: a candidate the local model flagged is adjudicated by the
384
- // cloud VLM BEFORE it can fire an alert. Same gate as the evidence frame,
385
- // so no frame leaves that would not already have left; the policy adds the
386
- // novelty/pacing/budget bounds. On success this frame's observation is the
387
- // CLOUD's — the local result is deliberately not also posted (one frame,
388
- // one observation).
389
- const canEscalate = this.escalationPolicy.isEnabled() && hasSignal;
390
- if (this.escalationPolicy.tryEscalate({
391
- hasSignal,
392
- // Only computed when the frame could actually escalate. This runs on
393
- // every frame of every camera and the common case — escalation off, or
394
- // an empty scene — needs no signature at all (tryEscalate rejects on
395
- // `disabled`/`no_signal` before it reads one).
396
- signature: canEscalate ? alertSignature(structured) : '',
397
- }).escalate) {
398
- try {
399
- const escalated = await this.uploadClient.analyze({
400
- jpeg: request.jpeg,
401
- capturedAt: capturedAtMs,
402
- captureMode: request.captureMode,
403
- ...frameDimensions,
404
- });
405
- // Rare by construction (bounded per feed per hour), so log every one:
406
- // an operator must be able to see each frame that left the premises.
407
- // eslint-disable-next-line no-console
408
- console.log(`[${this.feedName}] local candidate escalated to the cloud VLM for confirmation ` +
409
- `→ HTTP ${escalated.statusCode}${escalated.ok ? '' : ' (NOT OK)'}`);
410
- if (escalated.ok)
411
- return escalated;
412
- // A non-2xx cloud verdict is no verdict at all — fall through and ship
413
- // the local result rather than losing the observation.
414
- // eslint-disable-next-line no-console
415
- console.warn(`[${this.feedName}] cloud escalation returned HTTP ${escalated.statusCode} — ` +
416
- 'keeping the on-device verdict for this frame');
417
- }
418
- catch (err) {
419
- // eslint-disable-next-line no-console
420
- console.warn(`[${this.feedName}] cloud escalation failed (${err.message}) — ` +
421
- 'keeping the on-device verdict for this frame');
422
- }
423
- }
337
+ const hasSignal = isAlertWorthy(structured, this.cachedAbsenceWatchedFields);
424
338
  const result = {
425
339
  ...structured,
426
340
  source: 'vlm_edge',
@@ -463,11 +377,9 @@ function buildLocalSensingLoops(config, deps) {
463
377
  // Per-frame cloud fallback defaults OFF (opt-in) so the plain local-sense path
464
378
  // is unchanged. When true, a frame whose on-device inference throws is POSTed
465
379
  // to the cloud VLM (same upload client) rather than dropped.
466
- const cloudFallbackOnError = config.localSensing?.cloudFallbackOnError === true;
467
380
  // Cloud escalation defaults OFF. Each feed gets its OWN policy instance so the
468
381
  // per-camera budget is per camera (a shared one would let a busy feed spend a
469
382
  // quiet feed's confirmations).
470
- const cloudEscalation = config.localSensing?.cloudEscalation;
471
383
  const rtspFactory = deps?.rtspProviderFactory ??
472
384
  ((feed) => {
473
385
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -519,9 +431,6 @@ function buildLocalSensingLoops(config, deps) {
519
431
  client: new LocalSensingClient(localProviderFactory(feed), uploadClientFactory(feed), {
520
432
  profileClient: profileClientFactory(feed),
521
433
  attachEvidenceFrame,
522
- cloudFallbackOnError,
523
- feedName: feed.name,
524
- ...(cloudEscalation ? { cloudEscalation } : {}),
525
434
  }),
526
435
  }));
527
436
  }
@@ -1 +1 @@
1
- {"version":3,"file":"localSensing.js","sourceRoot":"","sources":["../src/localSensing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"localSensing.js","sourceRoot":"","sources":["../src/localSensing.ts"],"names":[],"mappings":"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"}