@camstack/addon-import-alexa 0.2.119 → 0.2.120

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 (3) hide show
  1. package/dist/addon.js +882 -461
  2. package/dist/addon.mjs +882 -461
  3. package/package.json +1 -1
package/dist/addon.mjs CHANGED
@@ -38,7 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
38
38
  var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
39
39
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
40
40
  //#endregion
41
- //#region ../types/dist/event-category-BGmz_oxW.mjs
41
+ //#region ../types/dist/event-category-B_0XEcLF.mjs
42
42
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
43
43
  EventCategory["SystemBoot"] = "system.boot";
44
44
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -539,15 +539,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
539
539
  EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
540
540
  EventCategory["AgentBackupActivated"] = "agent.backup.activated";
541
541
  EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
542
- /**
543
- * Per-agent hwaccel preference changed (user override set, cleared, or
544
- * re-probed). Observability event — decoders pull the current pref at
545
- * `createSession`, so running sessions keep their current backend until
546
- * they rotate naturally (camera add/remove, stream restart). Future
547
- * work can wire a listener in stream-broker that force-rotates live
548
- * sessions; for now this event powers logs + admin-UI toast feedback.
549
- */
550
- EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
551
542
  EventCategory["MotionAnalysis"] = "detection.motion-analysis";
552
543
  /** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
553
544
  EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
@@ -5418,7 +5409,7 @@ var ZodIssueCode = {
5418
5409
  var ZodFirstPartyTypeKind;
5419
5410
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5420
5411
  //#endregion
5421
- //#region ../types/dist/sleep-DXKLNFvA.mjs
5412
+ //#region ../types/dist/sleep-BNeXenvr.mjs
5422
5413
  /**
5423
5414
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5424
5415
  * window to float samples (D455).
@@ -6784,32 +6775,12 @@ object({
6784
6775
  audioCodec: string().optional(),
6785
6776
  metadata: record(string(), unknown()).readonly().optional()
6786
6777
  });
6787
- var EncodedPacketSchema = object({
6788
- type: _enum(["video", "audio"]),
6789
- data: _instanceof(Uint8Array),
6790
- pts: number(),
6791
- dts: number(),
6792
- keyframe: boolean(),
6793
- codec: string()
6794
- });
6795
- var DecodedFrameSchema = object({
6796
- data: _instanceof(Uint8Array),
6797
- width: number(),
6798
- height: number(),
6799
- format: _enum([
6800
- "jpeg",
6801
- "rgb",
6802
- "bgr",
6803
- "yuv420",
6804
- "gray"
6805
- ]),
6806
- timestamp: number()
6807
- });
6808
6778
  /**
6809
6779
  * Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
6810
6780
  * frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
6811
- * interface in `interfaces/frame-handle.ts` field-for-field so a decoder cap
6812
- * method (`pullHandles`) can carry handles over tRPC / Moleculer.
6781
+ * interface in `interfaces/frame-handle.ts` field-for-field so a cap method
6782
+ * (the runner's native-crop and pipeline-executor inputs) can carry handles
6783
+ * over tRPC / Moleculer.
6813
6784
  *
6814
6785
  * The `satisfies` assertion below pins this schema to the interface: if a
6815
6786
  * field is added to / removed from `FrameHandle` without a matching schema
@@ -6835,50 +6806,6 @@ var FrameHandleSchema = object({
6835
6806
  slotCount: number().int().positive()
6836
6807
  });
6837
6808
  /**
6838
- * Pixel format a frame-handle subscriber can request from the broker
6839
- * (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
6840
- * `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
6841
- * `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
6842
- * payload, and no decoded-frame consumer requests it over the shm plane.
6843
- */
6844
- var FrameHandleFormatSchema = _enum([
6845
- "rgb",
6846
- "bgr",
6847
- "yuv420",
6848
- "gray"
6849
- ]);
6850
- /**
6851
- * Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
6852
- * broker for a `FrameHandle` stream of one `format`; the broker maintains one
6853
- * shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
6854
- * subscriber (motion) and an `rgb` subscriber (detection) each read the format
6855
- * they asked for with no broker-side conversion.
6856
- */
6857
- var SubscribeFramesInputSchema = object({
6858
- brokerId: string(),
6859
- format: FrameHandleFormatSchema,
6860
- /**
6861
- * Optional reader-side cadence hint in frames per second. The broker does
6862
- * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
6863
- * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
6864
- * the consumer can pace its own `pullFrameHandles` polling.
6865
- */
6866
- maxFps: number().positive().optional(),
6867
- /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
6868
- tag: string().optional()
6869
- });
6870
- /**
6871
- * Result of `stream-broker.subscribeFrames`. The consumer then polls
6872
- * `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
6873
- * `FrameHandle` to a `FrameRingReader`.
6874
- */
6875
- var SubscribeFramesResultSchema = object({
6876
- /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
6877
- subscriptionId: string(),
6878
- /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
6879
- maxFps: number().nonnegative()
6880
- });
6881
- /**
6882
6809
  * Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
6883
6810
  * `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
6884
6811
  * sample bytes plus the track parameters a consumer needs to interpret them.
@@ -6886,8 +6813,8 @@ var SubscribeFramesResultSchema = object({
6886
6813
  * Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
6887
6814
  * Float32 PCM), so unlike video frames they ship their bytes INLINE over
6888
6815
  * tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
6889
- * (the wire-serialisable supertype of `Buffer`) to match `DecodedFrameSchema`
6890
- * / `EncodedPacketSchema`'s precedent; a `Buffer` is assignable to it.
6816
+ * (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
6817
+ * it.
6891
6818
  */
6892
6819
  var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
6893
6820
  var DecodedAudioChunkSchema = object({
@@ -6905,11 +6832,10 @@ var DecodedAudioChunkSchema = object({
6905
6832
  format: AudioChunkFormatSchema.optional()
6906
6833
  });
6907
6834
  /**
6908
- * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). The
6909
- * handle-free, ship-bytes-inline analogue of `subscribeFrames`: a consumer
6910
- * asks the broker for the decoded audio-chunk stream of one broker; the
6911
- * broker keeps a per-subscription bounded FIFO queue the consumer drains via
6912
- * `pullAudioChunks`.
6835
+ * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
6836
+ * its bytes inline: a consumer asks the broker for the decoded audio-chunk
6837
+ * stream of one broker; the broker keeps a per-subscription bounded FIFO queue
6838
+ * the consumer drains via `pullAudioChunks`.
6913
6839
  */
6914
6840
  var SubscribeAudioChunksInputSchema = object({
6915
6841
  brokerId: string(),
@@ -6940,9 +6866,7 @@ var BrokerStatsSchema = object({
6940
6866
  "stopped"
6941
6867
  ]),
6942
6868
  inputFps: number(),
6943
- decodeFps: number(),
6944
6869
  encodedSubscribers: number(),
6945
- decodedSubscribers: number(),
6946
6870
  uptimeMs: number(),
6947
6871
  bitrateKbps: number(),
6948
6872
  idrIntervalMs: number(),
@@ -6955,14 +6879,6 @@ var BrokerStatsSchema = object({
6955
6879
  preBufferMs: number(),
6956
6880
  preBufferPackets: number(),
6957
6881
  /**
6958
- * Moleculer node id of the decoder provider currently servicing this
6959
- * stream's decoded subscribers. `null` until the deferred decoder is
6960
- * created (no decoded clients yet, or codec not detected). Surfaces the
6961
- * runtime decoder placement so the UI can show "Decoder: <agent>" without
6962
- * a separate cap call per broker.
6963
- */
6964
- decoderNodeId: string().nullable(),
6965
- /**
6966
6882
  * Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
6967
6883
  * when the stream has no audio track or the broker is in cold start.
6968
6884
  * `supported = false` means the codec was detected but the local
@@ -10415,70 +10331,6 @@ var StorageLocationDeclarationSchema = object({
10415
10331
  "backup"
10416
10332
  ]).optional()
10417
10333
  });
10418
- var DecoderStatsSchema = object({
10419
- inputFps: number(),
10420
- outputFps: number(),
10421
- avgDecodeTimeMs: number(),
10422
- droppedFrames: number(),
10423
- /**
10424
- * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
10425
- * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
10426
- * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
10427
- * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
10428
- */
10429
- lagMs: number().optional(),
10430
- effectiveFps: number().optional(),
10431
- adaptiveFps: number().optional()
10432
- });
10433
- var DecoderSessionConfigSchema = object({
10434
- codec: string(),
10435
- maxFps: number().default(0),
10436
- outputFormat: _enum([
10437
- "jpeg",
10438
- "rgb",
10439
- "bgr",
10440
- "yuv420",
10441
- "gray"
10442
- ]).default("jpeg"),
10443
- scale: number().default(1),
10444
- width: number().optional(),
10445
- height: number().optional(),
10446
- /**
10447
- * Identifier of the camera this decoder session serves. Optional
10448
- * because the cap is generic (any caller could request decode), but
10449
- * stream-broker passes it so decoder logs include `deviceId` for
10450
- * per-camera filtering when diagnosing failures (e.g. node-av
10451
- * sendPacket errors on a single hung camera).
10452
- */
10453
- deviceId: number().int().nonnegative().optional(),
10454
- /**
10455
- * Free-form tag for log scoping. Stream-broker uses
10456
- * `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
10457
- * on every line so `grep tag=broker:5/high` filters one camera
10458
- * profile cleanly.
10459
- */
10460
- tag: string().optional(),
10461
- /**
10462
- * Where the session delivers decoded frames (Phase 5 / D9):
10463
- *
10464
- * - `'callback'` (default) — the legacy pixel path: decoded frames are
10465
- * buffered as `DecodedFrame`s and drained via `pullFrames`.
10466
- * - `'shm'` — the shared-memory frame plane: decoded frames are written
10467
- * into an OS shared-memory ring and drained as zero-pixel
10468
- * `FrameHandle`s via `pullHandles`. A session is one mode or the
10469
- * other — `pullFrames` returns nothing for an `'shm'` session and
10470
- * `pullHandles` returns nothing for a `'callback'` session.
10471
- */
10472
- frameSink: _enum(["callback", "shm"]).default("callback"),
10473
- /**
10474
- * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
10475
- * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
10476
- * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
10477
- * stream-broker's `streamingDebug` gate — off by default so production logs
10478
- * stay quiet and the emit path pays zero per-frame cost when disabled.
10479
- */
10480
- debug: boolean().optional()
10481
- });
10482
10334
  /**
10483
10335
  * Per-component log CHANNELS — the gate a hot path consults, and the registry
10484
10336
  * an addon declares its channels in.
@@ -10621,6 +10473,26 @@ var ClipSearchStrictnessSchema = _enum([
10621
10473
  "balanced",
10622
10474
  "strict"
10623
10475
  ]);
10476
+ /** Steps whose effect a root label can BE. */
10477
+ var LABEL_SUPPLY_STEP_IDS = [
10478
+ "animal-classifier",
10479
+ "vehicle-classifier",
10480
+ "package-detection"
10481
+ ];
10482
+ /** Steps whose box a root detection can BE. */
10483
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10484
+ /**
10485
+ * Steps whose per-detection MASK a root detection can carry (D737). The live
10486
+ * mask step is `segmentation` — a frame-plane refiner that runs its own model
10487
+ * once per detection crop. (`instance-segmentation` is a dormant step id that
10488
+ * no camera tree carries.)
10489
+ */
10490
+ var MASK_SUPPLY_STEP_IDS = ["segmentation"];
10491
+ [
10492
+ ...LABEL_SUPPLY_STEP_IDS,
10493
+ ...CROP_SUPPLY_STEP_IDS,
10494
+ ...MASK_SUPPLY_STEP_IDS
10495
+ ];
10624
10496
  var MODEL_FORMATS = [
10625
10497
  "onnx",
10626
10498
  "coreml",
@@ -10649,7 +10521,53 @@ var ModelFormatEntrySchema = object({
10649
10521
  /** Multi-file payload (directory members or sibling files). */
10650
10522
  files: array(string()).readonly().optional(),
10651
10523
  /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
10652
- runtimes: array(_enum(["python"])).readonly().optional()
10524
+ runtimes: array(_enum(["python"])).readonly().optional(),
10525
+ /**
10526
+ * Content revision of the artefact, for one hosted OFF the CamStack mirror.
10527
+ * A format on the mirror leaves it unset: its revision (the sha256 of its
10528
+ * weight file) comes from the downloader's generated table, kept in step
10529
+ * with the mirror by `scripts/check-hosted-model-revisions.ts` (D744). A
10530
+ * node records the revision it downloaded next to the file
10531
+ * (`<file>.revision`); a copy with no record or a different one is stale
10532
+ * unless its weight file hashes to the revision, and a stale copy is
10533
+ * downloaded again, the old one serving until the new one is complete. No
10534
+ * revision at all ⇒ a file on disk is current, whatever it holds (D743).
10535
+ */
10536
+ revision: string().min(1).optional()
10537
+ });
10538
+ /**
10539
+ * What a node holds for one (model, format) (D746). `current` is a complete
10540
+ * copy at its catalog revision — exactly what `downloaded: true` means.
10541
+ * `stale` is bytes on disk that are not (yet) proven current under D743/D744:
10542
+ * no or a different revision record, or a missing sibling. `missing` is no
10543
+ * copy. `downloaded` alone folds `stale` into "not downloaded", which hid
10544
+ * reclaimable bytes and a copy about to be replaced.
10545
+ */
10546
+ var ModelOnDiskStateSchema = _enum([
10547
+ "current",
10548
+ "stale",
10549
+ "missing"
10550
+ ]);
10551
+ /**
10552
+ * The numeric precision of one format's BUILD (D746) — reported only when the
10553
+ * build states it (file-name token, an INT8 variant, an EdgeTPU compile, a
10554
+ * CamStack Core ML export). Absent means "not stated", never "fp32".
10555
+ */
10556
+ var ModelFormatPrecisionSchema = _enum([
10557
+ "fp32",
10558
+ "fp16",
10559
+ "int8"
10560
+ ]);
10561
+ /**
10562
+ * One format of one model as a node's `pipelineExecutor.getSchema` reports it.
10563
+ * `onDisk` / `precision` are optional for version skew: a runner that predates
10564
+ * them omits them, and a reader falls back to `downloaded`.
10565
+ */
10566
+ var PipelineModelFormatStatusSchema = object({
10567
+ downloaded: boolean(),
10568
+ sizeMB: number(),
10569
+ onDisk: ModelOnDiskStateSchema.optional(),
10570
+ precision: ModelFormatPrecisionSchema.optional()
10653
10571
  });
10654
10572
  /**
10655
10573
  * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
@@ -10753,6 +10671,46 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10753
10671
  /** True when the weights or their data forbid commercial use. */
10754
10672
  nonCommercial: boolean().optional()
10755
10673
  }));
10674
+ /**
10675
+ * One step a ROOT detector can supply from its own output (D730) — see
10676
+ * `ModelCatalogEntry.suppliesSteps`.
10677
+ *
10678
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10679
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10680
+ * the root cannot produce (shown as unavailable, never a blocker).
10681
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10682
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10683
+ * child of the `parentMacro` detection that contains it — never a track.
10684
+ * - `mask`: the root's decode emits an instance mask with every detection (a
10685
+ * YOLO26-seg root, D737) — the `segmentation` step's result, carried on the
10686
+ * detection in the shape that step produces. Derived from the model's
10687
+ * postprocessor on read, never stored by an import.
10688
+ */
10689
+ var RootStepSupplySchema = discriminatedUnion("kind", [
10690
+ object({
10691
+ kind: literal("label"),
10692
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10693
+ labelToEffect: record(string(), string()),
10694
+ uncovered: array(string()).readonly()
10695
+ }),
10696
+ object({
10697
+ kind: literal("crop"),
10698
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10699
+ rootLabels: array(string()).readonly(),
10700
+ parentMacro: _enum(["vehicle", "person"]),
10701
+ childClass: _enum(["plate", "face"]),
10702
+ /**
10703
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10704
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10705
+ * stored by an import.
10706
+ */
10707
+ rootInputPx: number().int().positive().optional()
10708
+ }),
10709
+ object({
10710
+ kind: literal("mask"),
10711
+ stepId: _enum(MASK_SUPPLY_STEP_IDS)
10712
+ })
10713
+ ]);
10756
10714
  var ModelCatalogEntrySchema = object({
10757
10715
  id: string(),
10758
10716
  name: string(),
@@ -10818,6 +10776,35 @@ var ModelCatalogEntrySchema = object({
10818
10776
  */
10819
10777
  defaultConfidence: number().min(0).max(1).optional(),
10820
10778
  /**
10779
+ * Per-MODEL default of the per-class confidence floors (`minConfidence<Macro>`
10780
+ * on a detector step), keyed by macro class: `{ person: 0.45 }`. A class
10781
+ * absent here runs at the step slider's global default. The same row shape
10782
+ * the floor measurement produces (`model-floors.json`: modelId → floors), so
10783
+ * a measured table is copied in as-is. An operator override is bound to the
10784
+ * model it was made for and does not survive a model change (D738). A custom
10785
+ * / imported model may declare it; without it, the global defaults apply.
10786
+ */
10787
+ defaultClassFloors: record(string(), number().min(0).max(1)).optional(),
10788
+ /**
10789
+ * The inference precision this model's OpenVINO IR needs on an Intel GPU.
10790
+ * Absent ⇒ the device default (f16 on a GPU). Set to `'f32'` for an FP32 IR
10791
+ * that produces invalid output at f16 — measured 2026-10-07 for YOLO26
10792
+ * base IRs (`yolo26s`: 0 true / 146 false positives; `yolo26m*`: NaN
10793
+ * scores) on the Core Ultra iGPU and the N100. Threaded to the pool as
10794
+ * `PoolModelConfig.gpuInferencePrecision`; the pool sets
10795
+ * INFERENCE_PRECISION_HINT on a GPU only. Costs ~60% latency on the GPU.
10796
+ */
10797
+ gpuInferencePrecision: _enum(["f32", "f16"]).optional(),
10798
+ /**
10799
+ * ROOT detectors only: per supplied step (`animal-classifier`, …), the
10800
+ * minimum DETECTION score from which this root's own fine label (species,
10801
+ * vehicle type — D736 root supply) is taken (D741). Below it the detection
10802
+ * keeps its macro class without the fine label. `1` = never take it from
10803
+ * this root. Absent ⇒ no floor beyond the macro floor. The supplied step's
10804
+ * `minConfidence` slider, bound to the ROOT model, overrides it.
10805
+ */
10806
+ suppliedLabelFloors: record(string(), number().min(0).max(1)).optional(),
10807
+ /**
10821
10808
  * When true, the executor produces a landmark-aligned crop (similarity warp
10822
10809
  * onto the canonical template) before this step runs, instead of a plain
10823
10810
  * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
@@ -10879,6 +10866,16 @@ var ModelCatalogEntrySchema = object({
10879
10866
  */
10880
10867
  classMap: DetectionCatalogClassMapSchema.optional(),
10881
10868
  /**
10869
+ * The pipeline steps this ROOT detector can supply from its own output
10870
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
10871
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
10872
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
10873
+ * by hand and never assumed per family; a row without it is derived on read
10874
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
10875
+ * `useRootModel` flag (`resolveRootSupply`).
10876
+ */
10877
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
10878
+ /**
10882
10879
  * The model's CLIP feature-space contract (text encoder, dimension, vector
10883
10880
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
10884
10881
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -12548,13 +12545,6 @@ var BrokerRtspClientSchema = object({
12548
12545
  lastRtpAt: number(),
12549
12546
  bytesSent: number()
12550
12547
  });
12551
- var BrokerDecodedClientSchema = object({
12552
- tag: string(),
12553
- subscribedAt: number(),
12554
- maxFps: number(),
12555
- framesDelivered: number(),
12556
- framesDropped: number()
12557
- });
12558
12548
  var BrokerAudioClientSchema = object({
12559
12549
  tag: string(),
12560
12550
  subscribedAt: number(),
@@ -12646,7 +12636,6 @@ var BrokerEncodedClientSchema = object({
12646
12636
  });
12647
12637
  var BrokerClientsSchema = object({
12648
12638
  rtsp: array(BrokerRtspClientSchema).readonly(),
12649
- decoded: array(BrokerDecodedClientSchema).readonly(),
12650
12639
  audio: array(BrokerAudioClientSchema).readonly(),
12651
12640
  encoded: array(BrokerEncodedClientSchema).readonly(),
12652
12641
  pipeClients: number(),
@@ -13015,11 +13004,7 @@ method(object({
13015
13004
  auth: "admin"
13016
13005
  }), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
13017
13006
  brokerId: string(),
13018
- channel: _enum([
13019
- "rtsp",
13020
- "decoded",
13021
- "audio"
13022
- ]),
13007
+ channel: _enum(["rtsp", "audio"]),
13023
13008
  handle: string()
13024
13009
  }), object({ killed: boolean() }), {
13025
13010
  kind: "mutation",
@@ -13054,10 +13039,7 @@ method(object({
13054
13039
  }), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
13055
13040
  subscriptionId: string(),
13056
13041
  maxCount: number().int().positive().default(8)
13057
- }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(SubscribeFramesInputSchema, SubscribeFramesResultSchema, { kind: "mutation" }), method(object({
13058
- subscriptionId: string(),
13059
- maxCount: number().int().positive().default(4)
13060
- }), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
13042
+ }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
13061
13043
  brokerId: string(),
13062
13044
  seconds: number().min(0).max(30)
13063
13045
  }), _void(), {
@@ -14316,54 +14298,12 @@ id: union([string(), number()]) }), {
14316
14298
  kind: "mutation",
14317
14299
  auth: "admin"
14318
14300
  });
14319
- /**
14320
- * shm ring usage stats for a `frameSink: 'shm'` decoder session —
14321
- * exposed via `decoder.getShmStats` so downstream consumers can
14322
- * observe ring pressure (slot count, byte budget, hit/miss ratio).
14323
- */
14324
- var ShmRingStatsSchema = object({
14325
- sessionId: string(),
14326
- slotCount: number().int(),
14327
- slotByteLength: number().int(),
14328
- segmentBytes: number().int(),
14329
- budgetMb: number().int(),
14330
- framesWritten: number().int(),
14331
- getFrameHits: number().int(),
14332
- getFrameMisses: number().int()
14333
- });
14334
- method(object({ codec: string() }), boolean()), method(_void(), object({
14301
+ method(_void(), object({
14335
14302
  id: string(),
14336
14303
  name: string(),
14337
- isPullMode: boolean().optional(),
14338
- priority: number().optional(),
14339
14304
  hwaccel: string().optional(),
14340
14305
  probedBestHwaccel: string().optional()
14341
- })), method(DecoderSessionConfigSchema, object({
14342
- sessionId: string(),
14343
- nodeId: string()
14344
- })), method(object({ sessionId: string() }), _void()), method(object({
14345
- sessionId: string(),
14346
- packet: EncodedPacketSchema
14347
- }), _void()), method(object({
14348
- sessionId: string(),
14349
- url: string()
14350
- }), _void()), method(object({
14351
- sessionId: string(),
14352
- maxCount: number().default(1),
14353
- waitMs: number().optional()
14354
- }), array(DecodedFrameSchema)), method(object({
14355
- sessionId: string(),
14356
- maxCount: number().default(1),
14357
- waitMs: number().optional()
14358
- }), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
14359
- sessionId: string(),
14360
- config: DecoderSessionConfigSchema.partial()
14361
- }), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
14362
- sessionId: string(),
14363
- codec: string(),
14364
- outputFormat: string(),
14365
- createdAtMs: number()
14366
- })).readonly()), method(_void(), object({ backend: string() }), {
14306
+ })), method(_void(), object({ backend: string() }), {
14367
14307
  kind: "mutation",
14368
14308
  auth: "admin"
14369
14309
  });
@@ -16412,6 +16352,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
16412
16352
  kind: "mutation",
16413
16353
  auth: "admin"
16414
16354
  });
16355
+ var HUB_ADDRESS_ROLES = [
16356
+ "appConnections",
16357
+ "notificationTaps",
16358
+ "internal",
16359
+ "publicEndpoint"
16360
+ ];
16415
16361
  /**
16416
16362
  * Transport bounds for AI capability methods.
16417
16363
  *
@@ -19014,6 +18960,8 @@ var NcSystemEventKindSchema = _enum([
19014
18960
  "stream-offline",
19015
18961
  "node-online",
19016
18962
  "node-offline",
18963
+ "node-restarting",
18964
+ "node-updating",
19017
18965
  "node-inference-unavailable",
19018
18966
  "detection-blind",
19019
18967
  "addon-crash-loop",
@@ -20619,7 +20567,13 @@ var NcAlarmModeDelaysListSchema = array(object({
20619
20567
  * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20620
20568
  * is the one that starts the entry delay — the entry-delay notification already names it.
20621
20569
  */
20622
- notifySensorRewatched: boolean().optional()
20570
+ notifySensorRewatched: boolean().optional(),
20571
+ /**
20572
+ * D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
20573
+ * change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
20574
+ * re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
20575
+ */
20576
+ notifySensorIgnored: boolean().optional()
20623
20577
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20624
20578
  var NcAlarmModeDelaysEditListSchema = array(object({
20625
20579
  mode: AlarmArmModeSchema,
@@ -20632,7 +20586,9 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20632
20586
  /** D706: set the switch, or `null` to clear it (back to the default, false). */
20633
20587
  notifyDuringEntryDelay: boolean().nullable().optional(),
20634
20588
  /** D706: set the switch, or `null` to clear it (back to the default, false). */
20635
- notifySensorRewatched: boolean().nullable().optional()
20589
+ notifySensorRewatched: boolean().nullable().optional(),
20590
+ /** D735: set the switch, or `null` to clear it (back to the default, false). */
20591
+ notifySensorIgnored: boolean().nullable().optional()
20636
20592
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20637
20593
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20638
20594
  var NcAlarmNonBlockingEditSchema = object({
@@ -21610,8 +21566,8 @@ Object.freeze(Object.fromEntries([{
21610
21566
  var CLUSTER_STEP_SETTING_FIELDS = [{
21611
21567
  stepId: "face-embedding",
21612
21568
  key: "minLandmarkFaceSize",
21613
- label: "Min face size for recognition (detection px)",
21614
- description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
21569
+ label: "Min face size to embed (detection-frame px)",
21570
+ description: "Faces smaller than this in the small frame the detector sees are not embedded, so they can never be recognised. Below it the face cannot be aligned reliably and a bad embedding matches everyone. Same value on every node. 0 = no limit.",
21615
21571
  type: "slider",
21616
21572
  min: 0,
21617
21573
  max: 64,
@@ -23531,6 +23487,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23531
23487
  timestamp: number()
23532
23488
  });
23533
23489
  /**
23490
+ * A root model's boxes standing in for one crop-kind step's own inference
23491
+ * (D730) — see `runPipeline.suppliedRoot`.
23492
+ */
23493
+ var SuppliedRootOutputSchema = object({
23494
+ stepId: string(),
23495
+ /** The root model that drew the boxes — stamped on the result. */
23496
+ modelId: string(),
23497
+ detections: array(object({
23498
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23499
+ bbox: tuple([
23500
+ number(),
23501
+ number(),
23502
+ number(),
23503
+ number()
23504
+ ]),
23505
+ score: number(),
23506
+ /**
23507
+ * Five facial landmarks in the same pixels — a face the step's own
23508
+ * detector already re-found inside a root face box (D730), so its
23509
+ * embedder child aligns it exactly as it aligns any detected face.
23510
+ */
23511
+ landmarks: array(object({
23512
+ x: number(),
23513
+ y: number()
23514
+ })).optional()
23515
+ })).min(1)
23516
+ });
23517
+ /**
23534
23518
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
23535
23519
  * within the frame, so the executor can re-cut a leaf child ROI at native
23536
23520
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23578,7 +23562,7 @@ var FrameRefSchema = object({
23578
23562
  timestamp: number(),
23579
23563
  capturedAt: number().optional()
23580
23564
  });
23581
- var ModelFormatSchema$1 = _enum([
23565
+ var ModelFormatSchema$2 = _enum([
23582
23566
  "onnx",
23583
23567
  "coreml",
23584
23568
  "openvino",
@@ -23596,7 +23580,7 @@ var PipelineSlotSchema = _enum([
23596
23580
  var PipelineEngineChoiceSchema = object({
23597
23581
  runtime: literal("python"),
23598
23582
  backend: string(),
23599
- format: ModelFormatSchema$1,
23583
+ format: ModelFormatSchema$2,
23600
23584
  device: string().optional()
23601
23585
  });
23602
23586
  /**
@@ -23635,32 +23619,15 @@ var PipelineDefaultStepSchema = lazy(() => object({
23635
23619
  group: string().optional(),
23636
23620
  settings: record(string(), unknown()).optional()
23637
23621
  }));
23638
- var PipelineTemplateStepSchema = lazy(() => object({
23639
- addonId: string(),
23640
- enabled: boolean(),
23641
- modelId: string(),
23642
- children: array(PipelineTemplateStepSchema).readonly(),
23643
- settings: record(string(), unknown()).optional()
23644
- }));
23645
- var PipelineTemplateSchema$1 = object({
23646
- id: string(),
23647
- name: string(),
23648
- createdAt: string(),
23649
- updatedAt: string(),
23650
- engine: PipelineEngineChoiceSchema,
23651
- steps: array(PipelineTemplateStepSchema).readonly()
23652
- });
23653
23622
  var PipelineModelOptionSchema = object({
23654
23623
  id: string(),
23655
23624
  name: string(),
23656
- formats: record(string(), object({
23657
- downloaded: boolean(),
23658
- sizeMB: number()
23659
- })),
23625
+ formats: record(string(), PipelineModelFormatStatusSchema),
23660
23626
  group: ModelVariantGroupSchema.optional(),
23661
23627
  legacy: boolean().optional(),
23662
23628
  provider: ModelProviderIdSchema.optional(),
23663
- defaultConfidence: number().optional()
23629
+ defaultConfidence: number().optional(),
23630
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23664
23631
  });
23665
23632
  var ConfigFieldBridge = custom();
23666
23633
  var PipelineAddonSchemaSchema = object({
@@ -23822,6 +23789,22 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23822
23789
  }), {
23823
23790
  kind: "mutation",
23824
23791
  auth: "admin"
23792
+ }), method(object({
23793
+ nodeId: string(),
23794
+ deviceIds: array(number()).readonly().optional(),
23795
+ dryRun: boolean()
23796
+ }), object({
23797
+ entries: array(object({
23798
+ deviceId: number(),
23799
+ keys: array(string()).readonly()
23800
+ })).readonly(),
23801
+ refused: array(object({
23802
+ deviceId: number(),
23803
+ reason: string()
23804
+ })).readonly()
23805
+ }), {
23806
+ kind: "mutation",
23807
+ auth: "admin"
23825
23808
  }), method(object({ nodeId: string() }), object({ unhealthy: array(object({
23826
23809
  /** `<backend>:<device>`, e.g. `openvino:gpu`. */
23827
23810
  deviceKey: string(),
@@ -23847,22 +23830,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23847
23830
  }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
23848
23831
  steps: array(PipelineStepInputSchema),
23849
23832
  deviceKey: string().optional()
23850
- }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
23851
- name: string(),
23852
- steps: array(PipelineTemplateStepSchema).readonly(),
23853
- engine: PipelineEngineChoiceSchema
23854
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
23855
- id: string(),
23856
- name: string().optional(),
23857
- steps: array(PipelineTemplateStepSchema).readonly().optional()
23858
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
23833
+ }), PipelineValidationResultSchema), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
23859
23834
  addonId: string(),
23860
23835
  modelId: string(),
23861
- format: ModelFormatSchema$1
23836
+ format: ModelFormatSchema$2
23862
23837
  }), DownloadModelResultSchema, { kind: "mutation" }), method(object({
23863
23838
  addonId: string(),
23864
23839
  modelId: string(),
23865
- format: ModelFormatSchema$1
23840
+ format: ModelFormatSchema$2
23866
23841
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
23867
23842
  steps: array(PipelineStepInputSchema).min(1),
23868
23843
  frame: FrameInputSchema.optional(),
@@ -23928,7 +23903,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
23928
23903
  * `device-not-servable`), and nothing reaches the camera's live
23929
23904
  * trace stream. Absent ⇒ unchanged behaviour.
23930
23905
  */
23931
- replay: literal(true).optional()
23906
+ replay: literal(true).optional(),
23907
+ /**
23908
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
23909
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
23910
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
23911
+ * NOT inferred, these boxes are its output, and its children (the plate
23912
+ * reader) run on them through their own crop policy. Boxes are in the
23913
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
23914
+ */
23915
+ suppliedRoot: SuppliedRootOutputSchema.optional()
23932
23916
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
23933
23917
  steps: array(PipelineStepInputSchema).min(1),
23934
23918
  frames: array(FrameInputSchema).min(1).max(255),
@@ -24010,6 +23994,375 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24010
23994
  filename: string().optional(),
24011
23995
  settings: record(string(), unknown()).optional()
24012
23996
  }), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
23997
+ /**
23998
+ * The wire shapes of the Auto tune plan and apply (D745), used by the
23999
+ * `pipeline-orchestrator` cap. The recommender's own types
24000
+ * (`recommend.ts`) are the TS face of the same data; these
24001
+ * schemas are what crosses the cap boundary.
24002
+ */
24003
+ var ModelFormatSchema$1 = _enum(MODEL_FORMATS);
24004
+ /** The operator's range for it. */
24005
+ var MIN_SESSIONS_PER_DEVICE_RANGE = {
24006
+ min: 1,
24007
+ max: 8
24008
+ };
24009
+ var HardwareClassIdSchema = _enum([
24010
+ "intel-core-ultra",
24011
+ "intel-n-series",
24012
+ "apple-m-base",
24013
+ "apple-m-pro",
24014
+ "unknown"
24015
+ ]);
24016
+ var AcceleratorKindSchema = _enum([
24017
+ "intel-npu",
24018
+ "intel-igpu",
24019
+ "x86-cpu",
24020
+ "arm-cpu",
24021
+ "apple-ane",
24022
+ "coral"
24023
+ ]);
24024
+ var RecommendationReasonSchema = discriminatedUnion("kind", [
24025
+ object({
24026
+ kind: literal("capacity"),
24027
+ sessions: number(),
24028
+ minSessions: number()
24029
+ }),
24030
+ object({
24031
+ kind: literal("tie-faster"),
24032
+ over: string(),
24033
+ recallDelta: number()
24034
+ }),
24035
+ object({
24036
+ kind: literal("stepped-down"),
24037
+ from: string(),
24038
+ to: string(),
24039
+ limitedBy: string()
24040
+ }),
24041
+ object({
24042
+ kind: literal("no-fit-lightest"),
24043
+ sessions: number(),
24044
+ minSessions: number()
24045
+ }),
24046
+ object({
24047
+ kind: literal("derived-latency"),
24048
+ modelId: string()
24049
+ }),
24050
+ object({ kind: literal("cpu-device") }),
24051
+ object({ kind: literal("coral-untouched") }),
24052
+ object({ kind: literal("device-disabled") }),
24053
+ object({ kind: literal("device-unavailable") }),
24054
+ object({ kind: literal("node-offline") }),
24055
+ object({ kind: literal("no-hardware-facts") }),
24056
+ object({
24057
+ kind: literal("no-measured-data"),
24058
+ hardwareClass: HardwareClassIdSchema
24059
+ }),
24060
+ object({
24061
+ kind: literal("no-family-build"),
24062
+ format: ModelFormatSchema$1
24063
+ })
24064
+ ]);
24065
+ var DeviceModelChoiceSchema = object({
24066
+ modelId: string(),
24067
+ p50Ms: number(),
24068
+ fps: number(),
24069
+ measured: boolean(),
24070
+ /** Parallel sessions at the camera rate with the headroom kept free: ⌊fps × (1 − headroom) / camera fps⌋. */
24071
+ capacitySessions: number(),
24072
+ personRecall: number()
24073
+ });
24074
+ var DeviceRecommendationSchema = object({
24075
+ deviceKey: string(),
24076
+ accelerator: AcceleratorKindSchema.nullable(),
24077
+ enabled: boolean(),
24078
+ available: boolean(),
24079
+ chosen: DeviceModelChoiceSchema.nullable(),
24080
+ reasons: array(RecommendationReasonSchema).readonly()
24081
+ });
24082
+ var NodeRecommendationSchema = object({
24083
+ nodeId: string(),
24084
+ reachable: boolean(),
24085
+ hardwareClass: HardwareClassIdSchema.nullable(),
24086
+ cpuModel: string().nullable(),
24087
+ skipped: boolean(),
24088
+ acceleratorModelId: string().nullable(),
24089
+ devices: array(DeviceRecommendationSchema).readonly(),
24090
+ reasons: array(RecommendationReasonSchema).readonly()
24091
+ });
24092
+ var ModelPinChangeSchema = object({
24093
+ stepId: string(),
24094
+ before: string().nullable(),
24095
+ after: string().nullable()
24096
+ });
24097
+ var NodeDeviceChangeSchema = object({
24098
+ nodeId: string(),
24099
+ deviceKey: string(),
24100
+ madeExplicit: boolean(),
24101
+ modelPins: array(ModelPinChangeSchema).readonly(),
24102
+ thresholds: array(object({
24103
+ stepId: string(),
24104
+ keys: array(string()).readonly()
24105
+ })).readonly()
24106
+ });
24107
+ var CameraOverrideClearSchema = object({
24108
+ deviceId: number(),
24109
+ source: _enum(["step-override", "wholesale"]),
24110
+ nodeId: string(),
24111
+ deviceKey: string().nullable(),
24112
+ stepId: string(),
24113
+ modelIdBefore: string().nullable(),
24114
+ keys: array(string()).readonly()
24115
+ });
24116
+ var DetectorStoreClearSchema = object({
24117
+ deviceId: number(),
24118
+ keys: array(string()).readonly()
24119
+ });
24120
+ var AutoTuneWarningSchema = discriminatedUnion("kind", [
24121
+ object({
24122
+ kind: literal("detector-store-cluster-wide"),
24123
+ skippedNodes: array(string()).readonly()
24124
+ }),
24125
+ object({
24126
+ kind: literal("detector-store-unreadable"),
24127
+ error: string()
24128
+ }),
24129
+ object({
24130
+ kind: literal("coral-enabled"),
24131
+ nodeId: string(),
24132
+ deviceKey: string()
24133
+ })
24134
+ ]);
24135
+ var AutoTuneOptionsSchema = object({
24136
+ /** Share of each accelerator's throughput kept free (0.3–0.5). */
24137
+ headroom: number().min(.3).max(.5).default(.4),
24138
+ /**
24139
+ * The least number of parallel sessions every device must sustain at the
24140
+ * camera rate with the headroom kept free (D755). The most accurate model
24141
+ * that reaches it wins.
24142
+ */
24143
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
24144
+ });
24145
+ var AutoTunePlanSchema = object({
24146
+ /** Hash of everything the apply will write — the apply refuses a different one. */
24147
+ planHash: string(),
24148
+ family: literal("yolov9"),
24149
+ headroom: number(),
24150
+ minSessionsPerDevice: number(),
24151
+ /** The detection rate a session is counted at (the fastest camera running the pipeline root). */
24152
+ cameraFps: number(),
24153
+ generatedAt: number(),
24154
+ nodes: array(NodeRecommendationSchema).readonly(),
24155
+ nodeChanges: array(NodeDeviceChangeSchema).readonly(),
24156
+ cameraClears: array(CameraOverrideClearSchema).readonly(),
24157
+ detectorStoreClears: array(DetectorStoreClearSchema).readonly(),
24158
+ warnings: array(AutoTuneWarningSchema).readonly()
24159
+ });
24160
+ var AutoTuneApplyInputSchema = object({
24161
+ planHash: string(),
24162
+ headroom: number().min(.3).max(.5).default(.4),
24163
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
24164
+ });
24165
+ var AutoTunePhaseResultSchema = object({
24166
+ phase: _enum([
24167
+ "download",
24168
+ "camera-overrides",
24169
+ "detector-thresholds",
24170
+ "node-models",
24171
+ "redispatch"
24172
+ ]),
24173
+ ok: boolean(),
24174
+ detail: string()
24175
+ });
24176
+ var AutoTuneApplyResultSchema = discriminatedUnion("kind", [
24177
+ object({
24178
+ kind: literal("applied"),
24179
+ planHash: string(),
24180
+ phases: array(AutoTunePhaseResultSchema).readonly()
24181
+ }),
24182
+ object({
24183
+ kind: literal("aborted"),
24184
+ phases: array(AutoTunePhaseResultSchema).readonly()
24185
+ }),
24186
+ object({
24187
+ kind: literal("stale"),
24188
+ plan: AutoTunePlanSchema
24189
+ }),
24190
+ object({
24191
+ kind: literal("refused"),
24192
+ reason: _enum(["apply-in-progress"])
24193
+ })
24194
+ ]);
24195
+ /**
24196
+ * Wire shapes of the Load balancing surface (D748): the session placement
24197
+ * policy, the atomic share write, the observed placement statistics, the
24198
+ * hardware share suggestion and the stale device pins.
24199
+ */
24200
+ /**
24201
+ * How a new detection session picks its node and device.
24202
+ * - `least-loaded` — the historical rule: lowest `attached / weight`, a
24203
+ * constant node order at a tie (D37). An idle node always ties at 0, so a
24204
+ * weight only bites once a node already holds a session.
24205
+ * - `share` — the share of PARALLEL sessions is held to the weights, and a
24206
+ * full or drowning node yields to a free one (D748).
24207
+ */
24208
+ var SessionPlacementPolicySchema = _enum(["least-loaded", "share"]);
24209
+ var LoadBalancingSharesInputSchema = object({
24210
+ /** nodeId → share (> 0). A node left out keeps its weight. */
24211
+ nodes: record(string(), number().positive()).default({}),
24212
+ /** nodeId → deviceKey → share (> 0). A device left out keeps its weight. */
24213
+ devices: record(string(), record(string(), number().positive())).default({})
24214
+ });
24215
+ var PlacementStatsInputSchema = object({
24216
+ /** Window the observed shares are averaged over (default 1 h, max 24 h). */
24217
+ windowMs: number().int().min(6e4).max(1440 * 60 * 1e3).default(3600 * 1e3) });
24218
+ var PlacementDeviceStatsSchema = object({
24219
+ deviceKey: string(),
24220
+ /** Sessions running on this device now. */
24221
+ sessionsNow: number(),
24222
+ /** Sessions started on this device inside the window. */
24223
+ sessionsStarted: number(),
24224
+ /** Time-weighted share of the node's parallel sessions over the window (0–1); null = no session ran. */
24225
+ observedShare: number().nullable()
24226
+ });
24227
+ var PlacementNodeStatsSchema = object({
24228
+ nodeId: string(),
24229
+ sessionsNow: number(),
24230
+ sessionsStarted: number(),
24231
+ /** Time-weighted share of the cluster's parallel sessions over the window (0–1); null = none ran. */
24232
+ observedShare: number().nullable(),
24233
+ /** Most sessions this node ran at once inside the window. */
24234
+ peakSessions: number(),
24235
+ /** Sessions a share election handed elsewhere because this node was full or drowning. */
24236
+ yieldsAway: number(),
24237
+ devices: array(PlacementDeviceStatsSchema).readonly()
24238
+ });
24239
+ /** A camera's device pin that the session path cannot honour. */
24240
+ var StaleDevicePinSchema = object({
24241
+ deviceId: number(),
24242
+ deviceKey: string(),
24243
+ /** `disabled` — the key exists on some node but is not enabled anywhere; `absent` — no node has it. */
24244
+ reason: _enum(["disabled", "absent"])
24245
+ });
24246
+ var PlacementStatsSchema = object({
24247
+ policy: SessionPlacementPolicySchema,
24248
+ windowMs: number(),
24249
+ /** How much of the window was actually observed (the hub keeps it in memory). */
24250
+ observedForMs: number(),
24251
+ sessionsNow: number(),
24252
+ /** Most parallel sessions across the cluster inside the window. */
24253
+ clusterPeakSessions: number(),
24254
+ nodes: array(PlacementNodeStatsSchema).readonly(),
24255
+ stalePins: array(StaleDevicePinSchema).readonly()
24256
+ });
24257
+ /**
24258
+ * Where an automatic share's capacity comes from (D755).
24259
+ * - `hardware` — the static capacity of each device at its Auto tune model:
24260
+ * the measured latency table for the node's hardware class.
24261
+ * - `benchmark` — the node's own measured capacity (node benchmark results).
24262
+ * A node with no results falls back to `hardware`, and says so.
24263
+ */
24264
+ var CapacitySourceSchema = _enum(["hardware", "benchmark"]);
24265
+ /** Why a node under the `benchmark` source was sized from hardware instead. */
24266
+ var CapacityFallbackSchema = _enum(["no-benchmark-results", "partial-benchmark-results"]);
24267
+ var SuggestSharesInputSchema = object({
24268
+ headroom: number().min(.3).max(.5).default(.4),
24269
+ /** Default `hardware`. */
24270
+ source: CapacitySourceSchema.default("hardware")
24271
+ });
24272
+ var SuggestedDeviceShareSchema = object({
24273
+ deviceKey: string(),
24274
+ /** Share of the node (0–100, rounded). */
24275
+ share: number(),
24276
+ modelId: string().nullable(),
24277
+ /** Inferences per second at that model, from the measured table; null when sized by a benchmark. */
24278
+ fps: number().nullable(),
24279
+ /** False for a table cell derived from another chip; true for a measured cell or a benchmark. */
24280
+ measured: boolean(),
24281
+ /**
24282
+ * Advisory session cap: ⌊fps × (1 − headroom) / camera fps⌋ from the table,
24283
+ * or the benchmark's measured max sessions. Never enforced.
24284
+ */
24285
+ suggestedMaxSessions: number().nullable()
24286
+ });
24287
+ var SuggestedNodeShareSchema = object({
24288
+ nodeId: string(),
24289
+ /** Share of the cluster (0–100, rounded); null = node skipped (offline, unknown hardware). */
24290
+ share: number().nullable(),
24291
+ /** Parallel sessions the node sustains at the suggested models with the headroom kept free. */
24292
+ capacitySessions: number(),
24293
+ devices: array(SuggestedDeviceShareSchema).readonly(),
24294
+ skippedReason: string().nullable(),
24295
+ /** What this node's capacity was read from; null when the node is skipped. */
24296
+ capacitySource: CapacitySourceSchema.nullable(),
24297
+ /** Set when the `benchmark` source was asked for and this node used `hardware`. */
24298
+ capacityFallback: CapacityFallbackSchema.nullable()
24299
+ });
24300
+ var SuggestSharesResultSchema = object({
24301
+ headroom: number(),
24302
+ /** The source asked for; each node says what it actually used. */
24303
+ source: CapacitySourceSchema,
24304
+ /** Camera detection rate the capacity is counted in (the fastest camera's fps). */
24305
+ cameraFps: number(),
24306
+ /** The Auto tune capacity floor the models were picked at. */
24307
+ minSessionsPerDevice: number(),
24308
+ nodes: array(SuggestedNodeShareSchema).readonly()
24309
+ });
24310
+ /**
24311
+ * Where the node and device shares come from (D750, D755).
24312
+ * - `hardware` (default) — computed by the system from each node's static
24313
+ * capacity (its accelerators at their Auto tune models, from the measured
24314
+ * latency table), recomputed whenever a node or device joins, leaves, is
24315
+ * switched on or off, or changes model. No load input.
24316
+ * - `benchmark` — the same, from each node's measured capacity (node
24317
+ * benchmark results); a node without results falls back to `hardware`.
24318
+ * - `manual` — the operator's stored sliders.
24319
+ * Either way a node or device that cannot take sessions gives its share to
24320
+ * the others in proportion; the stored values are never rewritten for that.
24321
+ */
24322
+ var ShareSourceSchema = _enum([
24323
+ "hardware",
24324
+ "benchmark",
24325
+ "manual"
24326
+ ]);
24327
+ var SetShareSourceInputSchema = object({ source: ShareSourceSchema });
24328
+ object({
24329
+ nodes: record(string(), number()),
24330
+ devices: record(string(), record(string(), number()))
24331
+ });
24332
+ var EffectiveDeviceShareSchema = object({
24333
+ deviceKey: string(),
24334
+ /** Can take sessions now (enabled, available, can run the root). */
24335
+ eligible: boolean(),
24336
+ /** The share the source assigns, as a percentage of the node's devices. */
24337
+ configuredPct: number(),
24338
+ /** The share actually used, after an ineligible device's share went to the others. */
24339
+ effectivePct: number()
24340
+ });
24341
+ var EffectiveNodeShareSchema = object({
24342
+ nodeId: string(),
24343
+ eligible: boolean(),
24344
+ configuredPct: number(),
24345
+ effectivePct: number(),
24346
+ /** Automatic sources: what this node's share was computed from; null under `manual` or before the first answer. */
24347
+ capacitySource: CapacitySourceSchema.nullable(),
24348
+ /** Automatic `benchmark`: why this node used `hardware` instead. */
24349
+ capacityFallback: CapacityFallbackSchema.nullable(),
24350
+ devices: array(EffectiveDeviceShareSchema).readonly()
24351
+ });
24352
+ var EffectiveSharesSchema = object({
24353
+ source: ShareSourceSchema,
24354
+ policy: SessionPlacementPolicySchema,
24355
+ /** An automatic source with no computed answer yet: the stored sliders are used meanwhile. */
24356
+ autoPending: boolean(),
24357
+ /** When the automatic shares were last computed (ms epoch); null = never. */
24358
+ computedAt: number().nullable(),
24359
+ /** What made the system recompute them last. */
24360
+ trigger: string().nullable(),
24361
+ nodes: array(EffectiveNodeShareSchema).readonly(),
24362
+ /** The relative weights the election reads (before eligibility). */
24363
+ nodeWeights: record(string(), number()),
24364
+ deviceWeights: record(string(), record(string(), number()))
24365
+ });
24013
24366
  object({
24014
24367
  activeCameras: number(),
24015
24368
  throttledCameras: number(),
@@ -24927,14 +25280,15 @@ var RunnerLocalLoadSchema = object({
24927
25280
  * Per-inference-device live load (multi-device C4). One entry per deviceKey
24928
25281
  * this runner currently has attached cameras on, so the orchestrator's second
24929
25282
  * `balance()` pass (over a node's devices) weights on real per-pool session
24930
- * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
24931
- * per device is 0 until the pool backlog gets a public accessor (follow-up).
25283
+ * counts. Empty on single-device / pre-multi-device runners. There is no
25284
+ * per-device queue depth: the inference pool's backlog has no accessor, and
25285
+ * a field that always read 0 was removed rather than shown as a measurement
25286
+ * (D762).
24932
25287
  */
24933
25288
  devices: array(object({
24934
25289
  deviceKey: string(),
24935
25290
  backend: string(),
24936
- attachedCameras: number(),
24937
- queueDepthTotal: number()
25291
+ attachedCameras: number()
24938
25292
  })).default([]),
24939
25293
  /** Hardware capability flags reported by this node. */
24940
25294
  hardware: object({
@@ -25070,7 +25424,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
25070
25424
  */
25071
25425
  cropJpeg: string().optional(),
25072
25426
  parent: DetailParentSchema,
25073
- steps: array(string()).optional()
25427
+ steps: array(string()).optional(),
25428
+ /**
25429
+ * The camera's root model already drew this step's boxes (D730): a
25430
+ * `license_plate` inside the parent vehicle. The named step is NOT
25431
+ * inferred — these FRAME-space boxes are its output — and its
25432
+ * requested children (the plate reader) run on them. Absent ⇒ every
25433
+ * requested step infers as before.
25434
+ */
25435
+ supplied: object({
25436
+ stepId: string(),
25437
+ modelId: string(),
25438
+ boxes: array(object({
25439
+ bbox: NativeCropBboxSchema,
25440
+ score: number()
25441
+ })).min(1)
25442
+ }).optional()
25074
25443
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
25075
25444
  /** Catalog step id, e.g. `clip-embedding`. */
25076
25445
  stepId: string(),
@@ -25133,14 +25502,6 @@ var CameraPipelineConfigSchema = object({
25133
25502
  settings: record(string(), unknown()).readonly().optional()
25134
25503
  }).nullable().optional()
25135
25504
  });
25136
- var PipelineTemplateSchema = object({
25137
- id: string(),
25138
- name: string(),
25139
- description: string().optional(),
25140
- config: CameraPipelineConfigSchema,
25141
- createdAt: string(),
25142
- updatedAt: string()
25143
- });
25144
25505
  var DeviceStepConfigSchema = object({
25145
25506
  modelId: string().optional(),
25146
25507
  settings: record(string(), unknown()).optional(),
@@ -25214,9 +25575,10 @@ var CameraStepOverridePatchSchema = object({
25214
25575
  modelId: string().optional(),
25215
25576
  settings: record(string(), unknown()).readonly().optional()
25216
25577
  });
25578
+ var CameraStepSettingsSchema = record(string(), record(string(), unknown()).readonly());
25217
25579
  var CameraPipelineSettingsSchema = object({
25218
- pinnedAgentNodeId: string().optional(),
25219
25580
  stepToggles: record(string(), boolean()).optional(),
25581
+ stepSettings: CameraStepSettingsSchema.optional(),
25220
25582
  stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
25221
25583
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
25222
25584
  });
@@ -25249,7 +25611,10 @@ var PipelineAssignmentSchema = object({
25249
25611
  });
25250
25612
  /**
25251
25613
  * Per-agent load summary surfaced to the load balancer + dashboards.
25252
- * Aggregated from each runner's `getLocalLoad` cap call.
25614
+ * Aggregated from each runner's `getLocalLoad` cap call. In the
25615
+ * `getAgentLoad` report, a single-device node's default-pool sessions (no
25616
+ * `deviceKey`) are credited to its one eligible device in `load.devices` —
25617
+ * the default pool IS that device (D745); the balancer's census stays raw.
25253
25618
  */
25254
25619
  var AgentLoadSummarySchema = object({
25255
25620
  nodeId: string(),
@@ -25338,26 +25703,27 @@ var CameraBrokerStatusSchema = object({
25338
25703
  width: number(),
25339
25704
  height: number(),
25340
25705
  subscribers: number(),
25341
- inFps: number(),
25342
- outFps: number()
25706
+ /**
25707
+ * Encoded packets/s the broker receives from the camera. null when the
25708
+ * broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
25709
+ * There is no output rate: decoding runs in the session decode workers, not
25710
+ * in the broker, so the broker's own decoded-frame rate is 0 on every live
25711
+ * camera and is not served (D758).
25712
+ */
25713
+ inFps: number().nullable()
25343
25714
  })).readonly(),
25344
25715
  webrtcSessions: number(),
25345
25716
  rtspRestream: boolean()
25346
25717
  });
25347
- /** Shared-memory ring statistics within the decoder block. */
25348
- var CameraDecoderShmSchema = object({
25349
- framesWritten: number(),
25350
- getFrameHits: number(),
25351
- getFrameMisses: number(),
25352
- budgetMb: number()
25353
- });
25354
- /** Decoder block — null when the decoder stage is unreachable or inactive. */
25355
- var CameraDecoderStatusSchema = object({
25356
- nodeId: string(),
25357
- formats: array(string()).readonly(),
25358
- sessionCount: number(),
25359
- shm: CameraDecoderShmSchema
25360
- });
25718
+ /**
25719
+ * Decoder block — WHERE decode runs (co-located with the detection node by
25720
+ * construction); null when the camera has no detection node. It carries no
25721
+ * frame counter: the shared-memory plane whose counters it used to serve is
25722
+ * gone, and those fields read 0 forever. Whether frames actually flow is read
25723
+ * from `detection.actualFps` (frames delivered to and processed by the
25724
+ * detector), never from a counter nothing feeds.
25725
+ */
25726
+ var CameraDecoderStatusSchema = object({ nodeId: string() });
25361
25727
  /** Motion block — null when motion detection is not active for this device. */
25362
25728
  var CameraMotionStatusSchema = object({
25363
25729
  enabled: boolean(),
@@ -25714,12 +26080,6 @@ method(object({
25714
26080
  }), object({ success: literal(true) }), {
25715
26081
  kind: "mutation",
25716
26082
  auth: "admin"
25717
- }), method(object({
25718
- agentNodeId: string(),
25719
- detectWeight: number().positive().nullable()
25720
- }), object({ success: literal(true) }), {
25721
- kind: "mutation",
25722
- auth: "admin"
25723
26083
  }), method(object({
25724
26084
  agentNodeId: string(),
25725
26085
  detect: boolean().nullable().optional(),
@@ -25761,6 +26121,15 @@ method(object({
25761
26121
  }), {
25762
26122
  kind: "mutation",
25763
26123
  auth: "admin"
26124
+ }), method(AutoTuneOptionsSchema, AutoTunePlanSchema, { auth: "admin" }), method(AutoTuneApplyInputSchema, AutoTuneApplyResultSchema, {
26125
+ kind: "mutation",
26126
+ auth: "admin"
26127
+ }), method(LoadBalancingSharesInputSchema, object({ success: literal(true) }), {
26128
+ kind: "mutation",
26129
+ auth: "admin"
26130
+ }), method(PlacementStatsInputSchema, PlacementStatsSchema, { auth: "admin" }), method(SuggestSharesInputSchema, SuggestSharesResultSchema, { auth: "admin" }), method(_void(), EffectiveSharesSchema, { auth: "admin" }), method(SetShareSourceInputSchema, object({ success: literal(true) }), {
26131
+ kind: "mutation",
26132
+ auth: "admin"
25764
26133
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
25765
26134
  deviceId: number(),
25766
26135
  addonId: string(),
@@ -25777,6 +26146,13 @@ method(object({
25777
26146
  }), object({ success: literal(true) }), {
25778
26147
  kind: "mutation",
25779
26148
  auth: "admin"
26149
+ }), method(object({
26150
+ deviceId: number(),
26151
+ addonId: string(),
26152
+ settings: record(string(), unknown()).nullable()
26153
+ }), object({ success: literal(true) }), {
26154
+ kind: "mutation",
26155
+ auth: "admin"
25780
26156
  }), method(object({
25781
26157
  deviceId: number(),
25782
26158
  agentNodeId: string(),
@@ -25800,25 +26176,7 @@ method(object({
25800
26176
  }), method(_void(), DiskReconcileJobSchema, {
25801
26177
  kind: "mutation",
25802
26178
  auth: "admin"
25803
- }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
25804
- name: string(),
25805
- description: string().optional(),
25806
- config: CameraPipelineConfigSchema
25807
- }), PipelineTemplateSchema, {
25808
- kind: "mutation",
25809
- auth: "admin"
25810
- }), method(object({
25811
- id: string(),
25812
- name: string().optional(),
25813
- description: string().optional(),
25814
- config: CameraPipelineConfigSchema.optional()
25815
- }), PipelineTemplateSchema, {
25816
- kind: "mutation",
25817
- auth: "admin"
25818
- }), method(object({ id: string() }), object({ success: literal(true) }), {
25819
- kind: "mutation",
25820
- auth: "admin"
25821
- });
26179
+ }), method(_void(), DiskReconcileJobSchema, { auth: "admin" });
25822
26180
  /**
25823
26181
  * Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
25824
26182
  * `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
@@ -28067,8 +28425,6 @@ var WebrtcStreamChoiceSchema = object({
28067
28425
  ]).nullable(),
28068
28426
  /** Input FPS from the camera (null for adaptive). */
28069
28427
  inputFps: number().nullable(),
28070
- /** Decoded FPS (null for adaptive). */
28071
- decodeFps: number().nullable(),
28072
28428
  /** Bitrate in kbps (null for adaptive). */
28073
28429
  bitrateKbps: number().nullable()
28074
28430
  });
@@ -28400,6 +28756,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
28400
28756
  */
28401
28757
  alive: boolean()
28402
28758
  })), method(object({
28759
+ deviceId: number().int().nonnegative(),
28760
+ sessionId: string(),
28761
+ downlinkMbps: number().nonnegative()
28762
+ }), object({
28763
+ outcome: _enum(["switching", "held"]),
28764
+ tier: CamProfileSchema.nullable(),
28765
+ reason: string()
28766
+ }), { kind: "mutation" }), method(object({
28403
28767
  deviceId: number().int().nonnegative(),
28404
28768
  sessionId: string()
28405
28769
  }), WebrtcSessionDebugSchema, { kind: "query" });
@@ -32228,7 +32592,8 @@ var ConnectionEndpointSchema = object({
32228
32592
  "lan-ipv6",
32229
32593
  "public",
32230
32594
  "loopback",
32231
- "app-link"
32595
+ "app-link",
32596
+ "custom"
32232
32597
  ]),
32233
32598
  /**
32234
32599
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32297,7 +32662,7 @@ var GetConnectionEndpointsResultSchema = object({
32297
32662
  localPort: AdvertisedLocalPortSchema
32298
32663
  });
32299
32664
  /**
32300
- * The address flagged for notification links. `baseUrl: null` = AUTO, which
32665
+ * The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
32301
32666
  * since D709 is the CamStack app link; `resolved` reports the effective value,
32302
32667
  * so the UI can show it either way.
32303
32668
  */
@@ -32330,6 +32695,72 @@ var ViewerEndpointsSchema = object({
32330
32695
  /** What the ranking currently resolves to (may be empty if nothing is up). */
32331
32696
  resolved: array(string()).readonly()
32332
32697
  });
32698
+ /**
32699
+ * DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
32700
+ * for addons built against it): `cluster` is the `internal` role, `browser`
32701
+ * the `publicEndpoint` role; `override` is the flagged address.
32702
+ */
32703
+ var HubAddressSnapshotSchema = object({
32704
+ override: string().nullable(),
32705
+ resolved: string().nullable(),
32706
+ source: _enum([
32707
+ "override",
32708
+ "auto",
32709
+ "none"
32710
+ ])
32711
+ });
32712
+ var HubAddressesSchema = object({
32713
+ cluster: HubAddressSnapshotSchema,
32714
+ browser: HubAddressSnapshotSchema
32715
+ });
32716
+ /**
32717
+ * What an address is used for (`hub-address.ts`, D734). `appConnections` is
32718
+ * many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
32719
+ * by at most one address.
32720
+ */
32721
+ var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
32722
+ var RoleSourceSchema = _enum([
32723
+ "flagged",
32724
+ "auto",
32725
+ "none"
32726
+ ]);
32727
+ /** One single-valued role: the flagged address, the one in use, and why. */
32728
+ var HubAddressRoleResolutionSchema = object({
32729
+ /** The address carrying the flag, or null = automatic. */
32730
+ flagged: string().nullable(),
32731
+ /** The address in use, or null when nothing qualifies (never loopback). */
32732
+ resolved: string().nullable(),
32733
+ source: RoleSourceSchema
32734
+ });
32735
+ var HubAppConnectionsResolutionSchema = object({
32736
+ /** The addresses flagged `appConnections`, or empty = automatic. */
32737
+ flagged: array(string()).readonly(),
32738
+ /** What the apps race right now. */
32739
+ resolved: array(string()).readonly(),
32740
+ source: RoleSourceSchema
32741
+ });
32742
+ var HubAddressBookSchema = object({
32743
+ rows: array(ConnectionEndpointSchema.extend({
32744
+ /** In the hub's detected palette right now. */
32745
+ detected: boolean(),
32746
+ /** Entered by the operator (removable). */
32747
+ custom: boolean(),
32748
+ /** The roles explicitly flagged on this address. */
32749
+ flags: array(HubAddressRoleSchema).readonly(),
32750
+ /** The roles this address serves right now — flagged or automatic. */
32751
+ inUse: array(HubAddressRoleSchema).readonly(),
32752
+ /** The roles this address may be flagged with. */
32753
+ eligible: array(HubAddressRoleSchema).readonly()
32754
+ })).readonly(),
32755
+ roles: object({
32756
+ appConnections: HubAppConnectionsResolutionSchema,
32757
+ notificationTaps: HubAddressRoleResolutionSchema,
32758
+ internal: HubAddressRoleResolutionSchema,
32759
+ publicEndpoint: HubAddressRoleResolutionSchema
32760
+ }),
32761
+ /** The `hub=` an app link carries (D709), or null. */
32762
+ appLinkHub: string().nullable()
32763
+ });
32333
32764
  var AllowedAddressesSchema = object({
32334
32765
  /**
32335
32766
  * Allowlist of interface addresses operators have explicitly opted
@@ -32373,10 +32804,27 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
32373
32804
  * tunnel always emits `https://` regardless. */
32374
32805
  scheme: _enum(["http", "https"]).optional(),
32375
32806
  /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
32376
- * an address notification links can be flagged with, not a hub
32807
+ * an address notification taps can be flagged with, not a hub
32377
32808
  * route. Default `false`: racers and rankers never see it. */
32378
32809
  includeAppLink: boolean().optional()
32379
- }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
32810
+ }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(object({ scheme: _enum(["http", "https"]).optional() }).optional(), HubAddressBookSchema), method(object({
32811
+ baseUrl: string(),
32812
+ label: string().max(80)
32813
+ }), HubAddressBookSchema, {
32814
+ kind: "mutation",
32815
+ auth: "admin"
32816
+ }), method(object({ baseUrl: string() }), HubAddressBookSchema, {
32817
+ kind: "mutation",
32818
+ auth: "admin"
32819
+ }), method(object({
32820
+ role: HubAddressRoleSchema,
32821
+ baseUrl: string().nullable(),
32822
+ enabled: boolean(),
32823
+ acceptInsecureHttp: boolean().optional()
32824
+ }), HubAddressBookSchema, {
32825
+ kind: "mutation",
32826
+ auth: "admin"
32827
+ }), method(_void(), HubAddressesSchema), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
32380
32828
  kind: "mutation",
32381
32829
  auth: "admin"
32382
32830
  }), method(object({
@@ -32834,7 +33282,8 @@ var MotionStatusSchema = object({
32834
33282
  * writes this slice (not even a boot seed), and neither does the runner's
32835
33283
  * phase machine: its phase is "a session is attached" for every on-motion
32836
33284
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
32837
- * A provider's `isDetected` answers from the hub's slice.
33285
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
33286
+ * (`hubMotionNativeProvider`).
32838
33287
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
32839
33288
  * imports) — the provider pushes both edges itself, from the upstream
32840
33289
  * system's own state change. That is the sensor's own fact.
@@ -39381,6 +39830,16 @@ var zoneRulesCapability = {
39381
39830
  durability: "restored"
39382
39831
  };
39383
39832
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
39833
+ Object.freeze({
39834
+ person: .5,
39835
+ vehicle: .5,
39836
+ animal: .5
39837
+ });
39838
+ Object.freeze({
39839
+ person: .65,
39840
+ vehicle: .65,
39841
+ animal: .65
39842
+ });
39384
39843
  /**
39385
39844
  * Accessory device helpers — shared across drivers.
39386
39845
  *
@@ -42261,90 +42720,18 @@ Object.freeze({
42261
42720
  addonId: null,
42262
42721
  access: "create"
42263
42722
  },
42264
- "decoder.createSession": {
42265
- capName: "decoder",
42266
- capScope: "system",
42267
- addonId: null,
42268
- access: "view"
42269
- },
42270
- "decoder.destroySession": {
42271
- capName: "decoder",
42272
- capScope: "system",
42273
- addonId: null,
42274
- access: "delete"
42275
- },
42276
- "decoder.getFrame": {
42277
- capName: "decoder",
42278
- capScope: "system",
42279
- addonId: null,
42280
- access: "view"
42281
- },
42282
42723
  "decoder.getInfo": {
42283
42724
  capName: "decoder",
42284
42725
  capScope: "system",
42285
42726
  addonId: null,
42286
42727
  access: "view"
42287
42728
  },
42288
- "decoder.getShmStats": {
42289
- capName: "decoder",
42290
- capScope: "system",
42291
- addonId: null,
42292
- access: "view"
42293
- },
42294
- "decoder.getStats": {
42295
- capName: "decoder",
42296
- capScope: "system",
42297
- addonId: null,
42298
- access: "view"
42299
- },
42300
- "decoder.listActiveSessions": {
42301
- capName: "decoder",
42302
- capScope: "system",
42303
- addonId: null,
42304
- access: "view"
42305
- },
42306
- "decoder.openStream": {
42307
- capName: "decoder",
42308
- capScope: "system",
42309
- addonId: null,
42310
- access: "view"
42311
- },
42312
- "decoder.pullFrames": {
42313
- capName: "decoder",
42314
- capScope: "system",
42315
- addonId: null,
42316
- access: "view"
42317
- },
42318
- "decoder.pullHandles": {
42319
- capName: "decoder",
42320
- capScope: "system",
42321
- addonId: null,
42322
- access: "view"
42323
- },
42324
- "decoder.pushPacket": {
42325
- capName: "decoder",
42326
- capScope: "system",
42327
- addonId: null,
42328
- access: "view"
42329
- },
42330
42729
  "decoder.reprobeHwaccel": {
42331
42730
  capName: "decoder",
42332
42731
  capScope: "system",
42333
42732
  addonId: null,
42334
42733
  access: "create"
42335
42734
  },
42336
- "decoder.supportsCodec": {
42337
- capName: "decoder",
42338
- capScope: "system",
42339
- addonId: null,
42340
- access: "view"
42341
- },
42342
- "decoder.updateConfig": {
42343
- capName: "decoder",
42344
- capScope: "system",
42345
- addonId: null,
42346
- access: "view"
42347
- },
42348
42735
  "detectionPipeline.applyDeviceSettingsPatch": {
42349
42736
  capName: "detection-pipeline",
42350
42737
  capScope: "device",
@@ -43833,12 +44220,24 @@ Object.freeze({
43833
44220
  addonId: null,
43834
44221
  access: "view"
43835
44222
  },
44223
+ "localNetwork.addCustomAddress": {
44224
+ capName: "local-network",
44225
+ capScope: "system",
44226
+ addonId: null,
44227
+ access: "create"
44228
+ },
43836
44229
  "localNetwork.downloadCa": {
43837
44230
  capName: "local-network",
43838
44231
  capScope: "system",
43839
44232
  addonId: null,
43840
44233
  access: "view"
43841
44234
  },
44235
+ "localNetwork.getAddresses": {
44236
+ capName: "local-network",
44237
+ capScope: "system",
44238
+ addonId: null,
44239
+ access: "view"
44240
+ },
43842
44241
  "localNetwork.getAllowedAddresses": {
43843
44242
  capName: "local-network",
43844
44243
  capScope: "system",
@@ -43851,6 +44250,12 @@ Object.freeze({
43851
44250
  addonId: null,
43852
44251
  access: "view"
43853
44252
  },
44253
+ "localNetwork.getHubAddresses": {
44254
+ capName: "local-network",
44255
+ capScope: "system",
44256
+ addonId: null,
44257
+ access: "view"
44258
+ },
43854
44259
  "localNetwork.getNotificationEndpoint": {
43855
44260
  capName: "local-network",
43856
44261
  capScope: "system",
@@ -43887,6 +44292,12 @@ Object.freeze({
43887
44292
  addonId: null,
43888
44293
  access: "create"
43889
44294
  },
44295
+ "localNetwork.removeCustomAddress": {
44296
+ capName: "local-network",
44297
+ capScope: "system",
44298
+ addonId: null,
44299
+ access: "delete"
44300
+ },
43890
44301
  "localNetwork.resetAllowlistToBestMatch": {
43891
44302
  capName: "local-network",
43892
44303
  capScope: "system",
@@ -43899,6 +44310,12 @@ Object.freeze({
43899
44310
  addonId: null,
43900
44311
  access: "create"
43901
44312
  },
44313
+ "localNetwork.setAddressRole": {
44314
+ capName: "local-network",
44315
+ capScope: "system",
44316
+ addonId: null,
44317
+ access: "create"
44318
+ },
43902
44319
  "localNetwork.setAllowedAddresses": {
43903
44320
  capName: "local-network",
43904
44321
  capScope: "system",
@@ -45393,13 +45810,13 @@ Object.freeze({
45393
45810
  addonId: null,
45394
45811
  access: "delete"
45395
45812
  },
45396
- "pipelineExecutor.deleteModel": {
45813
+ "pipelineExecutor.clearModelBoundDeviceOverrides": {
45397
45814
  capName: "pipeline-executor",
45398
45815
  capScope: "system",
45399
45816
  addonId: null,
45400
45817
  access: "delete"
45401
45818
  },
45402
- "pipelineExecutor.deleteTemplate": {
45819
+ "pipelineExecutor.deleteModel": {
45403
45820
  capName: "pipeline-executor",
45404
45821
  capScope: "system",
45405
45822
  addonId: null,
@@ -45543,12 +45960,6 @@ Object.freeze({
45543
45960
  addonId: null,
45544
45961
  access: "view"
45545
45962
  },
45546
- "pipelineExecutor.listTemplates": {
45547
- capName: "pipeline-executor",
45548
- capScope: "system",
45549
- addonId: null,
45550
- access: "view"
45551
- },
45552
45963
  "pipelineExecutor.rearmInferenceDevice": {
45553
45964
  capName: "pipeline-executor",
45554
45965
  capScope: "system",
@@ -45573,12 +45984,6 @@ Object.freeze({
45573
45984
  addonId: null,
45574
45985
  access: "create"
45575
45986
  },
45576
- "pipelineExecutor.saveTemplate": {
45577
- capName: "pipeline-executor",
45578
- capScope: "system",
45579
- addonId: null,
45580
- access: "create"
45581
- },
45582
45987
  "pipelineExecutor.setVideoPipelineSteps": {
45583
45988
  capName: "pipeline-executor",
45584
45989
  capScope: "system",
@@ -45597,41 +46002,35 @@ Object.freeze({
45597
46002
  addonId: null,
45598
46003
  access: "create"
45599
46004
  },
45600
- "pipelineExecutor.updateTemplate": {
45601
- capName: "pipeline-executor",
45602
- capScope: "system",
45603
- addonId: null,
45604
- access: "create"
45605
- },
45606
46005
  "pipelineExecutor.validatePipeline": {
45607
46006
  capName: "pipeline-executor",
45608
46007
  capScope: "system",
45609
46008
  addonId: null,
45610
46009
  access: "view"
45611
46010
  },
45612
- "pipelineOrchestrator.applyDeviceSettingsPatch": {
46011
+ "pipelineOrchestrator.applyAutoTune": {
45613
46012
  capName: "pipeline-orchestrator",
45614
46013
  capScope: "system",
45615
46014
  addonId: null,
45616
46015
  access: "create"
45617
46016
  },
45618
- "pipelineOrchestrator.assignAudio": {
46017
+ "pipelineOrchestrator.applyDeviceSettingsPatch": {
45619
46018
  capName: "pipeline-orchestrator",
45620
46019
  capScope: "system",
45621
46020
  addonId: null,
45622
46021
  access: "create"
45623
46022
  },
45624
- "pipelineOrchestrator.assignPipeline": {
46023
+ "pipelineOrchestrator.assignAudio": {
45625
46024
  capName: "pipeline-orchestrator",
45626
46025
  capScope: "system",
45627
46026
  addonId: null,
45628
46027
  access: "create"
45629
46028
  },
45630
- "pipelineOrchestrator.deleteTemplate": {
46029
+ "pipelineOrchestrator.assignPipeline": {
45631
46030
  capName: "pipeline-orchestrator",
45632
46031
  capScope: "system",
45633
46032
  addonId: null,
45634
- access: "delete"
46033
+ access: "create"
45635
46034
  },
45636
46035
  "pipelineOrchestrator.getAgentLoad": {
45637
46036
  capName: "pipeline-orchestrator",
@@ -45723,6 +46122,12 @@ Object.freeze({
45723
46122
  addonId: null,
45724
46123
  access: "view"
45725
46124
  },
46125
+ "pipelineOrchestrator.getEffectiveShares": {
46126
+ capName: "pipeline-orchestrator",
46127
+ capScope: "system",
46128
+ addonId: null,
46129
+ access: "view"
46130
+ },
45726
46131
  "pipelineOrchestrator.getGlobalMetrics": {
45727
46132
  capName: "pipeline-orchestrator",
45728
46133
  capScope: "system",
@@ -45759,19 +46164,19 @@ Object.freeze({
45759
46164
  addonId: null,
45760
46165
  access: "view"
45761
46166
  },
45762
- "pipelineOrchestrator.getReconcileFromDiskStatus": {
46167
+ "pipelineOrchestrator.getPlacementStats": {
45763
46168
  capName: "pipeline-orchestrator",
45764
46169
  capScope: "system",
45765
46170
  addonId: null,
45766
46171
  access: "view"
45767
46172
  },
45768
- "pipelineOrchestrator.listAgentSettings": {
46173
+ "pipelineOrchestrator.getReconcileFromDiskStatus": {
45769
46174
  capName: "pipeline-orchestrator",
45770
46175
  capScope: "system",
45771
46176
  addonId: null,
45772
46177
  access: "view"
45773
46178
  },
45774
- "pipelineOrchestrator.listTemplates": {
46179
+ "pipelineOrchestrator.listAgentSettings": {
45775
46180
  capName: "pipeline-orchestrator",
45776
46181
  capScope: "system",
45777
46182
  addonId: null,
@@ -45783,6 +46188,12 @@ Object.freeze({
45783
46188
  addonId: null,
45784
46189
  access: "create"
45785
46190
  },
46191
+ "pipelineOrchestrator.planAutoTune": {
46192
+ capName: "pipeline-orchestrator",
46193
+ capScope: "system",
46194
+ addonId: null,
46195
+ access: "view"
46196
+ },
45786
46197
  "pipelineOrchestrator.rebalance": {
45787
46198
  capName: "pipeline-orchestrator",
45788
46199
  capScope: "system",
@@ -45825,12 +46236,6 @@ Object.freeze({
45825
46236
  addonId: null,
45826
46237
  access: "create"
45827
46238
  },
45828
- "pipelineOrchestrator.saveTemplate": {
45829
- capName: "pipeline-orchestrator",
45830
- capScope: "system",
45831
- addonId: null,
45832
- access: "create"
45833
- },
45834
46239
  "pipelineOrchestrator.setAgentCapabilities": {
45835
46240
  capName: "pipeline-orchestrator",
45836
46241
  capScope: "system",
@@ -45843,12 +46248,6 @@ Object.freeze({
45843
46248
  addonId: null,
45844
46249
  access: "create"
45845
46250
  },
45846
- "pipelineOrchestrator.setAgentDetectWeight": {
45847
- capName: "pipeline-orchestrator",
45848
- capScope: "system",
45849
- addonId: null,
45850
- access: "create"
45851
- },
45852
46251
  "pipelineOrchestrator.setAgentInferenceDevices": {
45853
46252
  capName: "pipeline-orchestrator",
45854
46253
  capScope: "system",
@@ -45885,6 +46284,12 @@ Object.freeze({
45885
46284
  addonId: null,
45886
46285
  access: "create"
45887
46286
  },
46287
+ "pipelineOrchestrator.setCameraStepSettings": {
46288
+ capName: "pipeline-orchestrator",
46289
+ capScope: "system",
46290
+ addonId: null,
46291
+ access: "create"
46292
+ },
45888
46293
  "pipelineOrchestrator.setCameraStepToggle": {
45889
46294
  capName: "pipeline-orchestrator",
45890
46295
  capScope: "system",
@@ -45903,25 +46308,37 @@ Object.freeze({
45903
46308
  addonId: null,
45904
46309
  access: "create"
45905
46310
  },
46311
+ "pipelineOrchestrator.setLoadBalancingShares": {
46312
+ capName: "pipeline-orchestrator",
46313
+ capScope: "system",
46314
+ addonId: null,
46315
+ access: "create"
46316
+ },
45906
46317
  "pipelineOrchestrator.setPipelineDevicePin": {
45907
46318
  capName: "pipeline-orchestrator",
45908
46319
  capScope: "system",
45909
46320
  addonId: null,
45910
46321
  access: "create"
45911
46322
  },
45912
- "pipelineOrchestrator.unassignAudio": {
46323
+ "pipelineOrchestrator.setShareSource": {
45913
46324
  capName: "pipeline-orchestrator",
45914
46325
  capScope: "system",
45915
46326
  addonId: null,
45916
46327
  access: "create"
45917
46328
  },
45918
- "pipelineOrchestrator.unassignPipeline": {
46329
+ "pipelineOrchestrator.suggestShares": {
46330
+ capName: "pipeline-orchestrator",
46331
+ capScope: "system",
46332
+ addonId: null,
46333
+ access: "view"
46334
+ },
46335
+ "pipelineOrchestrator.unassignAudio": {
45919
46336
  capName: "pipeline-orchestrator",
45920
46337
  capScope: "system",
45921
46338
  addonId: null,
45922
46339
  access: "create"
45923
46340
  },
45924
- "pipelineOrchestrator.updateTemplate": {
46341
+ "pipelineOrchestrator.unassignPipeline": {
45925
46342
  capName: "pipeline-orchestrator",
45926
46343
  capScope: "system",
45927
46344
  addonId: null,
@@ -47361,12 +47778,6 @@ Object.freeze({
47361
47778
  addonId: null,
47362
47779
  access: "view"
47363
47780
  },
47364
- "streamBroker.pullFrameHandles": {
47365
- capName: "stream-broker",
47366
- capScope: "system",
47367
- addonId: null,
47368
- access: "view"
47369
- },
47370
47781
  "streamBroker.regenerateRtspToken": {
47371
47782
  capName: "stream-broker",
47372
47783
  capScope: "system",
@@ -47433,12 +47844,6 @@ Object.freeze({
47433
47844
  addonId: null,
47434
47845
  access: "create"
47435
47846
  },
47436
- "streamBroker.subscribeFrames": {
47437
- capName: "stream-broker",
47438
- capScope: "system",
47439
- addonId: null,
47440
- access: "create"
47441
- },
47442
47847
  "streamBroker.unassignProfile": {
47443
47848
  capName: "stream-broker",
47444
47849
  capScope: "system",
@@ -47451,12 +47856,6 @@ Object.freeze({
47451
47856
  addonId: null,
47452
47857
  access: "create"
47453
47858
  },
47454
- "streamBroker.unsubscribeFrames": {
47455
- capName: "stream-broker",
47456
- capScope: "system",
47457
- addonId: null,
47458
- access: "create"
47459
- },
47460
47859
  "streamCatalog.getCatalog": {
47461
47860
  capName: "stream-catalog",
47462
47861
  capScope: "device",
@@ -48153,6 +48552,12 @@ Object.freeze({
48153
48552
  addonId: null,
48154
48553
  access: "create"
48155
48554
  },
48555
+ "webrtcSession.applyDownlinkProbe": {
48556
+ capName: "webrtc-session",
48557
+ capScope: "device",
48558
+ addonId: null,
48559
+ access: "create"
48560
+ },
48156
48561
  "webrtcSession.closeSession": {
48157
48562
  capName: "webrtc-session",
48158
48563
  capScope: "device",
@@ -49964,11 +50369,6 @@ Object.freeze({
49964
50369
  form: "single",
49965
50370
  optional: false
49966
50371
  }],
49967
- "decoder.createSession": [{
49968
- name: "deviceId",
49969
- form: "single",
49970
- optional: true
49971
- }],
49972
50372
  "detectionPipeline.applyDeviceSettingsPatch": [{
49973
50373
  name: "deviceId",
49974
50374
  form: "single",
@@ -51199,6 +51599,11 @@ Object.freeze({
51199
51599
  form: "single",
51200
51600
  optional: false
51201
51601
  }],
51602
+ "pipelineExecutor.clearModelBoundDeviceOverrides": [{
51603
+ name: "deviceIds",
51604
+ form: "array",
51605
+ optional: true
51606
+ }],
51202
51607
  "pipelineExecutor.runPipeline": [{
51203
51608
  name: "deviceId",
51204
51609
  form: "single",
@@ -51304,6 +51709,11 @@ Object.freeze({
51304
51709
  form: "single",
51305
51710
  optional: false
51306
51711
  }],
51712
+ "pipelineOrchestrator.setCameraStepSettings": [{
51713
+ name: "deviceId",
51714
+ form: "single",
51715
+ optional: false
51716
+ }],
51307
51717
  "pipelineOrchestrator.setCameraStepToggle": [{
51308
51718
  name: "deviceId",
51309
51719
  form: "single",
@@ -52075,6 +52485,11 @@ Object.freeze({
52075
52485
  form: "single",
52076
52486
  optional: false
52077
52487
  }],
52488
+ "webrtcSession.applyDownlinkProbe": [{
52489
+ name: "deviceId",
52490
+ form: "single",
52491
+ optional: false
52492
+ }],
52078
52493
  "webrtcSession.closeSession": [{
52079
52494
  name: "deviceId",
52080
52495
  form: "single",
@@ -52304,6 +52719,8 @@ new Map(Object.entries({
52304
52719
  "detection-blind": "device-events",
52305
52720
  "node-online": "system",
52306
52721
  "node-offline": "system",
52722
+ "node-restarting": "system",
52723
+ "node-updating": "system",
52307
52724
  "node-inference-unavailable": "system",
52308
52725
  "addon-crash-loop": "system",
52309
52726
  "addon-update-available": "system",
@@ -52381,6 +52798,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52381
52798
  kinds: [
52382
52799
  "node-offline",
52383
52800
  "node-online",
52801
+ "node-restarting",
52384
52802
  "node-inference-unavailable"
52385
52803
  ]
52386
52804
  },
@@ -52402,6 +52820,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52402
52820
  label: "Server & container updates",
52403
52821
  kinds: [
52404
52822
  "server-update-available",
52823
+ "node-updating",
52405
52824
  "server-updated",
52406
52825
  "wrapper-update-available"
52407
52826
  ]
@@ -52549,6 +52968,7 @@ var STATE_SUMMARY_SECTION_VARS = [
52549
52968
  kinds: [
52550
52969
  "node-offline",
52551
52970
  "node-online",
52971
+ "node-restarting",
52552
52972
  "node-inference-unavailable"
52553
52973
  ]
52554
52974
  },
@@ -52570,6 +52990,7 @@ var STATE_SUMMARY_SECTION_VARS = [
52570
52990
  example: "server 1.2.377 → 1.2.378",
52571
52991
  kinds: [
52572
52992
  "server-update-available",
52993
+ "node-updating",
52573
52994
  "server-updated",
52574
52995
  "wrapper-update-available"
52575
52996
  ]
@@ -52602,7 +53023,7 @@ var STATE_SUMMARY_VARS = [
52602
53023
  {
52603
53024
  name: "summarySection",
52604
53025
  label: "Summary: this section",
52605
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
53026
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
52606
53027
  example: "Batterie scariche",
52607
53028
  group: "system",
52608
53029
  families: ["rule"],