@camstack/types 1.2.99 → 1.2.101

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_event_category = require("./event-category-EY0GNjV9.js");
3
- const require_sleep = require("./sleep-C2XhJhkd.js");
3
+ const require_sleep = require("./sleep-BwXldPpA.js");
4
4
  const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -2605,6 +2605,32 @@ var ModelVariantGroupSchema = zod.z.object({
2605
2605
  */
2606
2606
  resolution: zod.z.number().int().positive().optional()
2607
2607
  });
2608
+ /**
2609
+ * Where a catalog entry came from. The pipeline stepper partitions the picker
2610
+ * by this id (CamStack / Frigate / Scrypted / Custom). Absent on older durable
2611
+ * registry rows — {@link inferModelProvider} fills it at read time. Built-in
2612
+ * catalog entries omit it and `getSchema` treats them as `camstack`.
2613
+ */
2614
+ var MODEL_PROVIDER_IDS = [
2615
+ "camstack",
2616
+ "frigate",
2617
+ "scrypted",
2618
+ "custom"
2619
+ ];
2620
+ var ModelProviderIdSchema = zod.z.enum(MODEL_PROVIDER_IDS);
2621
+ /**
2622
+ * Resolve a catalog entry's picker provider. An explicit stamp always wins;
2623
+ * otherwise Frigate/Scrypted are recognised from id prefix or description.
2624
+ * Unstamped BYO registry rows fall through to `custom`. Family `yolov9` is
2625
+ * NOT a Scrypted signal — CamStack ships that family too.
2626
+ */
2627
+ function inferModelProvider(entry) {
2628
+ if (entry.provider !== void 0) return entry.provider;
2629
+ const haystack = `${entry.id} ${entry.description ?? ""}`;
2630
+ if (/scrypted/i.test(haystack)) return "scrypted";
2631
+ if (/frigate/i.test(haystack)) return "frigate";
2632
+ return "custom";
2633
+ }
2608
2634
  var ModelCatalogEntrySchema = zod.z.object({
2609
2635
  id: zod.z.string(),
2610
2636
  name: zod.z.string(),
@@ -2702,6 +2728,12 @@ var ModelCatalogEntrySchema = zod.z.object({
2702
2728
  */
2703
2729
  group: ModelVariantGroupSchema.optional(),
2704
2730
  /**
2731
+ * Catalog source for the pipeline stepper's provider-first picker. Absent on
2732
+ * built-in CamStack entries (treated as `camstack`) and on registry rows
2733
+ * persisted before this field existed (`inferModelProvider` fills those).
2734
+ */
2735
+ provider: ModelProviderIdSchema.optional(),
2736
+ /**
2705
2737
  * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
2706
2738
  * applies (Frigate / COCO public catalog). Set on a custom model whose raw
2707
2739
  * labels already ARE the CamStack macros (Scrypted identity map).
@@ -12453,12 +12485,15 @@ var NC_AUDIO_DBFS_FLOOR = -96;
12453
12485
  * there is no second switch that can disagree with the first and every rule
12454
12486
  * authored before the decision migrates for free (`audioModeOf`):
12455
12487
  *
12456
- * - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
12457
- * classifier labels with one of them. No window, no percentage:
12458
- * `hitPercent` and `samplingSeconds` are ignored, and the rule's own
12459
- * `throttle` cooldown is the only brake. The per-label confidence floor is
12460
- * the analyzer's (`classificationMinScore`, per device) a label only
12461
- * reaches this condition if the classifier was already confident enough.
12488
+ * - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
12489
+ * labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
12490
+ * `hitPercent` and `samplingSeconds` are still ignored a percentage of
12491
+ * frames is the wrong question for a classifier that labels 1–3 frames
12492
+ * per episode. The count window is the brake that drops a single-frame
12493
+ * false positive; the rule's own `throttle` cooldown is the other. The
12494
+ * per-label confidence floor is the analyzer's (`classificationMinScore`,
12495
+ * per device) — a label only reaches this condition if the classifier was
12496
+ * already confident enough. `confirmHits: 1` restores first-frame fire.
12462
12497
  * - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
12463
12498
  * the condition: at least `hitPercent`% of the samples over
12464
12499
  * `samplingSeconds` must be at or above `dbThreshold` dBFS (see
@@ -12485,14 +12520,22 @@ var NC_AUDIO_DBFS_FLOOR = -96;
12485
12520
  * an operator who typed `dog` mean the same thing.
12486
12521
  */
12487
12522
  var NcAudioConditionSchema = zod.z.object({
12488
- /** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
12523
+ /** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
12489
12524
  labels: zod.z.array(zod.z.string().min(1)).min(1).optional(),
12490
12525
  /** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
12491
12526
  dbThreshold: zod.z.number().min(-96).max(0).optional(),
12492
12527
  /** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
12493
12528
  hitPercent: zod.z.number().int().min(1).max(100).default(60),
12494
12529
  /** LEVEL MODE ONLY: length of the sampling window in seconds. */
12495
- samplingSeconds: zod.z.number().int().min(1).max(300).default(10)
12530
+ samplingSeconds: zod.z.number().int().min(1).max(300).default(10),
12531
+ /**
12532
+ * LABEL MODE: how many labelled frames must land inside
12533
+ * {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
12534
+ * Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
12535
+ */
12536
+ confirmHits: zod.z.number().int().min(1).max(20).optional(),
12537
+ /** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
12538
+ confirmWindowSec: zod.z.number().int().min(1).max(60).optional()
12496
12539
  });
12497
12540
  /**
12498
12541
  * Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
@@ -15452,6 +15495,46 @@ var RecentTracksPageSchema = zod.z.object({
15452
15495
  /** Cursor for the next page, or null when this page is the last. */
15453
15496
  nextCursor: zod.z.string().nullable()
15454
15497
  });
15498
+ var LIST_GROUPS_DEFAULT_LIMIT = 40;
15499
+ var LIST_GROUPS_MAX_LIMIT = 100;
15500
+ var AnalyticsGroupRecordSchema = zod.z.object({
15501
+ id: zod.z.string(),
15502
+ deviceId: zod.z.number().int(),
15503
+ openedAt: zod.z.number().int(),
15504
+ closedAt: zod.z.number().int(),
15505
+ timestamp: zod.z.number().int(),
15506
+ memberCount: zod.z.number().int(),
15507
+ memberTrackIds: zod.z.array(zod.z.string()).readonly(),
15508
+ className: zod.z.string(),
15509
+ classes: zod.z.array(zod.z.string()).readonly(),
15510
+ /** Relative event-media path, or null when the group has no picture yet. */
15511
+ mediaUrl: zod.z.string().nullable(),
15512
+ singleton: zod.z.boolean()
15513
+ });
15514
+ var AnalyticsGroupMemberSchema = zod.z.object({
15515
+ trackId: zod.z.string(),
15516
+ deviceId: zod.z.number().int(),
15517
+ className: zod.z.string(),
15518
+ firstSeen: zod.z.number().int(),
15519
+ lastSeen: zod.z.number().int(),
15520
+ mediaUrl: zod.z.string().nullable()
15521
+ });
15522
+ var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: zod.z.array(AnalyticsGroupMemberSchema).readonly() });
15523
+ var ListGroupsQueryInput = zod.z.object({
15524
+ /** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
15525
+ deviceIds: zod.z.array(zod.z.number()),
15526
+ /** Window lower bound on `closedAt` (inclusive). */
15527
+ since: zod.z.number().optional(),
15528
+ /** Window upper bound on `openedAt` (inclusive). */
15529
+ until: zod.z.number().optional(),
15530
+ limit: zod.z.number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
15531
+ /** Opaque continuation cursor from a previous page's `nextCursor`. */
15532
+ cursor: zod.z.string().optional()
15533
+ });
15534
+ var ListGroupsPageSchema = zod.z.object({
15535
+ groups: zod.z.array(AnalyticsGroupRecordSchema).readonly(),
15536
+ nextCursor: zod.z.string().nullable()
15537
+ });
15455
15538
  var KeyEventQueryInput = zod.z.object({
15456
15539
  deviceId: zod.z.number(),
15457
15540
  /** Window lower bound (track firstSeen ≥ since). */
@@ -15527,7 +15610,9 @@ var TrackCascadeCountsSchema = zod.z.object({
15527
15610
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
15528
15611
  plates: zod.z.number().int(),
15529
15612
  /** Per-track CLIP search vectors removed (best-effort). */
15530
- embeddings: zod.z.number().int()
15613
+ embeddings: zod.z.number().int(),
15614
+ /** Group membership + group rows removed with their last member (best-effort). */
15615
+ groups: zod.z.number().int()
15531
15616
  });
15532
15617
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
15533
15618
  var DiskReconcileCountsSchema = zod.z.object({
@@ -15699,6 +15784,16 @@ var pipelineAnalyticsCapability = {
15699
15784
  * are not included (same contract as `listTracks`).
15700
15785
  */
15701
15786
  listRecentTracks: require_sleep.method(RecentTracksQueryInput, RecentTracksPageSchema),
15787
+ /**
15788
+ * Batched co-moving group listing — the Groups feed. Same merge/cursor
15789
+ * contract as {@link listRecentTracks}. A group is a sealed partition of
15790
+ * one session; `getGroup` is the detail with members.
15791
+ */
15792
+ listGroups: require_sleep.method(ListGroupsQueryInput, ListGroupsPageSchema),
15793
+ getGroup: require_sleep.method(zod.z.object({
15794
+ deviceId: zod.z.number(),
15795
+ groupId: zod.z.string().min(1)
15796
+ }), AnalyticsGroupDetailSchema.nullable()),
15702
15797
  clearTracks: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
15703
15798
  kind: "mutation",
15704
15799
  auth: "admin"
@@ -16387,7 +16482,8 @@ var PipelineModelOptionSchema = zod.z.object({
16387
16482
  sizeMB: zod.z.number()
16388
16483
  })),
16389
16484
  group: ModelVariantGroupSchema.optional(),
16390
- legacy: zod.z.boolean().optional()
16485
+ legacy: zod.z.boolean().optional(),
16486
+ provider: ModelProviderIdSchema.optional()
16391
16487
  });
16392
16488
  var ConfigFieldBridge = zod.z.custom();
16393
16489
  var PipelineAddonSchemaSchema = zod.z.object({
@@ -37777,6 +37873,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
37777
37873
  addonId: null,
37778
37874
  access: "view"
37779
37875
  },
37876
+ "pipelineAnalytics.getGroup": {
37877
+ capName: "pipeline-analytics",
37878
+ capScope: "device",
37879
+ addonId: null,
37880
+ access: "view"
37881
+ },
37780
37882
  "pipelineAnalytics.getKeyEvents": {
37781
37883
  capName: "pipeline-analytics",
37782
37884
  capScope: "device",
@@ -37861,6 +37963,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
37861
37963
  addonId: null,
37862
37964
  access: "view"
37863
37965
  },
37966
+ "pipelineAnalytics.listGroups": {
37967
+ capName: "pipeline-analytics",
37968
+ capScope: "device",
37969
+ addonId: null,
37970
+ access: "view"
37971
+ },
37864
37972
  "pipelineAnalytics.listOpsLog": {
37865
37973
  capName: "pipeline-analytics",
37866
37974
  capScope: "device",
@@ -41537,6 +41645,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
41537
41645
  form: "single",
41538
41646
  optional: false
41539
41647
  }],
41648
+ "pipelineAnalytics.getGroup": [{
41649
+ name: "deviceId",
41650
+ form: "single",
41651
+ optional: false
41652
+ }],
41540
41653
  "pipelineAnalytics.getKeyEvents": [{
41541
41654
  name: "deviceId",
41542
41655
  form: "single",
@@ -41592,6 +41705,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
41592
41705
  form: "array",
41593
41706
  optional: false
41594
41707
  }],
41708
+ "pipelineAnalytics.listGroups": [{
41709
+ name: "deviceIds",
41710
+ form: "array",
41711
+ optional: false
41712
+ }],
41595
41713
  "pipelineAnalytics.listOpsLog": [{
41596
41714
  name: "deviceId",
41597
41715
  form: "single",
@@ -43590,6 +43708,19 @@ var NC_AUDIO_HIT_PERCENT_MIN = 1;
43590
43708
  var NC_AUDIO_HIT_PERCENT_MAX = 100;
43591
43709
  var NC_AUDIO_SAMPLING_MIN_SEC = 1;
43592
43710
  var NC_AUDIO_SAMPLING_MAX_SEC = 300;
43711
+ /**
43712
+ * LABEL-mode confirm-count defaults. Chosen against the live "Pianti" rule
43713
+ * (2026-08-23): 15 notifies in 12 h, each a single YAMNet `crying` frame,
43714
+ * nobody actually crying. Two labelled frames in 5 s drops the single-frame
43715
+ * false positives and still catches a real episode (YAMNet labels 2–3
43716
+ * frames of a genuine cry).
43717
+ */
43718
+ var NC_AUDIO_CONFIRM_HITS_DEFAULT = 2;
43719
+ var NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT = 5;
43720
+ var NC_AUDIO_CONFIRM_HITS_MIN = 1;
43721
+ var NC_AUDIO_CONFIRM_HITS_MAX = 20;
43722
+ var NC_AUDIO_CONFIRM_WINDOW_MIN_SEC = 1;
43723
+ var NC_AUDIO_CONFIRM_WINDOW_MAX_SEC = 60;
43593
43724
  /** Schema defaults — an untouched sub-field must author exactly these. */
43594
43725
  var NC_AUDIO_DEFAULTS = {
43595
43726
  hitPercent: 60,
@@ -43669,7 +43800,15 @@ function patchAudio(current, patch) {
43669
43800
  ...labels !== void 0 ? { labels: [...labels] } : {},
43670
43801
  ...dbThreshold !== void 0 ? { dbThreshold: clampInt(dbThreshold, NC_AUDIO_DB_MIN, 0) } : {},
43671
43802
  hitPercent: clampInt(patch.hitPercent ?? base.hitPercent, 1, 100),
43672
- samplingSeconds: clampInt(patch.samplingSeconds ?? base.samplingSeconds, 1, 300)
43803
+ samplingSeconds: clampInt(patch.samplingSeconds ?? base.samplingSeconds, 1, 300),
43804
+ ...(() => {
43805
+ const hits = has(patch, "confirmHits") ? patch.confirmHits : base.confirmHits;
43806
+ const windowSec = has(patch, "confirmWindowSec") ? patch.confirmWindowSec : base.confirmWindowSec;
43807
+ return {
43808
+ ...hits !== void 0 ? { confirmHits: clampInt(hits, 1, 20) } : {},
43809
+ ...windowSec !== void 0 ? { confirmWindowSec: clampInt(windowSec, 1, 60) } : {}
43810
+ };
43811
+ })()
43673
43812
  };
43674
43813
  }
43675
43814
  /**
@@ -47428,6 +47567,9 @@ exports.AlertSeveritySchema = AlertSeveritySchema;
47428
47567
  exports.AlertSourceSchema = AlertSourceSchema;
47429
47568
  exports.AlertStatusSchema = AlertStatusSchema;
47430
47569
  exports.AmbientLightSensorStatusSchema = AmbientLightSensorStatusSchema;
47570
+ exports.AnalyticsGroupDetailSchema = AnalyticsGroupDetailSchema;
47571
+ exports.AnalyticsGroupMemberSchema = AnalyticsGroupMemberSchema;
47572
+ exports.AnalyticsGroupRecordSchema = AnalyticsGroupRecordSchema;
47431
47573
  exports.ApiKeyRecordSchema = ApiKeyRecordSchema;
47432
47574
  exports.ApiKeySummarySchema = ApiKeySummarySchema;
47433
47575
  exports.ArchiveEntrySchema = ArchiveEntrySchema;
@@ -47771,6 +47913,8 @@ exports.LawnMowerActivitySchema = LawnMowerActivitySchema;
47771
47913
  exports.LawnMowerControlStatusSchema = LawnMowerControlStatusSchema;
47772
47914
  exports.LinkedDeviceSchema = LinkedDeviceSchema;
47773
47915
  exports.LinkedDevicesModeSchema = LinkedDevicesModeSchema;
47916
+ exports.ListGroupsPageSchema = ListGroupsPageSchema;
47917
+ exports.ListGroupsQueryInput = ListGroupsQueryInput;
47774
47918
  exports.LlmDefaultSchema = LlmDefaultSchema;
47775
47919
  exports.LlmDefaultSelectorSchema = LlmDefaultSelectorSchema;
47776
47920
  exports.LlmDownloadProgressSchema = LlmDownloadProgressSchema;
@@ -47814,6 +47958,7 @@ exports.MAX_EXPRESSION_SOURCE_LENGTH = MAX_EXPRESSION_SOURCE_LENGTH;
47814
47958
  exports.METHOD_ACCESS_MAP = METHOD_ACCESS_MAP;
47815
47959
  exports.METHOD_DEVICE_SELECTORS = METHOD_DEVICE_SELECTORS;
47816
47960
  exports.MODEL_FORMATS = MODEL_FORMATS;
47961
+ exports.MODEL_PROVIDER_IDS = MODEL_PROVIDER_IDS;
47817
47962
  exports.MOTION_TRIGGER_FEATURE = MOTION_TRIGGER_FEATURE;
47818
47963
  exports.ManagedModelCatalogEntrySchema = ManagedModelCatalogEntrySchema;
47819
47964
  exports.ManagedModelExtraFileSchema = ManagedModelExtraFileSchema;
@@ -47844,6 +47989,7 @@ exports.ModelDistributeResultSchema = ModelDistributeResultSchema;
47844
47989
  exports.ModelExtraFileSchema = ModelExtraFileSchema;
47845
47990
  exports.ModelFormatEntrySchema = ModelFormatEntrySchema;
47846
47991
  exports.ModelFormatsSchema = ModelFormatsSchema;
47992
+ exports.ModelProviderIdSchema = ModelProviderIdSchema;
47847
47993
  exports.ModelSubstitutionSchema = ModelSubstitutionSchema;
47848
47994
  exports.ModelVariantGroupSchema = ModelVariantGroupSchema;
47849
47995
  exports.MotionAnalysisResultSchema = MotionAnalysisResultSchema;
@@ -47873,6 +48019,12 @@ exports.NATIVE_LEASE_SECTION_ID = NATIVE_LEASE_SECTION_ID;
47873
48019
  exports.NATIVE_LEASE_TILE_BUDGET_FIELD = NATIVE_LEASE_TILE_BUDGET_FIELD;
47874
48020
  exports.NATIVE_LEASE_TILE_BUDGET_KEY = NATIVE_LEASE_TILE_BUDGET_KEY;
47875
48021
  exports.NC_ALARM_SYSTEM_EVENT_KINDS = NC_ALARM_SYSTEM_EVENT_KINDS;
48022
+ exports.NC_AUDIO_CONFIRM_HITS_DEFAULT = NC_AUDIO_CONFIRM_HITS_DEFAULT;
48023
+ exports.NC_AUDIO_CONFIRM_HITS_MAX = NC_AUDIO_CONFIRM_HITS_MAX;
48024
+ exports.NC_AUDIO_CONFIRM_HITS_MIN = NC_AUDIO_CONFIRM_HITS_MIN;
48025
+ exports.NC_AUDIO_CONFIRM_WINDOW_MAX_SEC = NC_AUDIO_CONFIRM_WINDOW_MAX_SEC;
48026
+ exports.NC_AUDIO_CONFIRM_WINDOW_MIN_SEC = NC_AUDIO_CONFIRM_WINDOW_MIN_SEC;
48027
+ exports.NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT = NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT;
47876
48028
  exports.NC_AUDIO_DBFS_FLOOR = NC_AUDIO_DBFS_FLOOR;
47877
48029
  exports.NC_AUDIO_DB_MAX = NC_AUDIO_DB_MAX;
47878
48030
  exports.NC_AUDIO_DB_MIN = NC_AUDIO_DB_MIN;
@@ -48493,6 +48645,7 @@ exports.humiditySensorCapability = humiditySensorCapability;
48493
48645
  exports.hydrateSchema = require_sleep.hydrateSchema;
48494
48646
  exports.imageCapability = imageCapability;
48495
48647
  exports.imageSettingsCapability = imageSettingsCapability;
48648
+ exports.inferModelProvider = inferModelProvider;
48496
48649
  exports.initialPoolMemoryState = initialPoolMemoryState;
48497
48650
  exports.integrationsCapability = integrationsCapability;
48498
48651
  exports.intercomCapability = intercomCapability;