@camstack/addon-post-analysis 1.2.302 → 1.2.304
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/dist/{clip-model-registry-CQIBimj5.js → clip-model-registry--qJe8fTH.js} +60 -16
- package/dist/{clip-model-registry-BtY4fS3d.mjs → clip-model-registry-DBKCbXPJ.mjs} +55 -17
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DVMLLink.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-sLPWG5v8.mjs} +1 -1
- package/dist/pipeline-analytics/{_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-m9iqcykg.mjs → _virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CMq-UvYj.mjs} +1 -1
- package/dist/pipeline-analytics/{hostInit-DRjMNOyG.mjs → hostInit-D23-Tde_.mjs} +1 -1
- package/dist/pipeline-analytics/index.js +194 -23
- package/dist/pipeline-analytics/index.mjs +194 -23
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as NC_CLIP_RETENTION_MAX_SEC, $n as
|
|
1
|
+
import { $ as NC_CLIP_RETENTION_MAX_SEC, $n as storageOccupancyCapability, $t as TrackPuritySchema, A as EVENT_KIND_BY_CAP, An as isMediaOwnerType, Ar as number, B as MAX_ARCHIVED_DEBUG_NOTES, Bt as SCENE_DEFAULT_QUIET_SECONDS, C as DETECTION_PIPELINE_CAP_NAME, Cn as failureContributionCapability, Ct as NcSystemEventKindSchema, D as EMBEDDING_REQUIREMENTS_FAILED, Dn as isDetectionMacroClass, Dr as boolean, Dt as NcTemplateVarDescriptorSchema, E as EMBEDDING_MODEL_FAILED, En as isAudioClassName, Er as array, Et as NcTemplatePreviewSchema, F as FailureCounters, Fn as kebabToCamel, Fr as string, Ft as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, G as MOTION_CLOSE_AFTER_MS, Gn as readTimelapseGeneratedAt, Gt as SetTrackPurityInputSchema, H as MAX_BIRTH_LATENCY_PROXY_MS, Hn as plateGalleryCapability, Ht as SCENE_DIVERGED, I as LabelAttributionSchema, In as mayWriteToLocation, Ir as tuple, It as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, J as NC_ALARM_SYSTEM_EVENT_KINDS, Jt as TIMELAPSE_DENSE_FLOOR_SEC, K as MediaFileKindEnum, Kn as resolveClipSearchMinScore, Kt as SetTrackPurityResultSchema, L as ListTrackRelationsInputSchema, Ln as memoizePinnedFfmpeg, Lr as union, Lt as SCENE_DEFAULT_ANCHOR_THRESHOLD, M as EXPORT_DENSE_MAX_RANGES, Mn as isSystemDelivery, Mr as partialRecord, Mt as RECORDING_SOURCE_CAMSTACK_ADDON, N as FIRST_LEVEL_MACRO_CLASSES, Nn as isSystemEventSummaryRule, Nr as record, Nt as RebuildObjectEmbeddingsRefusalSchema, O as EMBEDDING_REQUIREMENTS_UNAVAILABLE, On as isEventOwnerType, Or as discriminatedUnion, Ot as OPS_LOG_DEFAULT_LIMIT, P as FULL_IMAGE_BBOX, Pn as isVectorIndexDimConflict, Pr as strictObject, Pt as RetrainStatusSchema, Q as NC_CLIP_PRE_ROLL_DEFAULT_SEC, Qn as servedTemplateVars, Qt as TimelapseRuleSchema, R as ListTrackRelationsResultSchema, Rn as notificationRulesCapability, Rr as unknown, Rt as SCENE_DEFAULT_CHECK_INTERVAL_SEC, S as DETECTION_MACRO_CLASSES, Sn as faceGalleryCapability, Sr as nodePin, St as NcSnoozeSuppressedSchema, T as DetectionSourceSchema, Tn as gifFromMp4Args, Tr as _enum, Tt as NcTemplatePreviewInputSchema, U as MAX_TRACK_PURITIES, Un as readDeviceStateFrom, Ut as SCENE_RESET_RECAPTURES, V as MAX_BIRTH_DECISION_RECORDS, Vn as pipelineAnalyticsCapability, Vt as SCENE_DEFAULT_UNCOVERED_POLICY, W as MAX_TRACK_RELATIONS, Wn as readMotionTriggeredBy, Wt as SceneMonitorSchema, X as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, Xn as sceneMonitorCapability, Xt as TimelapseRuleInputSchema, Y as NC_AUDIO_CONFIRM_HITS_DEFAULT, Yn as ruleBelongsToAlarm$1, Yt as TRACK_RELATIONS_DEFAULT_LIMIT, Z as NC_CLIP_POST_ROLL_DEFAULT_SEC, Zn as sensorRaisedOf, Zt as TimelapseRulePatchSchema, _ as ClearTrackRelationInputSchema, _n as embeddingRefusalOf, _r as createEvent, _t as NcRuleTargetSchema, a as CLIP_EMBEDDING_STEP_ID, an as alarmPanelCapability, ar as templateCarriesSummary, at as NC_SNOOZE_MAX_MINUTES, b as DEFAULT_EVENT_COLOR, bn as encodeVectorBase64, br as hydrateSchema, bt as NcSnoozeInputSchema, c as resolveClusterModelPin, cn as audioModeOf, cr as zoneAnalyticsCapability, ct as NC_TAXONOMY, d as AlarmArmModeSchema, dn as cosineSimilarity$1, dr as evaluateSensorEdge, dt as NcAlarmSettingsPatchSchema, en as TrackRelationKindSchema, er as subKindsOf, et as NC_CONDITION_CATALOG, f as ArchivedDebugNoteSchema, fn as deriveRecordingMode, fr as isSourceCap, ft as NcConditionDescriptorSchema, g as COCO_TO_MACRO, gr as CamProfileSchema, gt as NcRuleSchema, h as BirthDecisionRecordSchema, hr as BaseAddon, ht as NcRulePatchSchema, in as addonWidgetsSourceCapability, ir as systemEventSummaryScheduleOf, it as NC_SENSOR_TRANSITION_KINDS, j as EVENT_OWNER_TYPES, jn as isScheduleActive, jr as object, jt as RECORDING_EXPORT_MAX_READ_BYTES, k as EVENT_DENSITY_BATCH_MAX, kn as isKnownTemplateVar, kr as literal, kt as OpsLogEntrySchema, l as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, ln as buildEventKindDescriptor, lr as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, lt as NC_TEMPLATE_VARS, m as BaseDevice, mn as describeSystemEventFamilyProblem, mr as errMsg, mt as NcRuleInputSchema, nn as TrackSideSchema, nr as systemEventFamilyProblems, nt as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, o as FACE_EMBEDDING_STEP_ID, on as assertTimelapseCadences, or as templateVarsFor, ot as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, p as BIRTH_DECISION_DEFAULT_LIMIT, pn as describeSystemEventDeliveryProblem, pr as DeviceType, pt as NcConditionsSchema, q as MotionTriggeredBySchema, qn as resolveLocationMode, qt as SetTrackRelationInputSchema, rn as TrackSourceSchema, rr as systemEventFilterApplies, rt as NC_DEFAULT_SNOOZE_MINUTES, s as readClusterModelPinStrict, sn as audioMetricsCapability, sr as vectorDimFromBase64, st as NC_TANK_SYSTEM_EVENT_KINDS, t as BUILTIN_CLIP_MODELS, tn as TrackRelationSchema, tr as systemEventDeliveryProblems, tt as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, u as AUDIO_MACRO_LABELS, un as consumableLowPercentOf, ur as canonicalHash, ut as NcAlarmConfigSchema, v as ClearTrackRelationResultSchema, vr as customAction, vt as NcRuleUpdateInputSchema, w as DeclaredDevices, wn as gifDeriveSpeed, wr as sleep$1, wt as NcTaxonomySchema, x as DEFAULT_TIMELAPSE_PREVIEW_TEXT, xn as evictionPolicyOfLocation, xr as isDeviceScopedCap, xt as NcSnoozeSchema, y as CoverStateSchema, yr as defineCustomActions, yt as NcScheduleSchema, z as LockStateSchema, zn as occupancyScope, zr as EventCategory, zt as SCENE_DEFAULT_OBSERVATION_SPACING_SEC } from "../clip-model-registry-DBKCbXPJ.mjs";
|
|
2
2
|
import { t as __exportAll } from "../embedding-encoder/index.mjs";
|
|
3
3
|
import * as fs$1 from "node:fs";
|
|
4
4
|
import { createWriteStream, promises } from "node:fs";
|
|
@@ -14201,11 +14201,26 @@ function sortedSystemEvent(condition) {
|
|
|
14201
14201
|
...packageNames !== void 0 ? { packageNames: packageNames.toSorted(byValue) } : {}
|
|
14202
14202
|
};
|
|
14203
14203
|
}
|
|
14204
|
+
/**
|
|
14205
|
+
* `zones` with its redundant quantifier dropped: `match: 'any'` says exactly
|
|
14206
|
+
* what an absent `match` says (D690 — the editors write `{ ids }`, the store
|
|
14207
|
+
* still holds `match: 'any'` on every rule written before). `'all'` is kept:
|
|
14208
|
+
* it IS a different rule.
|
|
14209
|
+
*/
|
|
14210
|
+
function canonicalZones(conditions) {
|
|
14211
|
+
const zones = conditions.zones;
|
|
14212
|
+
if (zones?.match !== "any") return conditions;
|
|
14213
|
+
return {
|
|
14214
|
+
...conditions,
|
|
14215
|
+
zones: { ids: zones.ids }
|
|
14216
|
+
};
|
|
14217
|
+
}
|
|
14204
14218
|
/** The canonical form two conditions are compared in. */
|
|
14205
14219
|
function conditionsFingerprint(conditions) {
|
|
14206
|
-
const
|
|
14207
|
-
|
|
14208
|
-
|
|
14220
|
+
const canonical = canonicalZones(conditions);
|
|
14221
|
+
const { systemEvent } = canonical;
|
|
14222
|
+
return canonicalHash(systemEvent === void 0 ? canonical : {
|
|
14223
|
+
...canonical,
|
|
14209
14224
|
systemEvent: sortedSystemEvent(systemEvent)
|
|
14210
14225
|
});
|
|
14211
14226
|
}
|
|
@@ -14214,7 +14229,8 @@ function conditionsFingerprint(conditions) {
|
|
|
14214
14229
|
* (the normalisation the store applies on every write) and are compared
|
|
14215
14230
|
* canonically: key order is irrelevant, an `undefined` key equals an absent
|
|
14216
14231
|
* one, and the system-event `kinds` and id-list filters are compared as SETS.
|
|
14217
|
-
* Every other array keeps its order
|
|
14232
|
+
* Every other array keeps its order, and `zones.match: 'any'` equals an absent
|
|
14233
|
+
* `match`. A side that does not parse is treated as
|
|
14218
14234
|
* a change, so it is judged rather than waved through.
|
|
14219
14235
|
*/
|
|
14220
14236
|
function sameConditions(a, b) {
|
|
@@ -14259,7 +14275,7 @@ function assertPatchKeepsFamily(existing, patch) {
|
|
|
14259
14275
|
* the offending kind or filter). Then rethrow. A refused save is dropped work,
|
|
14260
14276
|
* and dropped work is never silent. Any other error passes through unlogged.
|
|
14261
14277
|
*/
|
|
14262
|
-
function logRefusal$
|
|
14278
|
+
function logRefusal$4(check, ctx) {
|
|
14263
14279
|
try {
|
|
14264
14280
|
check();
|
|
14265
14281
|
} catch (err) {
|
|
@@ -14275,11 +14291,11 @@ function logRefusal$3(check, ctx) {
|
|
|
14275
14291
|
}
|
|
14276
14292
|
/** {@link assertRuleFamily}, logged. The create path of both routes. */
|
|
14277
14293
|
function guardRuleFamily(rule, ctx) {
|
|
14278
|
-
logRefusal$
|
|
14294
|
+
logRefusal$4(() => assertRuleFamily(rule), ctx);
|
|
14279
14295
|
}
|
|
14280
14296
|
/** {@link assertPatchKeepsFamily}, logged. The update path of both routes. */
|
|
14281
14297
|
function guardPatchFamily(existing, patch, ctx) {
|
|
14282
|
-
logRefusal$
|
|
14298
|
+
logRefusal$4(() => assertPatchKeepsFamily(existing, patch), ctx);
|
|
14283
14299
|
}
|
|
14284
14300
|
//#endregion
|
|
14285
14301
|
//#region src/notification-center/device-scope-guard.ts
|
|
@@ -14304,15 +14320,15 @@ function assertDevicesExcludeDelivery(rule) {
|
|
|
14304
14320
|
throw new NcDevicesExcludeRefusal(rule.delivery, excluded);
|
|
14305
14321
|
}
|
|
14306
14322
|
/** Run the check; a refusal is dropped work, so it is logged before it is rethrown. */
|
|
14307
|
-
function logRefusal$
|
|
14323
|
+
function logRefusal$3(check, ctx) {
|
|
14308
14324
|
try {
|
|
14309
14325
|
check();
|
|
14310
14326
|
} catch (err) {
|
|
14311
|
-
if (err instanceof NcDevicesExcludeRefusal) warnRefusal$
|
|
14327
|
+
if (err instanceof NcDevicesExcludeRefusal) warnRefusal$2(ctx.logger, err, ctx);
|
|
14312
14328
|
throw err;
|
|
14313
14329
|
}
|
|
14314
14330
|
}
|
|
14315
|
-
function warnRefusal$
|
|
14331
|
+
function warnRefusal$2(logger, err, ctx) {
|
|
14316
14332
|
logger.warn("nc rule refused: devicesExclude on a system rule", { meta: {
|
|
14317
14333
|
...ctx.ruleId !== void 0 ? { ruleId: ctx.ruleId } : {},
|
|
14318
14334
|
by: ctx.by,
|
|
@@ -14322,7 +14338,7 @@ function warnRefusal$1(logger, err, ctx) {
|
|
|
14322
14338
|
}
|
|
14323
14339
|
/** The create path of both routes. */
|
|
14324
14340
|
function guardRuleDevicesExclude(rule, ctx) {
|
|
14325
|
-
logRefusal$
|
|
14341
|
+
logRefusal$3(() => assertDevicesExcludeDelivery(rule), ctx);
|
|
14326
14342
|
}
|
|
14327
14343
|
/**
|
|
14328
14344
|
* The update path of both routes: the MERGED rule is judged, and only when the
|
|
@@ -14332,7 +14348,7 @@ function guardPatchDevicesExclude(existing, patch, ctx) {
|
|
|
14332
14348
|
if (existing === null) return;
|
|
14333
14349
|
const merged = mergedFamilySubject(existing, patch);
|
|
14334
14350
|
if (merged === null) return;
|
|
14335
|
-
logRefusal$
|
|
14351
|
+
logRefusal$3(() => assertDevicesExcludeDelivery(merged), ctx);
|
|
14336
14352
|
}
|
|
14337
14353
|
//#endregion
|
|
14338
14354
|
//#region src/notification-center/rule-summary-guard.ts
|
|
@@ -14390,7 +14406,7 @@ function mergedDeliverySubject(existing, patch, clear) {
|
|
|
14390
14406
|
};
|
|
14391
14407
|
return JUDGED_KEYS.some((key) => canonicalHash(merged[key] ?? null) !== canonicalHash(existing[key] ?? null)) ? merged : null;
|
|
14392
14408
|
}
|
|
14393
|
-
function logRefusal$
|
|
14409
|
+
function logRefusal$2(check, ctx) {
|
|
14394
14410
|
try {
|
|
14395
14411
|
check();
|
|
14396
14412
|
} catch (err) {
|
|
@@ -14404,14 +14420,14 @@ function logRefusal$1(check, ctx) {
|
|
|
14404
14420
|
}
|
|
14405
14421
|
/** The create path of both routes. */
|
|
14406
14422
|
function guardRuleSystemEventDelivery(rule, ctx) {
|
|
14407
|
-
logRefusal$
|
|
14423
|
+
logRefusal$2(() => assertSystemEventDelivery(rule), ctx);
|
|
14408
14424
|
}
|
|
14409
14425
|
/** The update path of both routes: the MERGED rule, when the patch changes what is judged. */
|
|
14410
14426
|
function guardPatchSystemEventDelivery(existing, patch, clear, ctx) {
|
|
14411
14427
|
if (existing === null) return;
|
|
14412
14428
|
const merged = mergedDeliverySubject(existing, patch, clear);
|
|
14413
14429
|
if (merged === null) return;
|
|
14414
|
-
logRefusal$
|
|
14430
|
+
logRefusal$2(() => assertSystemEventDelivery(merged), ctx);
|
|
14415
14431
|
}
|
|
14416
14432
|
//#endregion
|
|
14417
14433
|
//#region src/notification-center/sensor-transition-guard.ts
|
|
@@ -14433,15 +14449,15 @@ function assertSensorTransitionDelivery(rule) {
|
|
|
14433
14449
|
throw new NcSensorTransitionRefusal(rule.delivery, transition);
|
|
14434
14450
|
}
|
|
14435
14451
|
/** Run the check; a refusal is dropped work, so it is logged before it is rethrown. */
|
|
14436
|
-
function logRefusal(check, ctx) {
|
|
14452
|
+
function logRefusal$1(check, ctx) {
|
|
14437
14453
|
try {
|
|
14438
14454
|
check();
|
|
14439
14455
|
} catch (err) {
|
|
14440
|
-
if (err instanceof NcSensorTransitionRefusal) warnRefusal(ctx.logger, err, ctx);
|
|
14456
|
+
if (err instanceof NcSensorTransitionRefusal) warnRefusal$1(ctx.logger, err, ctx);
|
|
14441
14457
|
throw err;
|
|
14442
14458
|
}
|
|
14443
14459
|
}
|
|
14444
|
-
function warnRefusal(logger, err, ctx) {
|
|
14460
|
+
function warnRefusal$1(logger, err, ctx) {
|
|
14445
14461
|
logger.warn("nc rule refused: sensorTransition off a device-event rule", { meta: {
|
|
14446
14462
|
...ctx.ruleId !== void 0 ? { ruleId: ctx.ruleId } : {},
|
|
14447
14463
|
by: ctx.by,
|
|
@@ -14451,7 +14467,7 @@ function warnRefusal(logger, err, ctx) {
|
|
|
14451
14467
|
}
|
|
14452
14468
|
/** The create path of both routes. */
|
|
14453
14469
|
function guardRuleSensorTransition(rule, ctx) {
|
|
14454
|
-
logRefusal(() => assertSensorTransitionDelivery(rule), ctx);
|
|
14470
|
+
logRefusal$1(() => assertSensorTransitionDelivery(rule), ctx);
|
|
14455
14471
|
}
|
|
14456
14472
|
/**
|
|
14457
14473
|
* The update path of both routes: the MERGED rule is judged, and only when the
|
|
@@ -14462,7 +14478,92 @@ function guardPatchSensorTransition(existing, patch, ctx) {
|
|
|
14462
14478
|
if (existing === null) return;
|
|
14463
14479
|
const merged = mergedFamilySubject(existing, patch);
|
|
14464
14480
|
if (merged === null) return;
|
|
14465
|
-
logRefusal(() => assertSensorTransitionDelivery(merged), ctx);
|
|
14481
|
+
logRefusal$1(() => assertSensorTransitionDelivery(merged), ctx);
|
|
14482
|
+
}
|
|
14483
|
+
//#endregion
|
|
14484
|
+
//#region src/notification-center/detection-audio-guard.ts
|
|
14485
|
+
var NcDetectionAudioRefusal = class extends Error {
|
|
14486
|
+
audioClasses;
|
|
14487
|
+
constructor(audioClasses) {
|
|
14488
|
+
super(`rule refused: a detection rule cannot name sounds (${audioClasses.join(", ")}) — create a Sound rule for them`);
|
|
14489
|
+
this.name = "NcDetectionAudioRefusal";
|
|
14490
|
+
this.audioClasses = audioClasses;
|
|
14491
|
+
}
|
|
14492
|
+
};
|
|
14493
|
+
/**
|
|
14494
|
+
* The audio classes a DETECTION rule carries (include and exclude), in stored
|
|
14495
|
+
* order. Empty for a Sound rule (its `audio` condition owns its sounds) and for
|
|
14496
|
+
* a system rule (it has no class scope).
|
|
14497
|
+
*/
|
|
14498
|
+
function audioClassesOnDetectionRule(rule) {
|
|
14499
|
+
if (isSystemDelivery(rule.delivery)) return [];
|
|
14500
|
+
if (rule.conditions.audio !== void 0) return [];
|
|
14501
|
+
return [...rule.conditions.classes ?? [], ...rule.conditions.classesExclude ?? []].filter(isAudioClassName);
|
|
14502
|
+
}
|
|
14503
|
+
function assertNoAudioClassOnDetectionRule(rule) {
|
|
14504
|
+
const audioClasses = audioClassesOnDetectionRule(rule);
|
|
14505
|
+
if (audioClasses.length > 0) throw new NcDetectionAudioRefusal(audioClasses);
|
|
14506
|
+
}
|
|
14507
|
+
/** Run the check; a refusal is dropped work, so it is logged before it is rethrown. */
|
|
14508
|
+
function logRefusal(check, ctx) {
|
|
14509
|
+
try {
|
|
14510
|
+
check();
|
|
14511
|
+
} catch (err) {
|
|
14512
|
+
if (err instanceof NcDetectionAudioRefusal) warnRefusal(ctx.logger, err, ctx);
|
|
14513
|
+
throw err;
|
|
14514
|
+
}
|
|
14515
|
+
}
|
|
14516
|
+
function warnRefusal(logger, err, ctx) {
|
|
14517
|
+
logger.warn("nc rule refused: a detection rule names sounds", { meta: {
|
|
14518
|
+
...ctx.ruleId !== void 0 ? { ruleId: ctx.ruleId } : {},
|
|
14519
|
+
by: ctx.by,
|
|
14520
|
+
audioClasses: err.audioClasses.join(", ")
|
|
14521
|
+
} });
|
|
14522
|
+
}
|
|
14523
|
+
/** The create path of both routes. */
|
|
14524
|
+
function guardRuleDetectionAudio(rule, ctx) {
|
|
14525
|
+
logRefusal(() => assertNoAudioClassOnDetectionRule(rule), ctx);
|
|
14526
|
+
}
|
|
14527
|
+
/**
|
|
14528
|
+
* The update path of both routes: the MERGED rule, only when the patch changes
|
|
14529
|
+
* it — and only the sounds the save ADDS. A legacy rule that already names a
|
|
14530
|
+
* sound stays editable (a threshold, a schedule, a zone); what is refused is
|
|
14531
|
+
* naming a new one.
|
|
14532
|
+
*/
|
|
14533
|
+
function guardPatchDetectionAudio(existing, patch, ctx) {
|
|
14534
|
+
if (existing === null) return;
|
|
14535
|
+
const merged = mergedFamilySubject(existing, patch);
|
|
14536
|
+
if (merged === null) return;
|
|
14537
|
+
const stored = new Set(audioClassesOnDetectionRule(existing).map(normalisedClass));
|
|
14538
|
+
const added = audioClassesOnDetectionRule(merged).filter((name) => !stored.has(normalisedClass(name)));
|
|
14539
|
+
if (added.length === 0) return;
|
|
14540
|
+
logRefusal(() => {
|
|
14541
|
+
throw new NcDetectionAudioRefusal(added);
|
|
14542
|
+
}, ctx);
|
|
14543
|
+
}
|
|
14544
|
+
function normalisedClass(name) {
|
|
14545
|
+
return name.trim().toLowerCase();
|
|
14546
|
+
}
|
|
14547
|
+
/**
|
|
14548
|
+
* The loader's half: every stored detection rule that names a sound is KEPT
|
|
14549
|
+
* (it loads and fires as it always did) and reported at WARN with its id —
|
|
14550
|
+
* once per rule per process, never on every reload tick. Returns the ids it
|
|
14551
|
+
* reported this time, for the caller's bookkeeping.
|
|
14552
|
+
*/
|
|
14553
|
+
function warnLegacyAudioClassRules(rules, alreadyWarned, logger) {
|
|
14554
|
+
const reported = [];
|
|
14555
|
+
for (const rule of rules) {
|
|
14556
|
+
if (alreadyWarned.has(rule.id)) continue;
|
|
14557
|
+
const audioClasses = audioClassesOnDetectionRule(rule);
|
|
14558
|
+
if (audioClasses.length === 0) continue;
|
|
14559
|
+
logger.warn("notification rule is a detection rule naming sounds — kept as it is; recreate it as a Sound rule", { meta: {
|
|
14560
|
+
ruleId: rule.id,
|
|
14561
|
+
name: rule.name,
|
|
14562
|
+
audioClasses: audioClasses.join(", ")
|
|
14563
|
+
} });
|
|
14564
|
+
reported.push(rule.id);
|
|
14565
|
+
}
|
|
14566
|
+
return reported;
|
|
14466
14567
|
}
|
|
14467
14568
|
//#endregion
|
|
14468
14569
|
//#region src/notification-center/occupancy-watcher.ts
|
|
@@ -17198,6 +17299,10 @@ function makeNcActionHandlers(deps) {
|
|
|
17198
17299
|
logger: deps.logger,
|
|
17199
17300
|
by: c.userId
|
|
17200
17301
|
});
|
|
17302
|
+
guardRuleDetectionAudio(parsed, {
|
|
17303
|
+
logger: deps.logger,
|
|
17304
|
+
by: c.userId
|
|
17305
|
+
});
|
|
17201
17306
|
guardRuleDevicesExclude(parsed, {
|
|
17202
17307
|
logger: deps.logger,
|
|
17203
17308
|
by: c.userId
|
|
@@ -17234,6 +17339,11 @@ function makeNcActionHandlers(deps) {
|
|
|
17234
17339
|
by: c.userId,
|
|
17235
17340
|
ruleId: input.ruleId
|
|
17236
17341
|
});
|
|
17342
|
+
guardPatchDetectionAudio(existing, patch, {
|
|
17343
|
+
logger: deps.logger,
|
|
17344
|
+
by: c.userId,
|
|
17345
|
+
ruleId: input.ruleId
|
|
17346
|
+
});
|
|
17237
17347
|
guardPatchDevicesExclude(existing, patch, {
|
|
17238
17348
|
logger: deps.logger,
|
|
17239
17349
|
by: c.userId,
|
|
@@ -25397,6 +25507,8 @@ var NcRuleStore = class {
|
|
|
25397
25507
|
identityIdsByName;
|
|
25398
25508
|
/** Has a {@link load} ever completed? See the note there. */
|
|
25399
25509
|
loaded = false;
|
|
25510
|
+
/** Legacy detection rules naming sounds already reported (D690) — once each. */
|
|
25511
|
+
audioClassWarned = /* @__PURE__ */ new Set();
|
|
25400
25512
|
constructor(deps) {
|
|
25401
25513
|
this.store = deps.store;
|
|
25402
25514
|
this.ledger = new DurableLedger({
|
|
@@ -25431,6 +25543,7 @@ var NcRuleStore = class {
|
|
|
25431
25543
|
async load() {
|
|
25432
25544
|
await this.ledger.load();
|
|
25433
25545
|
if (this.ledger.hasAnswered()) this.loaded = true;
|
|
25546
|
+
for (const id of warnLegacyAudioClassRules(this.ledger.snapshot(), this.audioClassWarned, this.logger)) this.audioClassWarned.add(id);
|
|
25434
25547
|
this.logger.debug("notification rules loaded", { meta: { rules: this.ledger.size } });
|
|
25435
25548
|
}
|
|
25436
25549
|
/**
|
|
@@ -33662,6 +33775,10 @@ var NotificationCenter = class NotificationCenter {
|
|
|
33662
33775
|
logger: this.logger,
|
|
33663
33776
|
by: caller.userId
|
|
33664
33777
|
});
|
|
33778
|
+
guardRuleDetectionAudio(rule, {
|
|
33779
|
+
logger: this.logger,
|
|
33780
|
+
by: caller.userId
|
|
33781
|
+
});
|
|
33665
33782
|
guardRuleDevicesExclude(rule, {
|
|
33666
33783
|
logger: this.logger,
|
|
33667
33784
|
by: caller.userId
|
|
@@ -33693,6 +33810,11 @@ var NotificationCenter = class NotificationCenter {
|
|
|
33693
33810
|
by: caller.userId,
|
|
33694
33811
|
ruleId
|
|
33695
33812
|
});
|
|
33813
|
+
guardPatchDetectionAudio(existing, patch, {
|
|
33814
|
+
logger: this.logger,
|
|
33815
|
+
by: caller.userId,
|
|
33816
|
+
ruleId
|
|
33817
|
+
});
|
|
33696
33818
|
guardPatchDevicesExclude(existing, patch, {
|
|
33697
33819
|
logger: this.logger,
|
|
33698
33820
|
by: caller.userId,
|
|
@@ -67228,6 +67350,22 @@ function messageOf(err) {
|
|
|
67228
67350
|
function isDetailNotAttachedRefusal(err) {
|
|
67229
67351
|
return messageOf(err).includes(DETAIL_NOT_ATTACHED_MARKER);
|
|
67230
67352
|
}
|
|
67353
|
+
/**
|
|
67354
|
+
* The runner's TYPED handle-expired refusal (D688): the frame handle a dispatch
|
|
67355
|
+
* named is past the native lease age bound, and the registry will refuse it on
|
|
67356
|
+
* every later ask. TWIN of `addon-pipeline/src/pipeline-runner/detail-park.ts`
|
|
67357
|
+
* `DETAIL_HANDLE_EXPIRED_MARKER` — keep the two identical.
|
|
67358
|
+
*
|
|
67359
|
+
* Why the dispatcher cares: unlike not-attached this is about ONE handle, not
|
|
67360
|
+
* the session — the parked frame still serves — but the handle itself is
|
|
67361
|
+
* finished. Naming it again (next tick, or through the native-strict crop rung)
|
|
67362
|
+
* can only be refused again; on the live fleet that was ~7 refusals per handle.
|
|
67363
|
+
*/
|
|
67364
|
+
var DETAIL_HANDLE_EXPIRED_MARKER = "runDetailSubtree-refused:handle-expired";
|
|
67365
|
+
/** Did this `runDetailSubtree` error carry the runner's handle-expired marker? */
|
|
67366
|
+
function isDetailHandleExpiredRefusal(err) {
|
|
67367
|
+
return messageOf(err).includes(DETAIL_HANDLE_EXPIRED_MARKER);
|
|
67368
|
+
}
|
|
67231
67369
|
//#endregion
|
|
67232
67370
|
//#region src/pipeline-analytics/detail-scheduler.ts
|
|
67233
67371
|
/** Default backoff/period when a step's cadence omits `minIntervalMs`. */
|
|
@@ -67684,6 +67822,7 @@ var TrackDetailDispatcher = class {
|
|
|
67684
67822
|
className: frame.className
|
|
67685
67823
|
};
|
|
67686
67824
|
const steps = composeDetailSteps(req, (trackId) => this.deps.hasTrackLabel?.(trackId) ?? false);
|
|
67825
|
+
let handleRefused = false;
|
|
67687
67826
|
if (frame.frameHandle !== void 0) try {
|
|
67688
67827
|
const primary = await this.deps.runDetailSubtree({
|
|
67689
67828
|
deviceId,
|
|
@@ -67697,7 +67836,10 @@ var TrackDetailDispatcher = class {
|
|
|
67697
67836
|
this.warnNotAttachedThrottled(deviceId, dev, req);
|
|
67698
67837
|
return null;
|
|
67699
67838
|
}
|
|
67700
|
-
|
|
67839
|
+
if (isDetailHandleExpiredRefusal(err)) {
|
|
67840
|
+
handleRefused = true;
|
|
67841
|
+
this.retireRefusedHandle(deviceId, dev, req, frame);
|
|
67842
|
+
} else this.deps.logger.debug("detail primary call failed — trying frame fallback", {
|
|
67701
67843
|
tags: { deviceId },
|
|
67702
67844
|
meta: {
|
|
67703
67845
|
trackId: req.trackId,
|
|
@@ -67747,7 +67889,7 @@ var TrackDetailDispatcher = class {
|
|
|
67747
67889
|
}
|
|
67748
67890
|
});
|
|
67749
67891
|
}
|
|
67750
|
-
if (this.deps.captureCropBase64 !== void 0) try {
|
|
67892
|
+
if (this.deps.captureCropBase64 !== void 0 && frame.frameHandle !== void 0 && !handleRefused) try {
|
|
67751
67893
|
const cropJpeg = await this.deps.captureCropBase64(frame);
|
|
67752
67894
|
if (cropJpeg !== null) {
|
|
67753
67895
|
const retry = await this.deps.runDetailSubtree({
|
|
@@ -67776,6 +67918,35 @@ var TrackDetailDispatcher = class {
|
|
|
67776
67918
|
return null;
|
|
67777
67919
|
}
|
|
67778
67920
|
/**
|
|
67921
|
+
* The runner refused `frame`'s handle as past the lease age bound (D688).
|
|
67922
|
+
* That verdict is final for the handle, so the track's stored association
|
|
67923
|
+
* loses it: later dispatches skip rung 1 and the native-strict crop rung
|
|
67924
|
+
* (both would name the same handle and be refused again — ~7 times per
|
|
67925
|
+
* handle on the live fleet) and go straight to the parked frame, until a
|
|
67926
|
+
* newly OBSERVED frame brings a fresh handle via {@link onFrame}.
|
|
67927
|
+
*
|
|
67928
|
+
* Only the refused handle is dropped: if a newer frame replaced it while the
|
|
67929
|
+
* dispatch was in flight, that one stands. The line is therefore emitted once
|
|
67930
|
+
* per (track, handle) — a concurrent dispatch refused on the same handle
|
|
67931
|
+
* finds it already gone and says nothing.
|
|
67932
|
+
*/
|
|
67933
|
+
retireRefusedHandle(deviceId, dev, req, frame) {
|
|
67934
|
+
const current = dev.tracks.get(req.trackId);
|
|
67935
|
+
if (current === void 0 || current.frameHandle !== frame.frameHandle) return;
|
|
67936
|
+
const { frameHandle: refused, ...withoutHandle } = current;
|
|
67937
|
+
dev.tracks.set(req.trackId, withoutHandle);
|
|
67938
|
+
this.deps.logger.info("detail dispatch: frame handle refused as expired — retired for this track, parked frame only until a fresh observation", {
|
|
67939
|
+
tags: { deviceId },
|
|
67940
|
+
meta: {
|
|
67941
|
+
trackId: req.trackId,
|
|
67942
|
+
stepId: req.stepId,
|
|
67943
|
+
reason: "handle-expired",
|
|
67944
|
+
handle: refused === void 0 ? null : `${refused.shmId}#${refused.slot}#${refused.seq}`,
|
|
67945
|
+
parkedFrameRung: this.deps.captureParkedFrame !== void 0
|
|
67946
|
+
}
|
|
67947
|
+
});
|
|
67948
|
+
}
|
|
67949
|
+
/**
|
|
67779
67950
|
* The typed refusal is EXPECTED for a track that outlives the runner's
|
|
67780
67951
|
* detail park grace (a closing track's last dispatches), so it logs its own
|
|
67781
67952
|
* line — the reason is knowable, unlike the every-rung-missed warn — and
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-sLPWG5v8.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-post-analysis",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.304",
|
|
4
4
|
"description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|