@camstack/addon-provider-rademacher 0.2.119 → 0.2.121

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 +1000 -533
  2. package/dist/addon.mjs +1000 -533
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -984,7 +984,7 @@ var Rademacher = class {
984
984
  }
985
985
  };
986
986
  //#endregion
987
- //#region ../types/dist/event-category-BGmz_oxW.mjs
987
+ //#region ../types/dist/event-category-B_0XEcLF.mjs
988
988
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
989
989
  EventCategory["SystemBoot"] = "system.boot";
990
990
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -1485,15 +1485,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
1485
1485
  EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
1486
1486
  EventCategory["AgentBackupActivated"] = "agent.backup.activated";
1487
1487
  EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
1488
- /**
1489
- * Per-agent hwaccel preference changed (user override set, cleared, or
1490
- * re-probed). Observability event — decoders pull the current pref at
1491
- * `createSession`, so running sessions keep their current backend until
1492
- * they rotate naturally (camera add/remove, stream restart). Future
1493
- * work can wire a listener in stream-broker that force-rotates live
1494
- * sessions; for now this event powers logs + admin-UI toast feedback.
1495
- */
1496
- EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
1497
1488
  EventCategory["MotionAnalysis"] = "detection.motion-analysis";
1498
1489
  /** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
1499
1490
  EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
@@ -6364,7 +6355,7 @@ var ZodIssueCode = {
6364
6355
  var ZodFirstPartyTypeKind;
6365
6356
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
6366
6357
  //#endregion
6367
- //#region ../types/dist/sleep-DXKLNFvA.mjs
6358
+ //#region ../types/dist/sleep-BNeXenvr.mjs
6368
6359
  /**
6369
6360
  * The audio chunk plane's byte format, and the ONE expansion from a coded
6370
6361
  * window to float samples (D455).
@@ -7730,32 +7721,12 @@ object({
7730
7721
  audioCodec: string().optional(),
7731
7722
  metadata: record(string(), unknown()).readonly().optional()
7732
7723
  });
7733
- var EncodedPacketSchema = object({
7734
- type: _enum(["video", "audio"]),
7735
- data: _instanceof(Uint8Array),
7736
- pts: number(),
7737
- dts: number(),
7738
- keyframe: boolean(),
7739
- codec: string()
7740
- });
7741
- var DecodedFrameSchema = object({
7742
- data: _instanceof(Uint8Array),
7743
- width: number(),
7744
- height: number(),
7745
- format: _enum([
7746
- "jpeg",
7747
- "rgb",
7748
- "bgr",
7749
- "yuv420",
7750
- "gray"
7751
- ]),
7752
- timestamp: number()
7753
- });
7754
7724
  /**
7755
7725
  * Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
7756
7726
  * frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
7757
- * interface in `interfaces/frame-handle.ts` field-for-field so a decoder cap
7758
- * method (`pullHandles`) can carry handles over tRPC / Moleculer.
7727
+ * interface in `interfaces/frame-handle.ts` field-for-field so a cap method
7728
+ * (the runner's native-crop and pipeline-executor inputs) can carry handles
7729
+ * over tRPC / Moleculer.
7759
7730
  *
7760
7731
  * The `satisfies` assertion below pins this schema to the interface: if a
7761
7732
  * field is added to / removed from `FrameHandle` without a matching schema
@@ -7781,50 +7752,6 @@ var FrameHandleSchema = object({
7781
7752
  slotCount: number().int().positive()
7782
7753
  });
7783
7754
  /**
7784
- * Pixel format a frame-handle subscriber can request from the broker
7785
- * (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
7786
- * `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
7787
- * `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
7788
- * payload, and no decoded-frame consumer requests it over the shm plane.
7789
- */
7790
- var FrameHandleFormatSchema = _enum([
7791
- "rgb",
7792
- "bgr",
7793
- "yuv420",
7794
- "gray"
7795
- ]);
7796
- /**
7797
- * Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
7798
- * broker for a `FrameHandle` stream of one `format`; the broker maintains one
7799
- * shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
7800
- * subscriber (motion) and an `rgb` subscriber (detection) each read the format
7801
- * they asked for with no broker-side conversion.
7802
- */
7803
- var SubscribeFramesInputSchema = object({
7804
- brokerId: string(),
7805
- format: FrameHandleFormatSchema,
7806
- /**
7807
- * Optional reader-side cadence hint in frames per second. The broker does
7808
- * NOT throttle — latest-wins ring reads drop frames implicitly for a slow
7809
- * consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
7810
- * the consumer can pace its own `pullFrameHandles` polling.
7811
- */
7812
- maxFps: number().positive().optional(),
7813
- /** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
7814
- tag: string().optional()
7815
- });
7816
- /**
7817
- * Result of `stream-broker.subscribeFrames`. The consumer then polls
7818
- * `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
7819
- * `FrameHandle` to a `FrameRingReader`.
7820
- */
7821
- var SubscribeFramesResultSchema = object({
7822
- /** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
7823
- subscriptionId: string(),
7824
- /** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
7825
- maxFps: number().nonnegative()
7826
- });
7827
- /**
7828
7755
  * Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
7829
7756
  * `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
7830
7757
  * sample bytes plus the track parameters a consumer needs to interpret them.
@@ -7832,8 +7759,8 @@ var SubscribeFramesResultSchema = object({
7832
7759
  * Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
7833
7760
  * Float32 PCM), so unlike video frames they ship their bytes INLINE over
7834
7761
  * tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
7835
- * (the wire-serialisable supertype of `Buffer`) to match `DecodedFrameSchema`
7836
- * / `EncodedPacketSchema`'s precedent; a `Buffer` is assignable to it.
7762
+ * (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
7763
+ * it.
7837
7764
  */
7838
7765
  var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
7839
7766
  var DecodedAudioChunkSchema = object({
@@ -7851,11 +7778,10 @@ var DecodedAudioChunkSchema = object({
7851
7778
  format: AudioChunkFormatSchema.optional()
7852
7779
  });
7853
7780
  /**
7854
- * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). The
7855
- * handle-free, ship-bytes-inline analogue of `subscribeFrames`: a consumer
7856
- * asks the broker for the decoded audio-chunk stream of one broker; the
7857
- * broker keeps a per-subscription bounded FIFO queue the consumer drains via
7858
- * `pullAudioChunks`.
7781
+ * Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
7782
+ * its bytes inline: a consumer asks the broker for the decoded audio-chunk
7783
+ * stream of one broker; the broker keeps a per-subscription bounded FIFO queue
7784
+ * the consumer drains via `pullAudioChunks`.
7859
7785
  */
7860
7786
  var SubscribeAudioChunksInputSchema = object({
7861
7787
  brokerId: string(),
@@ -7886,9 +7812,7 @@ var BrokerStatsSchema = object({
7886
7812
  "stopped"
7887
7813
  ]),
7888
7814
  inputFps: number(),
7889
- decodeFps: number(),
7890
7815
  encodedSubscribers: number(),
7891
- decodedSubscribers: number(),
7892
7816
  uptimeMs: number(),
7893
7817
  bitrateKbps: number(),
7894
7818
  idrIntervalMs: number(),
@@ -7901,14 +7825,6 @@ var BrokerStatsSchema = object({
7901
7825
  preBufferMs: number(),
7902
7826
  preBufferPackets: number(),
7903
7827
  /**
7904
- * Moleculer node id of the decoder provider currently servicing this
7905
- * stream's decoded subscribers. `null` until the deferred decoder is
7906
- * created (no decoded clients yet, or codec not detected). Surfaces the
7907
- * runtime decoder placement so the UI can show "Decoder: <agent>" without
7908
- * a separate cap call per broker.
7909
- */
7910
- decoderNodeId: string().nullable(),
7911
- /**
7912
7828
  * Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
7913
7829
  * when the stream has no audio track or the broker is in cold start.
7914
7830
  * `supported = false` means the codec was detected but the local
@@ -11244,70 +11160,6 @@ var StorageLocationDeclarationSchema = object({
11244
11160
  "backup"
11245
11161
  ]).optional()
11246
11162
  });
11247
- var DecoderStatsSchema = object({
11248
- inputFps: number(),
11249
- outputFps: number(),
11250
- avgDecodeTimeMs: number(),
11251
- droppedFrames: number(),
11252
- /**
11253
- * Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
11254
- * lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
11255
- * the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
11256
- * is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
11257
- */
11258
- lagMs: number().optional(),
11259
- effectiveFps: number().optional(),
11260
- adaptiveFps: number().optional()
11261
- });
11262
- var DecoderSessionConfigSchema = object({
11263
- codec: string(),
11264
- maxFps: number().default(0),
11265
- outputFormat: _enum([
11266
- "jpeg",
11267
- "rgb",
11268
- "bgr",
11269
- "yuv420",
11270
- "gray"
11271
- ]).default("jpeg"),
11272
- scale: number().default(1),
11273
- width: number().optional(),
11274
- height: number().optional(),
11275
- /**
11276
- * Identifier of the camera this decoder session serves. Optional
11277
- * because the cap is generic (any caller could request decode), but
11278
- * stream-broker passes it so decoder logs include `deviceId` for
11279
- * per-camera filtering when diagnosing failures (e.g. node-av
11280
- * sendPacket errors on a single hung camera).
11281
- */
11282
- deviceId: number().int().nonnegative().optional(),
11283
- /**
11284
- * Free-form tag for log scoping. Stream-broker uses
11285
- * `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
11286
- * on every line so `grep tag=broker:5/high` filters one camera
11287
- * profile cleanly.
11288
- */
11289
- tag: string().optional(),
11290
- /**
11291
- * Where the session delivers decoded frames (Phase 5 / D9):
11292
- *
11293
- * - `'callback'` (default) — the legacy pixel path: decoded frames are
11294
- * buffered as `DecodedFrame`s and drained via `pullFrames`.
11295
- * - `'shm'` — the shared-memory frame plane: decoded frames are written
11296
- * into an OS shared-memory ring and drained as zero-pixel
11297
- * `FrameHandle`s via `pullHandles`. A session is one mode or the
11298
- * other — `pullFrames` returns nothing for an `'shm'` session and
11299
- * `pullHandles` returns nothing for a `'callback'` session.
11300
- */
11301
- frameSink: _enum(["callback", "shm"]).default("callback"),
11302
- /**
11303
- * Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
11304
- * a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
11305
- * real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
11306
- * stream-broker's `streamingDebug` gate — off by default so production logs
11307
- * stay quiet and the emit path pays zero per-frame cost when disabled.
11308
- */
11309
- debug: boolean().optional()
11310
- });
11311
11163
  /**
11312
11164
  * Per-component log CHANNELS — the gate a hot path consults, and the registry
11313
11165
  * an addon declares its channels in.
@@ -11450,6 +11302,26 @@ var ClipSearchStrictnessSchema = _enum([
11450
11302
  "balanced",
11451
11303
  "strict"
11452
11304
  ]);
11305
+ /** Steps whose effect a root label can BE. */
11306
+ var LABEL_SUPPLY_STEP_IDS = [
11307
+ "animal-classifier",
11308
+ "vehicle-classifier",
11309
+ "package-detection"
11310
+ ];
11311
+ /** Steps whose box a root detection can BE. */
11312
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
11313
+ /**
11314
+ * Steps whose per-detection MASK a root detection can carry (D737). The live
11315
+ * mask step is `segmentation` — a frame-plane refiner that runs its own model
11316
+ * once per detection crop. (`instance-segmentation` is a dormant step id that
11317
+ * no camera tree carries.)
11318
+ */
11319
+ var MASK_SUPPLY_STEP_IDS = ["segmentation"];
11320
+ [
11321
+ ...LABEL_SUPPLY_STEP_IDS,
11322
+ ...CROP_SUPPLY_STEP_IDS,
11323
+ ...MASK_SUPPLY_STEP_IDS
11324
+ ];
11453
11325
  var MODEL_FORMATS = [
11454
11326
  "onnx",
11455
11327
  "coreml",
@@ -11478,7 +11350,53 @@ var ModelFormatEntrySchema = object({
11478
11350
  /** Multi-file payload (directory members or sibling files). */
11479
11351
  files: array(string()).readonly().optional(),
11480
11352
  /** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
11481
- runtimes: array(_enum(["python"])).readonly().optional()
11353
+ runtimes: array(_enum(["python"])).readonly().optional(),
11354
+ /**
11355
+ * Content revision of the artefact, for one hosted OFF the CamStack mirror.
11356
+ * A format on the mirror leaves it unset: its revision (the sha256 of its
11357
+ * weight file) comes from the downloader's generated table, kept in step
11358
+ * with the mirror by `scripts/check-hosted-model-revisions.ts` (D744). A
11359
+ * node records the revision it downloaded next to the file
11360
+ * (`<file>.revision`); a copy with no record or a different one is stale
11361
+ * unless its weight file hashes to the revision, and a stale copy is
11362
+ * downloaded again, the old one serving until the new one is complete. No
11363
+ * revision at all ⇒ a file on disk is current, whatever it holds (D743).
11364
+ */
11365
+ revision: string().min(1).optional()
11366
+ });
11367
+ /**
11368
+ * What a node holds for one (model, format) (D746). `current` is a complete
11369
+ * copy at its catalog revision — exactly what `downloaded: true` means.
11370
+ * `stale` is bytes on disk that are not (yet) proven current under D743/D744:
11371
+ * no or a different revision record, or a missing sibling. `missing` is no
11372
+ * copy. `downloaded` alone folds `stale` into "not downloaded", which hid
11373
+ * reclaimable bytes and a copy about to be replaced.
11374
+ */
11375
+ var ModelOnDiskStateSchema = _enum([
11376
+ "current",
11377
+ "stale",
11378
+ "missing"
11379
+ ]);
11380
+ /**
11381
+ * The numeric precision of one format's BUILD (D746) — reported only when the
11382
+ * build states it (file-name token, an INT8 variant, an EdgeTPU compile, a
11383
+ * CamStack Core ML export). Absent means "not stated", never "fp32".
11384
+ */
11385
+ var ModelFormatPrecisionSchema = _enum([
11386
+ "fp32",
11387
+ "fp16",
11388
+ "int8"
11389
+ ]);
11390
+ /**
11391
+ * One format of one model as a node's `pipelineExecutor.getSchema` reports it.
11392
+ * `onDisk` / `precision` are optional for version skew: a runner that predates
11393
+ * them omits them, and a reader falls back to `downloaded`.
11394
+ */
11395
+ var PipelineModelFormatStatusSchema = object({
11396
+ downloaded: boolean(),
11397
+ sizeMB: number(),
11398
+ onDisk: ModelOnDiskStateSchema.optional(),
11399
+ precision: ModelFormatPrecisionSchema.optional()
11482
11400
  });
11483
11401
  /**
11484
11402
  * Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
@@ -11519,11 +11437,11 @@ var ModelVariantGroupSchema = object({
11519
11437
  /** Quantization axis. Omit ⇒ the fp32 base build. */
11520
11438
  precision: _enum(["fp32", "int8"]).optional(),
11521
11439
  /**
11522
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
11523
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
11524
- * future performance variants plug into.
11440
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
11441
+ * an alternate training of the same family (Scrypted `relu_test`); chip
11442
+ * label is "Test".
11525
11443
  */
11526
- optimization: _enum(["standard", "fast"]).optional(),
11444
+ optimization: _enum(["standard", "test"]).optional(),
11527
11445
  /**
11528
11446
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
11529
11447
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -11546,9 +11464,10 @@ var ModelProviderIdSchema = _enum([
11546
11464
  * are per upstream. A persisted custom-model row written when this field was a
11547
11465
  * string still parses — the string is lifted into `{ weights }`.
11548
11466
  *
11549
- * Every licence surface (the admin "Models and licenses" page,
11550
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
11551
- * these records by `scripts/gen-model-licenses.ts` (D661).
11467
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
11468
+ * model table) is GENERATED from these records by
11469
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
11470
+ * `camstack/docs` → `/docs/detection/models`.
11552
11471
  */
11553
11472
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
11554
11473
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -11581,6 +11500,46 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
11581
11500
  /** True when the weights or their data forbid commercial use. */
11582
11501
  nonCommercial: boolean().optional()
11583
11502
  }));
11503
+ /**
11504
+ * One step a ROOT detector can supply from its own output (D730) — see
11505
+ * `ModelCatalogEntry.suppliesSteps`.
11506
+ *
11507
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
11508
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
11509
+ * the root cannot produce (shown as unavailable, never a blocker).
11510
+ * - `crop`: the root draws the box the step would have found (`license_plate`
11511
+ * for plate-detection, `face` for face-detection). The box becomes a detail
11512
+ * child of the `parentMacro` detection that contains it — never a track.
11513
+ * - `mask`: the root's decode emits an instance mask with every detection (a
11514
+ * YOLO26-seg root, D737) — the `segmentation` step's result, carried on the
11515
+ * detection in the shape that step produces. Derived from the model's
11516
+ * postprocessor on read, never stored by an import.
11517
+ */
11518
+ var RootStepSupplySchema = discriminatedUnion("kind", [
11519
+ object({
11520
+ kind: literal("label"),
11521
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
11522
+ labelToEffect: record(string(), string()),
11523
+ uncovered: array(string()).readonly()
11524
+ }),
11525
+ object({
11526
+ kind: literal("crop"),
11527
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
11528
+ rootLabels: array(string()).readonly(),
11529
+ parentMacro: _enum(["vehicle", "person"]),
11530
+ childClass: _enum(["plate", "face"]),
11531
+ /**
11532
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
11533
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
11534
+ * stored by an import.
11535
+ */
11536
+ rootInputPx: number().int().positive().optional()
11537
+ }),
11538
+ object({
11539
+ kind: literal("mask"),
11540
+ stepId: _enum(MASK_SUPPLY_STEP_IDS)
11541
+ })
11542
+ ]);
11584
11543
  var ModelCatalogEntrySchema = object({
11585
11544
  id: string(),
11586
11545
  name: string(),
@@ -11646,6 +11605,35 @@ var ModelCatalogEntrySchema = object({
11646
11605
  */
11647
11606
  defaultConfidence: number().min(0).max(1).optional(),
11648
11607
  /**
11608
+ * Per-MODEL default of the per-class confidence floors (`minConfidence<Macro>`
11609
+ * on a detector step), keyed by macro class: `{ person: 0.45 }`. A class
11610
+ * absent here runs at the step slider's global default. The same row shape
11611
+ * the floor measurement produces (`model-floors.json`: modelId → floors), so
11612
+ * a measured table is copied in as-is. An operator override is bound to the
11613
+ * model it was made for and does not survive a model change (D738). A custom
11614
+ * / imported model may declare it; without it, the global defaults apply.
11615
+ */
11616
+ defaultClassFloors: record(string(), number().min(0).max(1)).optional(),
11617
+ /**
11618
+ * The inference precision this model's OpenVINO IR needs on an Intel GPU.
11619
+ * Absent ⇒ the device default (f16 on a GPU). Set to `'f32'` for an FP32 IR
11620
+ * that produces invalid output at f16 — measured 2026-10-07 for YOLO26
11621
+ * base IRs (`yolo26s`: 0 true / 146 false positives; `yolo26m*`: NaN
11622
+ * scores) on the Core Ultra iGPU and the N100. Threaded to the pool as
11623
+ * `PoolModelConfig.gpuInferencePrecision`; the pool sets
11624
+ * INFERENCE_PRECISION_HINT on a GPU only. Costs ~60% latency on the GPU.
11625
+ */
11626
+ gpuInferencePrecision: _enum(["f32", "f16"]).optional(),
11627
+ /**
11628
+ * ROOT detectors only: per supplied step (`animal-classifier`, …), the
11629
+ * minimum DETECTION score from which this root's own fine label (species,
11630
+ * vehicle type — D736 root supply) is taken (D741). Below it the detection
11631
+ * keeps its macro class without the fine label. `1` = never take it from
11632
+ * this root. Absent ⇒ no floor beyond the macro floor. The supplied step's
11633
+ * `minConfidence` slider, bound to the ROOT model, overrides it.
11634
+ */
11635
+ suppliedLabelFloors: record(string(), number().min(0).max(1)).optional(),
11636
+ /**
11649
11637
  * When true, the executor produces a landmark-aligned crop (similarity warp
11650
11638
  * onto the canonical template) before this step runs, instead of a plain
11651
11639
  * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
@@ -11707,6 +11695,16 @@ var ModelCatalogEntrySchema = object({
11707
11695
  */
11708
11696
  classMap: DetectionCatalogClassMapSchema.optional(),
11709
11697
  /**
11698
+ * The pipeline steps this ROOT detector can supply from its own output
11699
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
11700
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
11701
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
11702
+ * by hand and never assumed per family; a row without it is derived on read
11703
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
11704
+ * `useRootModel` flag (`resolveRootSupply`).
11705
+ */
11706
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
11707
+ /**
11710
11708
  * The model's CLIP feature-space contract (text encoder, dimension, vector
11711
11709
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
11712
11710
  * CLIP image encoder; its absence is what "not a CLIP model" means to the
@@ -13308,13 +13306,6 @@ var BrokerRtspClientSchema = object({
13308
13306
  lastRtpAt: number(),
13309
13307
  bytesSent: number()
13310
13308
  });
13311
- var BrokerDecodedClientSchema = object({
13312
- tag: string(),
13313
- subscribedAt: number(),
13314
- maxFps: number(),
13315
- framesDelivered: number(),
13316
- framesDropped: number()
13317
- });
13318
13309
  var BrokerAudioClientSchema = object({
13319
13310
  tag: string(),
13320
13311
  subscribedAt: number(),
@@ -13406,7 +13397,6 @@ var BrokerEncodedClientSchema = object({
13406
13397
  });
13407
13398
  var BrokerClientsSchema = object({
13408
13399
  rtsp: array(BrokerRtspClientSchema).readonly(),
13409
- decoded: array(BrokerDecodedClientSchema).readonly(),
13410
13400
  audio: array(BrokerAudioClientSchema).readonly(),
13411
13401
  encoded: array(BrokerEncodedClientSchema).readonly(),
13412
13402
  pipeClients: number(),
@@ -13775,11 +13765,7 @@ method(object({
13775
13765
  auth: "admin"
13776
13766
  }), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
13777
13767
  brokerId: string(),
13778
- channel: _enum([
13779
- "rtsp",
13780
- "decoded",
13781
- "audio"
13782
- ]),
13768
+ channel: _enum(["rtsp", "audio"]),
13783
13769
  handle: string()
13784
13770
  }), object({ killed: boolean() }), {
13785
13771
  kind: "mutation",
@@ -13814,10 +13800,7 @@ method(object({
13814
13800
  }), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
13815
13801
  subscriptionId: string(),
13816
13802
  maxCount: number().int().positive().default(8)
13817
- }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(SubscribeFramesInputSchema, SubscribeFramesResultSchema, { kind: "mutation" }), method(object({
13818
- subscriptionId: string(),
13819
- maxCount: number().int().positive().default(4)
13820
- }), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
13803
+ }), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
13821
13804
  brokerId: string(),
13822
13805
  seconds: number().min(0).max(30)
13823
13806
  }), _void(), {
@@ -15076,54 +15059,12 @@ id: union([string(), number()]) }), {
15076
15059
  kind: "mutation",
15077
15060
  auth: "admin"
15078
15061
  });
15079
- /**
15080
- * shm ring usage stats for a `frameSink: 'shm'` decoder session —
15081
- * exposed via `decoder.getShmStats` so downstream consumers can
15082
- * observe ring pressure (slot count, byte budget, hit/miss ratio).
15083
- */
15084
- var ShmRingStatsSchema = object({
15085
- sessionId: string(),
15086
- slotCount: number().int(),
15087
- slotByteLength: number().int(),
15088
- segmentBytes: number().int(),
15089
- budgetMb: number().int(),
15090
- framesWritten: number().int(),
15091
- getFrameHits: number().int(),
15092
- getFrameMisses: number().int()
15093
- });
15094
- method(object({ codec: string() }), boolean()), method(_void(), object({
15062
+ method(_void(), object({
15095
15063
  id: string(),
15096
15064
  name: string(),
15097
- isPullMode: boolean().optional(),
15098
- priority: number().optional(),
15099
15065
  hwaccel: string().optional(),
15100
15066
  probedBestHwaccel: string().optional()
15101
- })), method(DecoderSessionConfigSchema, object({
15102
- sessionId: string(),
15103
- nodeId: string()
15104
- })), method(object({ sessionId: string() }), _void()), method(object({
15105
- sessionId: string(),
15106
- packet: EncodedPacketSchema
15107
- }), _void()), method(object({
15108
- sessionId: string(),
15109
- url: string()
15110
- }), _void()), method(object({
15111
- sessionId: string(),
15112
- maxCount: number().default(1),
15113
- waitMs: number().optional()
15114
- }), array(DecodedFrameSchema)), method(object({
15115
- sessionId: string(),
15116
- maxCount: number().default(1),
15117
- waitMs: number().optional()
15118
- }), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
15119
- sessionId: string(),
15120
- config: DecoderSessionConfigSchema.partial()
15121
- }), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
15122
- sessionId: string(),
15123
- codec: string(),
15124
- outputFormat: string(),
15125
- createdAtMs: number()
15126
- })).readonly()), method(_void(), object({ backend: string() }), {
15067
+ })), method(_void(), object({ backend: string() }), {
15127
15068
  kind: "mutation",
15128
15069
  auth: "admin"
15129
15070
  });
@@ -15179,7 +15120,7 @@ DeviceType.Camera;
15179
15120
  * This matters here more than anywhere else in the repo, because every provider
15180
15121
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
15181
15122
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
15182
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
15123
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
15183
15124
  * camera's own page will ask for its own login. That is correct, and pre-
15184
15125
  * filling it is the operator's business, not ours.
15185
15126
  *
@@ -17268,6 +17209,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
17268
17209
  kind: "mutation",
17269
17210
  auth: "admin"
17270
17211
  });
17212
+ var HUB_ADDRESS_ROLES = [
17213
+ "appConnections",
17214
+ "notificationTaps",
17215
+ "internal",
17216
+ "publicEndpoint"
17217
+ ];
17271
17218
  /**
17272
17219
  * Transport bounds for AI capability methods.
17273
17220
  *
@@ -18464,7 +18411,7 @@ method(object({
18464
18411
  timeoutMs: 6e5
18465
18412
  });
18466
18413
  method(object({
18467
- nodeId: string(),
18414
+ targetNodeId: string(),
18468
18415
  modelId: string(),
18469
18416
  format: _enum(MODEL_FORMATS),
18470
18417
  entry: ModelCatalogEntrySchema
@@ -19870,6 +19817,8 @@ var NcSystemEventKindSchema = _enum([
19870
19817
  "stream-offline",
19871
19818
  "node-online",
19872
19819
  "node-offline",
19820
+ "node-restarting",
19821
+ "node-updating",
19873
19822
  "node-inference-unavailable",
19874
19823
  "detection-blind",
19875
19824
  "addon-crash-loop",
@@ -20968,8 +20917,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20968
20917
  disabledTargetIds: array(string()).default([])
20969
20918
  });
20970
20919
  /**
20971
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20972
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20920
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20921
+ * report a still-true state. `addons` is the crash-looped addons only and
20922
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20973
20923
  * job is not an open state, and the alarm stays instant.
20974
20924
  */
20975
20925
  var NcStateSummarySectionIdSchema = _enum([
@@ -20981,6 +20931,7 @@ var NcStateSummarySectionIdSchema = _enum([
20981
20931
  "detection-blind",
20982
20932
  "nodes",
20983
20933
  "addons",
20934
+ "addon-updates",
20984
20935
  "updates"
20985
20936
  ]);
20986
20937
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -21461,7 +21412,25 @@ var NcAlarmModeDelaysListSchema = array(object({
21461
21412
  * When this mode may be armed. Absent / null = always allowed (same as a
21462
21413
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
21463
21414
  */
21464
- schedule: NcScheduleSchema.optional()
21415
+ schedule: NcScheduleSchema.optional(),
21416
+ /**
21417
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
21418
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
21419
+ * only one, and the matches ride the triggered notification's mosaic (D705).
21420
+ */
21421
+ notifyDuringEntryDelay: boolean().optional(),
21422
+ /**
21423
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
21424
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
21425
+ * is the one that starts the entry delay — the entry-delay notification already names it.
21426
+ */
21427
+ notifySensorRewatched: boolean().optional(),
21428
+ /**
21429
+ * D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
21430
+ * change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
21431
+ * re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
21432
+ */
21433
+ notifySensorIgnored: boolean().optional()
21465
21434
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
21466
21435
  var NcAlarmModeDelaysEditListSchema = array(object({
21467
21436
  mode: AlarmArmModeSchema,
@@ -21470,7 +21439,13 @@ var NcAlarmModeDelaysEditListSchema = array(object({
21470
21439
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
21471
21440
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
21472
21441
  /** Set a schedule, or `null` to clear (mode always allowed again). */
21473
- schedule: NcScheduleSchema.nullable().optional()
21442
+ schedule: NcScheduleSchema.nullable().optional(),
21443
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21444
+ notifyDuringEntryDelay: boolean().nullable().optional(),
21445
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
21446
+ notifySensorRewatched: boolean().nullable().optional(),
21447
+ /** D735: set the switch, or `null` to clear it (back to the default, false). */
21448
+ notifySensorIgnored: boolean().nullable().optional()
21474
21449
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
21475
21450
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
21476
21451
  var NcAlarmNonBlockingEditSchema = object({
@@ -22431,45 +22406,25 @@ Object.freeze(Object.fromEntries([{
22431
22406
  label: "Face recognition model",
22432
22407
  defaultModelId: "auraface-r100",
22433
22408
  indexName: "the enrolled face gallery",
22434
- options: [
22435
- {
22436
- id: "auraface-r100",
22437
- label: "AuraFace R100"
22438
- },
22439
- {
22440
- id: "arcface-r100",
22441
- label: "ArcFace (ResNet34)"
22442
- },
22443
- {
22444
- id: "inception-resnet-v1",
22445
- label: "Inception ResNet V1"
22446
- }
22447
- ]
22409
+ options: [{
22410
+ id: "auraface-r100",
22411
+ label: "AuraFace R100"
22412
+ }]
22448
22413
  }, {
22449
22414
  stepId: "clip-embedding",
22450
22415
  label: "Semantic search model",
22451
- defaultModelId: "mobileclip-s1",
22416
+ defaultModelId: "siglip2-b16-224",
22452
22417
  indexName: "the object semantic-search index",
22453
- options: [
22454
- {
22455
- id: "mobileclip-s1",
22456
- label: "MobileCLIP S1"
22457
- },
22458
- {
22459
- id: "mobileclip-s2",
22460
- label: "MobileCLIP S2"
22461
- },
22462
- {
22463
- id: "siglip2-b16-224",
22464
- label: "SigLIP2 B/16 (Apache-2.0)"
22465
- }
22466
- ]
22418
+ options: [{
22419
+ id: "siglip2-b16-224",
22420
+ label: "SigLIP2 B/16 (Apache-2.0)"
22421
+ }]
22467
22422
  }].map((s) => [s.stepId, s.defaultModelId])));
22468
22423
  var CLUSTER_STEP_SETTING_FIELDS = [{
22469
22424
  stepId: "face-embedding",
22470
22425
  key: "minLandmarkFaceSize",
22471
- label: "Min face size for recognition (detection px)",
22472
- 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.",
22426
+ label: "Min face size to embed (detection-frame px)",
22427
+ 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.",
22473
22428
  type: "slider",
22474
22429
  min: 0,
22475
22430
  max: 64,
@@ -24389,6 +24344,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
24389
24344
  timestamp: number()
24390
24345
  });
24391
24346
  /**
24347
+ * A root model's boxes standing in for one crop-kind step's own inference
24348
+ * (D730) — see `runPipeline.suppliedRoot`.
24349
+ */
24350
+ var SuppliedRootOutputSchema = object({
24351
+ stepId: string(),
24352
+ /** The root model that drew the boxes — stamped on the result. */
24353
+ modelId: string(),
24354
+ detections: array(object({
24355
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
24356
+ bbox: tuple([
24357
+ number(),
24358
+ number(),
24359
+ number(),
24360
+ number()
24361
+ ]),
24362
+ score: number(),
24363
+ /**
24364
+ * Five facial landmarks in the same pixels — a face the step's own
24365
+ * detector already re-found inside a root face box (D730), so its
24366
+ * embedder child aligns it exactly as it aligns any detected face.
24367
+ */
24368
+ landmarks: array(object({
24369
+ x: number(),
24370
+ y: number()
24371
+ })).optional()
24372
+ })).min(1)
24373
+ });
24374
+ /**
24392
24375
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
24393
24376
  * within the frame, so the executor can re-cut a leaf child ROI at native
24394
24377
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -24436,7 +24419,7 @@ var FrameRefSchema = object({
24436
24419
  timestamp: number(),
24437
24420
  capturedAt: number().optional()
24438
24421
  });
24439
- var ModelFormatSchema$1 = _enum([
24422
+ var ModelFormatSchema$2 = _enum([
24440
24423
  "onnx",
24441
24424
  "coreml",
24442
24425
  "openvino",
@@ -24454,7 +24437,7 @@ var PipelineSlotSchema = _enum([
24454
24437
  var PipelineEngineChoiceSchema = object({
24455
24438
  runtime: literal("python"),
24456
24439
  backend: string(),
24457
- format: ModelFormatSchema$1,
24440
+ format: ModelFormatSchema$2,
24458
24441
  device: string().optional()
24459
24442
  });
24460
24443
  /**
@@ -24493,32 +24476,15 @@ var PipelineDefaultStepSchema = lazy(() => object({
24493
24476
  group: string().optional(),
24494
24477
  settings: record(string(), unknown()).optional()
24495
24478
  }));
24496
- var PipelineTemplateStepSchema = lazy(() => object({
24497
- addonId: string(),
24498
- enabled: boolean(),
24499
- modelId: string(),
24500
- children: array(PipelineTemplateStepSchema).readonly(),
24501
- settings: record(string(), unknown()).optional()
24502
- }));
24503
- var PipelineTemplateSchema$1 = object({
24504
- id: string(),
24505
- name: string(),
24506
- createdAt: string(),
24507
- updatedAt: string(),
24508
- engine: PipelineEngineChoiceSchema,
24509
- steps: array(PipelineTemplateStepSchema).readonly()
24510
- });
24511
24479
  var PipelineModelOptionSchema = object({
24512
24480
  id: string(),
24513
24481
  name: string(),
24514
- formats: record(string(), object({
24515
- downloaded: boolean(),
24516
- sizeMB: number()
24517
- })),
24482
+ formats: record(string(), PipelineModelFormatStatusSchema),
24518
24483
  group: ModelVariantGroupSchema.optional(),
24519
24484
  legacy: boolean().optional(),
24520
24485
  provider: ModelProviderIdSchema.optional(),
24521
- defaultConfidence: number().optional()
24486
+ defaultConfidence: number().optional(),
24487
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
24522
24488
  });
24523
24489
  var ConfigFieldBridge = custom();
24524
24490
  var PipelineAddonSchemaSchema = object({
@@ -24680,6 +24646,22 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24680
24646
  }), {
24681
24647
  kind: "mutation",
24682
24648
  auth: "admin"
24649
+ }), method(object({
24650
+ nodeId: string(),
24651
+ deviceIds: array(number()).readonly().optional(),
24652
+ dryRun: boolean()
24653
+ }), object({
24654
+ entries: array(object({
24655
+ deviceId: number(),
24656
+ keys: array(string()).readonly()
24657
+ })).readonly(),
24658
+ refused: array(object({
24659
+ deviceId: number(),
24660
+ reason: string()
24661
+ })).readonly()
24662
+ }), {
24663
+ kind: "mutation",
24664
+ auth: "admin"
24683
24665
  }), method(object({ nodeId: string() }), object({ unhealthy: array(object({
24684
24666
  /** `<backend>:<device>`, e.g. `openvino:gpu`. */
24685
24667
  deviceKey: string(),
@@ -24705,22 +24687,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24705
24687
  }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
24706
24688
  steps: array(PipelineStepInputSchema),
24707
24689
  deviceKey: string().optional()
24708
- }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
24709
- name: string(),
24710
- steps: array(PipelineTemplateStepSchema).readonly(),
24711
- engine: PipelineEngineChoiceSchema
24712
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
24713
- id: string(),
24714
- name: string().optional(),
24715
- steps: array(PipelineTemplateStepSchema).readonly().optional()
24716
- }), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
24690
+ }), PipelineValidationResultSchema), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
24717
24691
  addonId: string(),
24718
24692
  modelId: string(),
24719
- format: ModelFormatSchema$1
24693
+ format: ModelFormatSchema$2
24720
24694
  }), DownloadModelResultSchema, { kind: "mutation" }), method(object({
24721
24695
  addonId: string(),
24722
24696
  modelId: string(),
24723
- format: ModelFormatSchema$1
24697
+ format: ModelFormatSchema$2
24724
24698
  }), object({ success: literal(true) }), { kind: "mutation" }), method(object({
24725
24699
  steps: array(PipelineStepInputSchema).min(1),
24726
24700
  frame: FrameInputSchema.optional(),
@@ -24786,7 +24760,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24786
24760
  * `device-not-servable`), and nothing reaches the camera's live
24787
24761
  * trace stream. Absent ⇒ unchanged behaviour.
24788
24762
  */
24789
- replay: literal(true).optional()
24763
+ replay: literal(true).optional(),
24764
+ /**
24765
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
24766
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
24767
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
24768
+ * NOT inferred, these boxes are its output, and its children (the plate
24769
+ * reader) run on them through their own crop policy. Boxes are in the
24770
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
24771
+ */
24772
+ suppliedRoot: SuppliedRootOutputSchema.optional()
24790
24773
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
24791
24774
  steps: array(PipelineStepInputSchema).min(1),
24792
24775
  frames: array(FrameInputSchema).min(1).max(255),
@@ -24868,6 +24851,375 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24868
24851
  filename: string().optional(),
24869
24852
  settings: record(string(), unknown()).optional()
24870
24853
  }), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
24854
+ /**
24855
+ * The wire shapes of the Auto tune plan and apply (D745), used by the
24856
+ * `pipeline-orchestrator` cap. The recommender's own types
24857
+ * (`recommend.ts`) are the TS face of the same data; these
24858
+ * schemas are what crosses the cap boundary.
24859
+ */
24860
+ var ModelFormatSchema$1 = _enum(MODEL_FORMATS);
24861
+ /** The operator's range for it. */
24862
+ var MIN_SESSIONS_PER_DEVICE_RANGE = {
24863
+ min: 1,
24864
+ max: 8
24865
+ };
24866
+ var HardwareClassIdSchema = _enum([
24867
+ "intel-core-ultra",
24868
+ "intel-n-series",
24869
+ "apple-m-base",
24870
+ "apple-m-pro",
24871
+ "unknown"
24872
+ ]);
24873
+ var AcceleratorKindSchema = _enum([
24874
+ "intel-npu",
24875
+ "intel-igpu",
24876
+ "x86-cpu",
24877
+ "arm-cpu",
24878
+ "apple-ane",
24879
+ "coral"
24880
+ ]);
24881
+ var RecommendationReasonSchema = discriminatedUnion("kind", [
24882
+ object({
24883
+ kind: literal("capacity"),
24884
+ sessions: number(),
24885
+ minSessions: number()
24886
+ }),
24887
+ object({
24888
+ kind: literal("tie-faster"),
24889
+ over: string(),
24890
+ recallDelta: number()
24891
+ }),
24892
+ object({
24893
+ kind: literal("stepped-down"),
24894
+ from: string(),
24895
+ to: string(),
24896
+ limitedBy: string()
24897
+ }),
24898
+ object({
24899
+ kind: literal("no-fit-lightest"),
24900
+ sessions: number(),
24901
+ minSessions: number()
24902
+ }),
24903
+ object({
24904
+ kind: literal("derived-latency"),
24905
+ modelId: string()
24906
+ }),
24907
+ object({ kind: literal("cpu-device") }),
24908
+ object({ kind: literal("coral-untouched") }),
24909
+ object({ kind: literal("device-disabled") }),
24910
+ object({ kind: literal("device-unavailable") }),
24911
+ object({ kind: literal("node-offline") }),
24912
+ object({ kind: literal("no-hardware-facts") }),
24913
+ object({
24914
+ kind: literal("no-measured-data"),
24915
+ hardwareClass: HardwareClassIdSchema
24916
+ }),
24917
+ object({
24918
+ kind: literal("no-family-build"),
24919
+ format: ModelFormatSchema$1
24920
+ })
24921
+ ]);
24922
+ var DeviceModelChoiceSchema = object({
24923
+ modelId: string(),
24924
+ p50Ms: number(),
24925
+ fps: number(),
24926
+ measured: boolean(),
24927
+ /** Parallel sessions at the camera rate with the headroom kept free: ⌊fps × (1 − headroom) / camera fps⌋. */
24928
+ capacitySessions: number(),
24929
+ personRecall: number()
24930
+ });
24931
+ var DeviceRecommendationSchema = object({
24932
+ deviceKey: string(),
24933
+ accelerator: AcceleratorKindSchema.nullable(),
24934
+ enabled: boolean(),
24935
+ available: boolean(),
24936
+ chosen: DeviceModelChoiceSchema.nullable(),
24937
+ reasons: array(RecommendationReasonSchema).readonly()
24938
+ });
24939
+ var NodeRecommendationSchema = object({
24940
+ nodeId: string(),
24941
+ reachable: boolean(),
24942
+ hardwareClass: HardwareClassIdSchema.nullable(),
24943
+ cpuModel: string().nullable(),
24944
+ skipped: boolean(),
24945
+ acceleratorModelId: string().nullable(),
24946
+ devices: array(DeviceRecommendationSchema).readonly(),
24947
+ reasons: array(RecommendationReasonSchema).readonly()
24948
+ });
24949
+ var ModelPinChangeSchema = object({
24950
+ stepId: string(),
24951
+ before: string().nullable(),
24952
+ after: string().nullable()
24953
+ });
24954
+ var NodeDeviceChangeSchema = object({
24955
+ nodeId: string(),
24956
+ deviceKey: string(),
24957
+ madeExplicit: boolean(),
24958
+ modelPins: array(ModelPinChangeSchema).readonly(),
24959
+ thresholds: array(object({
24960
+ stepId: string(),
24961
+ keys: array(string()).readonly()
24962
+ })).readonly()
24963
+ });
24964
+ var CameraOverrideClearSchema = object({
24965
+ deviceId: number(),
24966
+ source: _enum(["step-override", "wholesale"]),
24967
+ nodeId: string(),
24968
+ deviceKey: string().nullable(),
24969
+ stepId: string(),
24970
+ modelIdBefore: string().nullable(),
24971
+ keys: array(string()).readonly()
24972
+ });
24973
+ var DetectorStoreClearSchema = object({
24974
+ deviceId: number(),
24975
+ keys: array(string()).readonly()
24976
+ });
24977
+ var AutoTuneWarningSchema = discriminatedUnion("kind", [
24978
+ object({
24979
+ kind: literal("detector-store-cluster-wide"),
24980
+ skippedNodes: array(string()).readonly()
24981
+ }),
24982
+ object({
24983
+ kind: literal("detector-store-unreadable"),
24984
+ error: string()
24985
+ }),
24986
+ object({
24987
+ kind: literal("coral-enabled"),
24988
+ nodeId: string(),
24989
+ deviceKey: string()
24990
+ })
24991
+ ]);
24992
+ var AutoTuneOptionsSchema = object({
24993
+ /** Share of each accelerator's throughput kept free (0.3–0.5). */
24994
+ headroom: number().min(.3).max(.5).default(.4),
24995
+ /**
24996
+ * The least number of parallel sessions every device must sustain at the
24997
+ * camera rate with the headroom kept free (D755). The most accurate model
24998
+ * that reaches it wins.
24999
+ */
25000
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
25001
+ });
25002
+ var AutoTunePlanSchema = object({
25003
+ /** Hash of everything the apply will write — the apply refuses a different one. */
25004
+ planHash: string(),
25005
+ family: literal("yolov9"),
25006
+ headroom: number(),
25007
+ minSessionsPerDevice: number(),
25008
+ /** The detection rate a session is counted at (the fastest camera running the pipeline root). */
25009
+ cameraFps: number(),
25010
+ generatedAt: number(),
25011
+ nodes: array(NodeRecommendationSchema).readonly(),
25012
+ nodeChanges: array(NodeDeviceChangeSchema).readonly(),
25013
+ cameraClears: array(CameraOverrideClearSchema).readonly(),
25014
+ detectorStoreClears: array(DetectorStoreClearSchema).readonly(),
25015
+ warnings: array(AutoTuneWarningSchema).readonly()
25016
+ });
25017
+ var AutoTuneApplyInputSchema = object({
25018
+ planHash: string(),
25019
+ headroom: number().min(.3).max(.5).default(.4),
25020
+ minSessionsPerDevice: number().int().min(MIN_SESSIONS_PER_DEVICE_RANGE.min).max(MIN_SESSIONS_PER_DEVICE_RANGE.max).default(2)
25021
+ });
25022
+ var AutoTunePhaseResultSchema = object({
25023
+ phase: _enum([
25024
+ "download",
25025
+ "camera-overrides",
25026
+ "detector-thresholds",
25027
+ "node-models",
25028
+ "redispatch"
25029
+ ]),
25030
+ ok: boolean(),
25031
+ detail: string()
25032
+ });
25033
+ var AutoTuneApplyResultSchema = discriminatedUnion("kind", [
25034
+ object({
25035
+ kind: literal("applied"),
25036
+ planHash: string(),
25037
+ phases: array(AutoTunePhaseResultSchema).readonly()
25038
+ }),
25039
+ object({
25040
+ kind: literal("aborted"),
25041
+ phases: array(AutoTunePhaseResultSchema).readonly()
25042
+ }),
25043
+ object({
25044
+ kind: literal("stale"),
25045
+ plan: AutoTunePlanSchema
25046
+ }),
25047
+ object({
25048
+ kind: literal("refused"),
25049
+ reason: _enum(["apply-in-progress"])
25050
+ })
25051
+ ]);
25052
+ /**
25053
+ * Wire shapes of the Load balancing surface (D748): the session placement
25054
+ * policy, the atomic share write, the observed placement statistics, the
25055
+ * hardware share suggestion and the stale device pins.
25056
+ */
25057
+ /**
25058
+ * How a new detection session picks its node and device.
25059
+ * - `least-loaded` — the historical rule: lowest `attached / weight`, a
25060
+ * constant node order at a tie (D37). An idle node always ties at 0, so a
25061
+ * weight only bites once a node already holds a session.
25062
+ * - `share` — the share of PARALLEL sessions is held to the weights, and a
25063
+ * full or drowning node yields to a free one (D748).
25064
+ */
25065
+ var SessionPlacementPolicySchema = _enum(["least-loaded", "share"]);
25066
+ var LoadBalancingSharesInputSchema = object({
25067
+ /** nodeId → share (> 0). A node left out keeps its weight. */
25068
+ nodes: record(string(), number().positive()).default({}),
25069
+ /** nodeId → deviceKey → share (> 0). A device left out keeps its weight. */
25070
+ devices: record(string(), record(string(), number().positive())).default({})
25071
+ });
25072
+ var PlacementStatsInputSchema = object({
25073
+ /** Window the observed shares are averaged over (default 1 h, max 24 h). */
25074
+ windowMs: number().int().min(6e4).max(1440 * 60 * 1e3).default(3600 * 1e3) });
25075
+ var PlacementDeviceStatsSchema = object({
25076
+ deviceKey: string(),
25077
+ /** Sessions running on this device now. */
25078
+ sessionsNow: number(),
25079
+ /** Sessions started on this device inside the window. */
25080
+ sessionsStarted: number(),
25081
+ /** Time-weighted share of the node's parallel sessions over the window (0–1); null = no session ran. */
25082
+ observedShare: number().nullable()
25083
+ });
25084
+ var PlacementNodeStatsSchema = object({
25085
+ nodeId: string(),
25086
+ sessionsNow: number(),
25087
+ sessionsStarted: number(),
25088
+ /** Time-weighted share of the cluster's parallel sessions over the window (0–1); null = none ran. */
25089
+ observedShare: number().nullable(),
25090
+ /** Most sessions this node ran at once inside the window. */
25091
+ peakSessions: number(),
25092
+ /** Sessions a share election handed elsewhere because this node was full or drowning. */
25093
+ yieldsAway: number(),
25094
+ devices: array(PlacementDeviceStatsSchema).readonly()
25095
+ });
25096
+ /** A camera's device pin that the session path cannot honour. */
25097
+ var StaleDevicePinSchema = object({
25098
+ deviceId: number(),
25099
+ deviceKey: string(),
25100
+ /** `disabled` — the key exists on some node but is not enabled anywhere; `absent` — no node has it. */
25101
+ reason: _enum(["disabled", "absent"])
25102
+ });
25103
+ var PlacementStatsSchema = object({
25104
+ policy: SessionPlacementPolicySchema,
25105
+ windowMs: number(),
25106
+ /** How much of the window was actually observed (the hub keeps it in memory). */
25107
+ observedForMs: number(),
25108
+ sessionsNow: number(),
25109
+ /** Most parallel sessions across the cluster inside the window. */
25110
+ clusterPeakSessions: number(),
25111
+ nodes: array(PlacementNodeStatsSchema).readonly(),
25112
+ stalePins: array(StaleDevicePinSchema).readonly()
25113
+ });
25114
+ /**
25115
+ * Where an automatic share's capacity comes from (D755).
25116
+ * - `hardware` — the static capacity of each device at its Auto tune model:
25117
+ * the measured latency table for the node's hardware class.
25118
+ * - `benchmark` — the node's own measured capacity (node benchmark results).
25119
+ * A node with no results falls back to `hardware`, and says so.
25120
+ */
25121
+ var CapacitySourceSchema = _enum(["hardware", "benchmark"]);
25122
+ /** Why a node under the `benchmark` source was sized from hardware instead. */
25123
+ var CapacityFallbackSchema = _enum(["no-benchmark-results", "partial-benchmark-results"]);
25124
+ var SuggestSharesInputSchema = object({
25125
+ headroom: number().min(.3).max(.5).default(.4),
25126
+ /** Default `hardware`. */
25127
+ source: CapacitySourceSchema.default("hardware")
25128
+ });
25129
+ var SuggestedDeviceShareSchema = object({
25130
+ deviceKey: string(),
25131
+ /** Share of the node (0–100, rounded). */
25132
+ share: number(),
25133
+ modelId: string().nullable(),
25134
+ /** Inferences per second at that model, from the measured table; null when sized by a benchmark. */
25135
+ fps: number().nullable(),
25136
+ /** False for a table cell derived from another chip; true for a measured cell or a benchmark. */
25137
+ measured: boolean(),
25138
+ /**
25139
+ * Advisory session cap: ⌊fps × (1 − headroom) / camera fps⌋ from the table,
25140
+ * or the benchmark's measured max sessions. Never enforced.
25141
+ */
25142
+ suggestedMaxSessions: number().nullable()
25143
+ });
25144
+ var SuggestedNodeShareSchema = object({
25145
+ nodeId: string(),
25146
+ /** Share of the cluster (0–100, rounded); null = node skipped (offline, unknown hardware). */
25147
+ share: number().nullable(),
25148
+ /** Parallel sessions the node sustains at the suggested models with the headroom kept free. */
25149
+ capacitySessions: number(),
25150
+ devices: array(SuggestedDeviceShareSchema).readonly(),
25151
+ skippedReason: string().nullable(),
25152
+ /** What this node's capacity was read from; null when the node is skipped. */
25153
+ capacitySource: CapacitySourceSchema.nullable(),
25154
+ /** Set when the `benchmark` source was asked for and this node used `hardware`. */
25155
+ capacityFallback: CapacityFallbackSchema.nullable()
25156
+ });
25157
+ var SuggestSharesResultSchema = object({
25158
+ headroom: number(),
25159
+ /** The source asked for; each node says what it actually used. */
25160
+ source: CapacitySourceSchema,
25161
+ /** Camera detection rate the capacity is counted in (the fastest camera's fps). */
25162
+ cameraFps: number(),
25163
+ /** The Auto tune capacity floor the models were picked at. */
25164
+ minSessionsPerDevice: number(),
25165
+ nodes: array(SuggestedNodeShareSchema).readonly()
25166
+ });
25167
+ /**
25168
+ * Where the node and device shares come from (D750, D755).
25169
+ * - `hardware` (default) — computed by the system from each node's static
25170
+ * capacity (its accelerators at their Auto tune models, from the measured
25171
+ * latency table), recomputed whenever a node or device joins, leaves, is
25172
+ * switched on or off, or changes model. No load input.
25173
+ * - `benchmark` — the same, from each node's measured capacity (node
25174
+ * benchmark results); a node without results falls back to `hardware`.
25175
+ * - `manual` — the operator's stored sliders.
25176
+ * Either way a node or device that cannot take sessions gives its share to
25177
+ * the others in proportion; the stored values are never rewritten for that.
25178
+ */
25179
+ var ShareSourceSchema = _enum([
25180
+ "hardware",
25181
+ "benchmark",
25182
+ "manual"
25183
+ ]);
25184
+ var SetShareSourceInputSchema = object({ source: ShareSourceSchema });
25185
+ object({
25186
+ nodes: record(string(), number()),
25187
+ devices: record(string(), record(string(), number()))
25188
+ });
25189
+ var EffectiveDeviceShareSchema = object({
25190
+ deviceKey: string(),
25191
+ /** Can take sessions now (enabled, available, can run the root). */
25192
+ eligible: boolean(),
25193
+ /** The share the source assigns, as a percentage of the node's devices. */
25194
+ configuredPct: number(),
25195
+ /** The share actually used, after an ineligible device's share went to the others. */
25196
+ effectivePct: number()
25197
+ });
25198
+ var EffectiveNodeShareSchema = object({
25199
+ nodeId: string(),
25200
+ eligible: boolean(),
25201
+ configuredPct: number(),
25202
+ effectivePct: number(),
25203
+ /** Automatic sources: what this node's share was computed from; null under `manual` or before the first answer. */
25204
+ capacitySource: CapacitySourceSchema.nullable(),
25205
+ /** Automatic `benchmark`: why this node used `hardware` instead. */
25206
+ capacityFallback: CapacityFallbackSchema.nullable(),
25207
+ devices: array(EffectiveDeviceShareSchema).readonly()
25208
+ });
25209
+ var EffectiveSharesSchema = object({
25210
+ source: ShareSourceSchema,
25211
+ policy: SessionPlacementPolicySchema,
25212
+ /** An automatic source with no computed answer yet: the stored sliders are used meanwhile. */
25213
+ autoPending: boolean(),
25214
+ /** When the automatic shares were last computed (ms epoch); null = never. */
25215
+ computedAt: number().nullable(),
25216
+ /** What made the system recompute them last. */
25217
+ trigger: string().nullable(),
25218
+ nodes: array(EffectiveNodeShareSchema).readonly(),
25219
+ /** The relative weights the election reads (before eligibility). */
25220
+ nodeWeights: record(string(), number()),
25221
+ deviceWeights: record(string(), record(string(), number()))
25222
+ });
24871
25223
  object({
24872
25224
  activeCameras: number(),
24873
25225
  throttledCameras: number(),
@@ -25351,6 +25703,22 @@ var MotionSourceEnum = _enum([
25351
25703
  "device-activity"
25352
25704
  ]);
25353
25705
  /**
25706
+ * What opened an on-motion detection SESSION: the motion source that passed the
25707
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
25708
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
25709
+ * device name as the orchestrator's camera-sensors resolution last read it;
25710
+ * absent when unknown or when the camera itself triggered.
25711
+ *
25712
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
25713
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
25714
+ * runner never decides anything on it.
25715
+ */
25716
+ var SessionTriggerSchema = object({
25717
+ source: MotionSourceEnum,
25718
+ triggeredBy: MotionTriggeredBySchema,
25719
+ sensorName: string().optional()
25720
+ });
25721
+ /**
25354
25722
  * List of motion sources active on a camera. Empty array is valid:
25355
25723
  * "no source" — happens for battery cams without firmware motion when
25356
25724
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -25602,6 +25970,14 @@ var RunnerCameraConfigSchema = object({
25602
25970
  */
25603
25971
  motionSources: MotionSourcesSchema.default(["analyzer"]),
25604
25972
  /**
25973
+ * What opened this attach, on a SESSION attach only (see
25974
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
25975
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
25976
+ * behind it, and every attach from an orchestrator older than the field — the
25977
+ * runner then names no source on the phase event.
25978
+ */
25979
+ sessionTrigger: SessionTriggerSchema.optional(),
25980
+ /**
25605
25981
  * WHICH root detector runs for this camera. The detection counterpart of
25606
25982
  * {@link motionSources}, same shape and same discipline: a per-camera list
25607
25983
  * of sources the system understands, vendor-agnostic, owned here.
@@ -25761,14 +26137,15 @@ var RunnerLocalLoadSchema = object({
25761
26137
  * Per-inference-device live load (multi-device C4). One entry per deviceKey
25762
26138
  * this runner currently has attached cameras on, so the orchestrator's second
25763
26139
  * `balance()` pass (over a node's devices) weights on real per-pool session
25764
- * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
25765
- * per device is 0 until the pool backlog gets a public accessor (follow-up).
26140
+ * counts. Empty on single-device / pre-multi-device runners. There is no
26141
+ * per-device queue depth: the inference pool's backlog has no accessor, and
26142
+ * a field that always read 0 was removed rather than shown as a measurement
26143
+ * (D762).
25766
26144
  */
25767
26145
  devices: array(object({
25768
26146
  deviceKey: string(),
25769
26147
  backend: string(),
25770
- attachedCameras: number(),
25771
- queueDepthTotal: number()
26148
+ attachedCameras: number()
25772
26149
  })).default([]),
25773
26150
  /** Hardware capability flags reported by this node. */
25774
26151
  hardware: object({
@@ -25904,7 +26281,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
25904
26281
  */
25905
26282
  cropJpeg: string().optional(),
25906
26283
  parent: DetailParentSchema,
25907
- steps: array(string()).optional()
26284
+ steps: array(string()).optional(),
26285
+ /**
26286
+ * The camera's root model already drew this step's boxes (D730): a
26287
+ * `license_plate` inside the parent vehicle. The named step is NOT
26288
+ * inferred — these FRAME-space boxes are its output — and its
26289
+ * requested children (the plate reader) run on them. Absent ⇒ every
26290
+ * requested step infers as before.
26291
+ */
26292
+ supplied: object({
26293
+ stepId: string(),
26294
+ modelId: string(),
26295
+ boxes: array(object({
26296
+ bbox: NativeCropBboxSchema,
26297
+ score: number()
26298
+ })).min(1)
26299
+ }).optional()
25908
26300
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
25909
26301
  /** Catalog step id, e.g. `clip-embedding`. */
25910
26302
  stepId: string(),
@@ -25967,14 +26359,6 @@ var CameraPipelineConfigSchema = object({
25967
26359
  settings: record(string(), unknown()).readonly().optional()
25968
26360
  }).nullable().optional()
25969
26361
  });
25970
- var PipelineTemplateSchema = object({
25971
- id: string(),
25972
- name: string(),
25973
- description: string().optional(),
25974
- config: CameraPipelineConfigSchema,
25975
- createdAt: string(),
25976
- updatedAt: string()
25977
- });
25978
26362
  var DeviceStepConfigSchema = object({
25979
26363
  modelId: string().optional(),
25980
26364
  settings: record(string(), unknown()).optional(),
@@ -26048,9 +26432,10 @@ var CameraStepOverridePatchSchema = object({
26048
26432
  modelId: string().optional(),
26049
26433
  settings: record(string(), unknown()).readonly().optional()
26050
26434
  });
26435
+ var CameraStepSettingsSchema = record(string(), record(string(), unknown()).readonly());
26051
26436
  var CameraPipelineSettingsSchema = object({
26052
- pinnedAgentNodeId: string().optional(),
26053
26437
  stepToggles: record(string(), boolean()).optional(),
26438
+ stepSettings: CameraStepSettingsSchema.optional(),
26054
26439
  stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
26055
26440
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
26056
26441
  });
@@ -26083,7 +26468,10 @@ var PipelineAssignmentSchema = object({
26083
26468
  });
26084
26469
  /**
26085
26470
  * Per-agent load summary surfaced to the load balancer + dashboards.
26086
- * Aggregated from each runner's `getLocalLoad` cap call.
26471
+ * Aggregated from each runner's `getLocalLoad` cap call. In the
26472
+ * `getAgentLoad` report, a single-device node's default-pool sessions (no
26473
+ * `deviceKey`) are credited to its one eligible device in `load.devices` —
26474
+ * the default pool IS that device (D745); the balancer's census stays raw.
26087
26475
  */
26088
26476
  var AgentLoadSummarySchema = object({
26089
26477
  nodeId: string(),
@@ -26172,26 +26560,27 @@ var CameraBrokerStatusSchema = object({
26172
26560
  width: number(),
26173
26561
  height: number(),
26174
26562
  subscribers: number(),
26175
- inFps: number(),
26176
- outFps: number()
26563
+ /**
26564
+ * Encoded packets/s the broker receives from the camera. null when the
26565
+ * broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
26566
+ * There is no output rate: decoding runs in the session decode workers, not
26567
+ * in the broker, so the broker's own decoded-frame rate is 0 on every live
26568
+ * camera and is not served (D758).
26569
+ */
26570
+ inFps: number().nullable()
26177
26571
  })).readonly(),
26178
26572
  webrtcSessions: number(),
26179
26573
  rtspRestream: boolean()
26180
26574
  });
26181
- /** Shared-memory ring statistics within the decoder block. */
26182
- var CameraDecoderShmSchema = object({
26183
- framesWritten: number(),
26184
- getFrameHits: number(),
26185
- getFrameMisses: number(),
26186
- budgetMb: number()
26187
- });
26188
- /** Decoder block — null when the decoder stage is unreachable or inactive. */
26189
- var CameraDecoderStatusSchema = object({
26190
- nodeId: string(),
26191
- formats: array(string()).readonly(),
26192
- sessionCount: number(),
26193
- shm: CameraDecoderShmSchema
26194
- });
26575
+ /**
26576
+ * Decoder block — WHERE decode runs (co-located with the detection node by
26577
+ * construction); null when the camera has no detection node. It carries no
26578
+ * frame counter: the shared-memory plane whose counters it used to serve is
26579
+ * gone, and those fields read 0 forever. Whether frames actually flow is read
26580
+ * from `detection.actualFps` (frames delivered to and processed by the
26581
+ * detector), never from a counter nothing feeds.
26582
+ */
26583
+ var CameraDecoderStatusSchema = object({ nodeId: string() });
26195
26584
  /** Motion block — null when motion detection is not active for this device. */
26196
26585
  var CameraMotionStatusSchema = object({
26197
26586
  enabled: boolean(),
@@ -26548,12 +26937,6 @@ method(object({
26548
26937
  }), object({ success: literal(true) }), {
26549
26938
  kind: "mutation",
26550
26939
  auth: "admin"
26551
- }), method(object({
26552
- agentNodeId: string(),
26553
- detectWeight: number().positive().nullable()
26554
- }), object({ success: literal(true) }), {
26555
- kind: "mutation",
26556
- auth: "admin"
26557
26940
  }), method(object({
26558
26941
  agentNodeId: string(),
26559
26942
  detect: boolean().nullable().optional(),
@@ -26595,6 +26978,15 @@ method(object({
26595
26978
  }), {
26596
26979
  kind: "mutation",
26597
26980
  auth: "admin"
26981
+ }), method(AutoTuneOptionsSchema, AutoTunePlanSchema, { auth: "admin" }), method(AutoTuneApplyInputSchema, AutoTuneApplyResultSchema, {
26982
+ kind: "mutation",
26983
+ auth: "admin"
26984
+ }), method(LoadBalancingSharesInputSchema, object({ success: literal(true) }), {
26985
+ kind: "mutation",
26986
+ auth: "admin"
26987
+ }), method(PlacementStatsInputSchema, PlacementStatsSchema, { auth: "admin" }), method(SuggestSharesInputSchema, SuggestSharesResultSchema, { auth: "admin" }), method(_void(), EffectiveSharesSchema, { auth: "admin" }), method(SetShareSourceInputSchema, object({ success: literal(true) }), {
26988
+ kind: "mutation",
26989
+ auth: "admin"
26598
26990
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
26599
26991
  deviceId: number(),
26600
26992
  addonId: string(),
@@ -26611,6 +27003,13 @@ method(object({
26611
27003
  }), object({ success: literal(true) }), {
26612
27004
  kind: "mutation",
26613
27005
  auth: "admin"
27006
+ }), method(object({
27007
+ deviceId: number(),
27008
+ addonId: string(),
27009
+ settings: record(string(), unknown()).nullable()
27010
+ }), object({ success: literal(true) }), {
27011
+ kind: "mutation",
27012
+ auth: "admin"
26614
27013
  }), method(object({
26615
27014
  deviceId: number(),
26616
27015
  agentNodeId: string(),
@@ -26634,25 +27033,7 @@ method(object({
26634
27033
  }), method(_void(), DiskReconcileJobSchema, {
26635
27034
  kind: "mutation",
26636
27035
  auth: "admin"
26637
- }), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
26638
- name: string(),
26639
- description: string().optional(),
26640
- config: CameraPipelineConfigSchema
26641
- }), PipelineTemplateSchema, {
26642
- kind: "mutation",
26643
- auth: "admin"
26644
- }), method(object({
26645
- id: string(),
26646
- name: string().optional(),
26647
- description: string().optional(),
26648
- config: CameraPipelineConfigSchema.optional()
26649
- }), PipelineTemplateSchema, {
26650
- kind: "mutation",
26651
- auth: "admin"
26652
- }), method(object({ id: string() }), object({ success: literal(true) }), {
26653
- kind: "mutation",
26654
- auth: "admin"
26655
- });
27036
+ }), method(_void(), DiskReconcileJobSchema, { auth: "admin" });
26656
27037
  /**
26657
27038
  * Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
26658
27039
  * `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
@@ -28901,8 +29282,6 @@ var WebrtcStreamChoiceSchema = object({
28901
29282
  ]).nullable(),
28902
29283
  /** Input FPS from the camera (null for adaptive). */
28903
29284
  inputFps: number().nullable(),
28904
- /** Decoded FPS (null for adaptive). */
28905
- decodeFps: number().nullable(),
28906
29285
  /** Bitrate in kbps (null for adaptive). */
28907
29286
  bitrateKbps: number().nullable()
28908
29287
  });
@@ -29234,6 +29613,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
29234
29613
  */
29235
29614
  alive: boolean()
29236
29615
  })), method(object({
29616
+ deviceId: number().int().nonnegative(),
29617
+ sessionId: string(),
29618
+ downlinkMbps: number().nonnegative()
29619
+ }), object({
29620
+ outcome: _enum(["switching", "held"]),
29621
+ tier: CamProfileSchema.nullable(),
29622
+ reason: string()
29623
+ }), { kind: "mutation" }), method(object({
29237
29624
  deviceId: number().int().nonnegative(),
29238
29625
  sessionId: string()
29239
29626
  }), WebrtcSessionDebugSchema, { kind: "query" });
@@ -32990,7 +33377,7 @@ var LocalInterfaceSchema = object({
32990
33377
  name: string(),
32991
33378
  family: _enum(["IPv4", "IPv6"]),
32992
33379
  address: string(),
32993
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
33380
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32994
33381
  cidr: string(),
32995
33382
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32996
33383
  netmask: string(),
@@ -33044,7 +33431,9 @@ var ConnectionEndpointSchema = object({
33044
33431
  "lan-ipv4",
33045
33432
  "lan-ipv6",
33046
33433
  "public",
33047
- "loopback"
33434
+ "loopback",
33435
+ "app-link",
33436
+ "custom"
33048
33437
  ]),
33049
33438
  /**
33050
33439
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -33113,15 +33502,27 @@ var GetConnectionEndpointsResultSchema = object({
33113
33502
  localPort: AdvertisedLocalPortSchema
33114
33503
  });
33115
33504
  /**
33116
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
33117
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
33118
- * what AUTO currently picks, so the UI can show the effective value either way.
33505
+ * The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
33506
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
33507
+ * so the UI can show it either way.
33119
33508
  */
33120
33509
  var NotificationEndpointSchema = object({
33121
33510
  /** The operator's explicit choice, or null for AUTO. */
33122
33511
  baseUrl: string().nullable(),
33123
- /** What the ranking currently resolves to (null when nothing is reachable). */
33124
- resolved: string().nullable()
33512
+ /**
33513
+ * The effective flagged address: the explicit choice, else (AUTO) the
33514
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
33515
+ * answered the public tunnel / mesh here, or null.
33516
+ */
33517
+ resolved: string().nullable(),
33518
+ /**
33519
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
33520
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
33521
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
33522
+ * hub advertises neither; the app link is then minted without `hub=`.
33523
+ * Absent on a pre-D709 hub.
33524
+ */
33525
+ appLinkHub: string().nullable()
33125
33526
  });
33126
33527
  /**
33127
33528
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -33134,6 +33535,72 @@ var ViewerEndpointsSchema = object({
33134
33535
  /** What the ranking currently resolves to (may be empty if nothing is up). */
33135
33536
  resolved: array(string()).readonly()
33136
33537
  });
33538
+ /**
33539
+ * DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
33540
+ * for addons built against it): `cluster` is the `internal` role, `browser`
33541
+ * the `publicEndpoint` role; `override` is the flagged address.
33542
+ */
33543
+ var HubAddressSnapshotSchema = object({
33544
+ override: string().nullable(),
33545
+ resolved: string().nullable(),
33546
+ source: _enum([
33547
+ "override",
33548
+ "auto",
33549
+ "none"
33550
+ ])
33551
+ });
33552
+ var HubAddressesSchema = object({
33553
+ cluster: HubAddressSnapshotSchema,
33554
+ browser: HubAddressSnapshotSchema
33555
+ });
33556
+ /**
33557
+ * What an address is used for (`hub-address.ts`, D734). `appConnections` is
33558
+ * many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
33559
+ * by at most one address.
33560
+ */
33561
+ var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
33562
+ var RoleSourceSchema = _enum([
33563
+ "flagged",
33564
+ "auto",
33565
+ "none"
33566
+ ]);
33567
+ /** One single-valued role: the flagged address, the one in use, and why. */
33568
+ var HubAddressRoleResolutionSchema = object({
33569
+ /** The address carrying the flag, or null = automatic. */
33570
+ flagged: string().nullable(),
33571
+ /** The address in use, or null when nothing qualifies (never loopback). */
33572
+ resolved: string().nullable(),
33573
+ source: RoleSourceSchema
33574
+ });
33575
+ var HubAppConnectionsResolutionSchema = object({
33576
+ /** The addresses flagged `appConnections`, or empty = automatic. */
33577
+ flagged: array(string()).readonly(),
33578
+ /** What the apps race right now. */
33579
+ resolved: array(string()).readonly(),
33580
+ source: RoleSourceSchema
33581
+ });
33582
+ var HubAddressBookSchema = object({
33583
+ rows: array(ConnectionEndpointSchema.extend({
33584
+ /** In the hub's detected palette right now. */
33585
+ detected: boolean(),
33586
+ /** Entered by the operator (removable). */
33587
+ custom: boolean(),
33588
+ /** The roles explicitly flagged on this address. */
33589
+ flags: array(HubAddressRoleSchema).readonly(),
33590
+ /** The roles this address serves right now — flagged or automatic. */
33591
+ inUse: array(HubAddressRoleSchema).readonly(),
33592
+ /** The roles this address may be flagged with. */
33593
+ eligible: array(HubAddressRoleSchema).readonly()
33594
+ })).readonly(),
33595
+ roles: object({
33596
+ appConnections: HubAppConnectionsResolutionSchema,
33597
+ notificationTaps: HubAddressRoleResolutionSchema,
33598
+ internal: HubAddressRoleResolutionSchema,
33599
+ publicEndpoint: HubAddressRoleResolutionSchema
33600
+ }),
33601
+ /** The `hub=` an app link carries (D709), or null. */
33602
+ appLinkHub: string().nullable()
33603
+ });
33137
33604
  var AllowedAddressesSchema = object({
33138
33605
  /**
33139
33606
  * Allowlist of interface addresses operators have explicitly opted
@@ -33175,8 +33642,29 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33175
33642
  * Pass `'https'` when the caller is itself loaded over HTTPS
33176
33643
  * to avoid mixed-content blocks in the browser. The public
33177
33644
  * tunnel always emits `https://` regardless. */
33178
- scheme: _enum(["http", "https"]).optional()
33179
- }), 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, {
33645
+ scheme: _enum(["http", "https"]).optional(),
33646
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33647
+ * an address notification taps can be flagged with, not a hub
33648
+ * route. Default `false`: racers and rankers never see it. */
33649
+ includeAppLink: boolean().optional()
33650
+ }), 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({
33651
+ baseUrl: string(),
33652
+ label: string().max(80)
33653
+ }), HubAddressBookSchema, {
33654
+ kind: "mutation",
33655
+ auth: "admin"
33656
+ }), method(object({ baseUrl: string() }), HubAddressBookSchema, {
33657
+ kind: "mutation",
33658
+ auth: "admin"
33659
+ }), method(object({
33660
+ role: HubAddressRoleSchema,
33661
+ baseUrl: string().nullable(),
33662
+ enabled: boolean(),
33663
+ acceptInsecureHttp: boolean().optional()
33664
+ }), HubAddressBookSchema, {
33665
+ kind: "mutation",
33666
+ auth: "admin"
33667
+ }), 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, {
33180
33668
  kind: "mutation",
33181
33669
  auth: "admin"
33182
33670
  }), method(object({
@@ -33504,7 +33992,7 @@ var MeshPeerSchema = object({
33504
33992
  tags: array(string()).readonly(),
33505
33993
  /** True when the peer advertises itself as an exit-node candidate. */
33506
33994
  exitNodeOption: boolean(),
33507
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
33995
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
33508
33996
  advertisedRoutes: array(string()).readonly(),
33509
33997
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
33510
33998
  userLogin: string().nullable(),
@@ -33634,7 +34122,8 @@ var MotionStatusSchema = object({
33634
34122
  * writes this slice (not even a boot seed), and neither does the runner's
33635
34123
  * phase machine: its phase is "a session is attached" for every on-motion
33636
34124
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
33637
- * A provider's `isDetected` answers from the hub's slice.
34125
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
34126
+ * (`hubMotionNativeProvider`).
33638
34127
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
33639
34128
  * imports) — the provider pushes both edges itself, from the upstream
33640
34129
  * system's own state change. That is the sensor's own fact.
@@ -34832,7 +35321,13 @@ var OsdStatusSchema = object({ overlays: array(object({
34832
35321
  */
34833
35322
  availablePositions: array(OsdPositionEnum).readonly(),
34834
35323
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
34835
- readOnly: boolean().optional()
35324
+ readOnly: boolean().optional(),
35325
+ /**
35326
+ * Firmware text ceiling for this overlay. Absent = no known limit.
35327
+ * The OSD manager truncates here on every write — never stores its own
35328
+ * copy on the binding.
35329
+ */
35330
+ maxCharacters: number().int().positive().optional()
34836
35331
  })).readonly() });
34837
35332
  var OsdOverlayPatchSchema = object({
34838
35333
  enabled: boolean().optional(),
@@ -34883,7 +35378,9 @@ var OsdTemplateBindingSchema = object({
34883
35378
  valuePath: string().min(1).max(64),
34884
35379
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
34885
35380
  displayUnit: string().max(16).optional(),
34886
- maxDecimals: number().int().min(0).max(4).default(1)
35381
+ maxDecimals: number().int().min(0).max(4).default(1),
35382
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
35383
+ valueMap: record(string(), string()).optional()
34887
35384
  });
34888
35385
  /**
34889
35386
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34933,18 +35430,11 @@ var OsdSlotBindingSchema = object({
34933
35430
  source: OsdSourceSchema,
34934
35431
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34935
35432
  template: string().max(96).default("${value}"),
34936
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34937
- maxCharacters: number().int().min(4).max(64).optional(),
34938
35433
  /**
34939
35434
  * Decimal places for a numeric value. `0` yields an integer — the
34940
35435
  * documented workaround for firmwares that reject `.` in overlay text.
34941
35436
  */
34942
35437
  maxDecimals: number().int().min(0).max(4).default(1),
34943
- /**
34944
- * Appended via `${unit}` when no unit conversion produces a label.
34945
- * Prefer `source.displayUnit` for converted device-state values.
34946
- */
34947
- unitLabel: string().max(8).optional(),
34948
35438
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34949
35439
  valueMap: record(string(), string()).optional(),
34950
35440
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34953,9 +35443,7 @@ var OsdSlotBindingSchema = object({
34953
35443
  * Display gate, in the notification centre's condition vocabulary.
34954
35444
  * Only the keys reported by `getConditionSupport` are accepted.
34955
35445
  */
34956
- conditions: NcConditionsSchema.optional(),
34957
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34958
- fallbackText: string().max(64).default("")
35446
+ conditions: NcConditionsSchema.optional()
34959
35447
  });
34960
35448
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34961
35449
  var OsdSlotViewSchema = object({
@@ -40182,6 +40670,16 @@ var zoneRulesCapability = {
40182
40670
  durability: "restored"
40183
40671
  };
40184
40672
  SOURCE_CAPS.filter((cap) => cap !== "switch" && cap !== "motion");
40673
+ Object.freeze({
40674
+ person: .5,
40675
+ vehicle: .5,
40676
+ animal: .5
40677
+ });
40678
+ Object.freeze({
40679
+ person: .65,
40680
+ vehicle: .65,
40681
+ animal: .65
40682
+ });
40185
40683
  /**
40186
40684
  * Accessory device helpers — shared across drivers.
40187
40685
  *
@@ -43062,90 +43560,18 @@ Object.freeze({
43062
43560
  addonId: null,
43063
43561
  access: "create"
43064
43562
  },
43065
- "decoder.createSession": {
43066
- capName: "decoder",
43067
- capScope: "system",
43068
- addonId: null,
43069
- access: "view"
43070
- },
43071
- "decoder.destroySession": {
43072
- capName: "decoder",
43073
- capScope: "system",
43074
- addonId: null,
43075
- access: "delete"
43076
- },
43077
- "decoder.getFrame": {
43078
- capName: "decoder",
43079
- capScope: "system",
43080
- addonId: null,
43081
- access: "view"
43082
- },
43083
43563
  "decoder.getInfo": {
43084
43564
  capName: "decoder",
43085
43565
  capScope: "system",
43086
43566
  addonId: null,
43087
43567
  access: "view"
43088
43568
  },
43089
- "decoder.getShmStats": {
43090
- capName: "decoder",
43091
- capScope: "system",
43092
- addonId: null,
43093
- access: "view"
43094
- },
43095
- "decoder.getStats": {
43096
- capName: "decoder",
43097
- capScope: "system",
43098
- addonId: null,
43099
- access: "view"
43100
- },
43101
- "decoder.listActiveSessions": {
43102
- capName: "decoder",
43103
- capScope: "system",
43104
- addonId: null,
43105
- access: "view"
43106
- },
43107
- "decoder.openStream": {
43108
- capName: "decoder",
43109
- capScope: "system",
43110
- addonId: null,
43111
- access: "view"
43112
- },
43113
- "decoder.pullFrames": {
43114
- capName: "decoder",
43115
- capScope: "system",
43116
- addonId: null,
43117
- access: "view"
43118
- },
43119
- "decoder.pullHandles": {
43120
- capName: "decoder",
43121
- capScope: "system",
43122
- addonId: null,
43123
- access: "view"
43124
- },
43125
- "decoder.pushPacket": {
43126
- capName: "decoder",
43127
- capScope: "system",
43128
- addonId: null,
43129
- access: "view"
43130
- },
43131
43569
  "decoder.reprobeHwaccel": {
43132
43570
  capName: "decoder",
43133
43571
  capScope: "system",
43134
43572
  addonId: null,
43135
43573
  access: "create"
43136
43574
  },
43137
- "decoder.supportsCodec": {
43138
- capName: "decoder",
43139
- capScope: "system",
43140
- addonId: null,
43141
- access: "view"
43142
- },
43143
- "decoder.updateConfig": {
43144
- capName: "decoder",
43145
- capScope: "system",
43146
- addonId: null,
43147
- access: "view"
43148
- },
43149
43575
  "detectionPipeline.applyDeviceSettingsPatch": {
43150
43576
  capName: "detection-pipeline",
43151
43577
  capScope: "device",
@@ -44634,12 +45060,24 @@ Object.freeze({
44634
45060
  addonId: null,
44635
45061
  access: "view"
44636
45062
  },
45063
+ "localNetwork.addCustomAddress": {
45064
+ capName: "local-network",
45065
+ capScope: "system",
45066
+ addonId: null,
45067
+ access: "create"
45068
+ },
44637
45069
  "localNetwork.downloadCa": {
44638
45070
  capName: "local-network",
44639
45071
  capScope: "system",
44640
45072
  addonId: null,
44641
45073
  access: "view"
44642
45074
  },
45075
+ "localNetwork.getAddresses": {
45076
+ capName: "local-network",
45077
+ capScope: "system",
45078
+ addonId: null,
45079
+ access: "view"
45080
+ },
44643
45081
  "localNetwork.getAllowedAddresses": {
44644
45082
  capName: "local-network",
44645
45083
  capScope: "system",
@@ -44652,6 +45090,12 @@ Object.freeze({
44652
45090
  addonId: null,
44653
45091
  access: "view"
44654
45092
  },
45093
+ "localNetwork.getHubAddresses": {
45094
+ capName: "local-network",
45095
+ capScope: "system",
45096
+ addonId: null,
45097
+ access: "view"
45098
+ },
44655
45099
  "localNetwork.getNotificationEndpoint": {
44656
45100
  capName: "local-network",
44657
45101
  capScope: "system",
@@ -44688,6 +45132,12 @@ Object.freeze({
44688
45132
  addonId: null,
44689
45133
  access: "create"
44690
45134
  },
45135
+ "localNetwork.removeCustomAddress": {
45136
+ capName: "local-network",
45137
+ capScope: "system",
45138
+ addonId: null,
45139
+ access: "delete"
45140
+ },
44691
45141
  "localNetwork.resetAllowlistToBestMatch": {
44692
45142
  capName: "local-network",
44693
45143
  capScope: "system",
@@ -44700,6 +45150,12 @@ Object.freeze({
44700
45150
  addonId: null,
44701
45151
  access: "create"
44702
45152
  },
45153
+ "localNetwork.setAddressRole": {
45154
+ capName: "local-network",
45155
+ capScope: "system",
45156
+ addonId: null,
45157
+ access: "create"
45158
+ },
44703
45159
  "localNetwork.setAllowedAddresses": {
44704
45160
  capName: "local-network",
44705
45161
  capScope: "system",
@@ -46194,13 +46650,13 @@ Object.freeze({
46194
46650
  addonId: null,
46195
46651
  access: "delete"
46196
46652
  },
46197
- "pipelineExecutor.deleteModel": {
46653
+ "pipelineExecutor.clearModelBoundDeviceOverrides": {
46198
46654
  capName: "pipeline-executor",
46199
46655
  capScope: "system",
46200
46656
  addonId: null,
46201
46657
  access: "delete"
46202
46658
  },
46203
- "pipelineExecutor.deleteTemplate": {
46659
+ "pipelineExecutor.deleteModel": {
46204
46660
  capName: "pipeline-executor",
46205
46661
  capScope: "system",
46206
46662
  addonId: null,
@@ -46344,12 +46800,6 @@ Object.freeze({
46344
46800
  addonId: null,
46345
46801
  access: "view"
46346
46802
  },
46347
- "pipelineExecutor.listTemplates": {
46348
- capName: "pipeline-executor",
46349
- capScope: "system",
46350
- addonId: null,
46351
- access: "view"
46352
- },
46353
46803
  "pipelineExecutor.rearmInferenceDevice": {
46354
46804
  capName: "pipeline-executor",
46355
46805
  capScope: "system",
@@ -46374,12 +46824,6 @@ Object.freeze({
46374
46824
  addonId: null,
46375
46825
  access: "create"
46376
46826
  },
46377
- "pipelineExecutor.saveTemplate": {
46378
- capName: "pipeline-executor",
46379
- capScope: "system",
46380
- addonId: null,
46381
- access: "create"
46382
- },
46383
46827
  "pipelineExecutor.setVideoPipelineSteps": {
46384
46828
  capName: "pipeline-executor",
46385
46829
  capScope: "system",
@@ -46398,41 +46842,35 @@ Object.freeze({
46398
46842
  addonId: null,
46399
46843
  access: "create"
46400
46844
  },
46401
- "pipelineExecutor.updateTemplate": {
46402
- capName: "pipeline-executor",
46403
- capScope: "system",
46404
- addonId: null,
46405
- access: "create"
46406
- },
46407
46845
  "pipelineExecutor.validatePipeline": {
46408
46846
  capName: "pipeline-executor",
46409
46847
  capScope: "system",
46410
46848
  addonId: null,
46411
46849
  access: "view"
46412
46850
  },
46413
- "pipelineOrchestrator.applyDeviceSettingsPatch": {
46851
+ "pipelineOrchestrator.applyAutoTune": {
46414
46852
  capName: "pipeline-orchestrator",
46415
46853
  capScope: "system",
46416
46854
  addonId: null,
46417
46855
  access: "create"
46418
46856
  },
46419
- "pipelineOrchestrator.assignAudio": {
46857
+ "pipelineOrchestrator.applyDeviceSettingsPatch": {
46420
46858
  capName: "pipeline-orchestrator",
46421
46859
  capScope: "system",
46422
46860
  addonId: null,
46423
46861
  access: "create"
46424
46862
  },
46425
- "pipelineOrchestrator.assignPipeline": {
46863
+ "pipelineOrchestrator.assignAudio": {
46426
46864
  capName: "pipeline-orchestrator",
46427
46865
  capScope: "system",
46428
46866
  addonId: null,
46429
46867
  access: "create"
46430
46868
  },
46431
- "pipelineOrchestrator.deleteTemplate": {
46869
+ "pipelineOrchestrator.assignPipeline": {
46432
46870
  capName: "pipeline-orchestrator",
46433
46871
  capScope: "system",
46434
46872
  addonId: null,
46435
- access: "delete"
46873
+ access: "create"
46436
46874
  },
46437
46875
  "pipelineOrchestrator.getAgentLoad": {
46438
46876
  capName: "pipeline-orchestrator",
@@ -46524,6 +46962,12 @@ Object.freeze({
46524
46962
  addonId: null,
46525
46963
  access: "view"
46526
46964
  },
46965
+ "pipelineOrchestrator.getEffectiveShares": {
46966
+ capName: "pipeline-orchestrator",
46967
+ capScope: "system",
46968
+ addonId: null,
46969
+ access: "view"
46970
+ },
46527
46971
  "pipelineOrchestrator.getGlobalMetrics": {
46528
46972
  capName: "pipeline-orchestrator",
46529
46973
  capScope: "system",
@@ -46560,19 +47004,19 @@ Object.freeze({
46560
47004
  addonId: null,
46561
47005
  access: "view"
46562
47006
  },
46563
- "pipelineOrchestrator.getReconcileFromDiskStatus": {
47007
+ "pipelineOrchestrator.getPlacementStats": {
46564
47008
  capName: "pipeline-orchestrator",
46565
47009
  capScope: "system",
46566
47010
  addonId: null,
46567
47011
  access: "view"
46568
47012
  },
46569
- "pipelineOrchestrator.listAgentSettings": {
47013
+ "pipelineOrchestrator.getReconcileFromDiskStatus": {
46570
47014
  capName: "pipeline-orchestrator",
46571
47015
  capScope: "system",
46572
47016
  addonId: null,
46573
47017
  access: "view"
46574
47018
  },
46575
- "pipelineOrchestrator.listTemplates": {
47019
+ "pipelineOrchestrator.listAgentSettings": {
46576
47020
  capName: "pipeline-orchestrator",
46577
47021
  capScope: "system",
46578
47022
  addonId: null,
@@ -46584,6 +47028,12 @@ Object.freeze({
46584
47028
  addonId: null,
46585
47029
  access: "create"
46586
47030
  },
47031
+ "pipelineOrchestrator.planAutoTune": {
47032
+ capName: "pipeline-orchestrator",
47033
+ capScope: "system",
47034
+ addonId: null,
47035
+ access: "view"
47036
+ },
46587
47037
  "pipelineOrchestrator.rebalance": {
46588
47038
  capName: "pipeline-orchestrator",
46589
47039
  capScope: "system",
@@ -46626,12 +47076,6 @@ Object.freeze({
46626
47076
  addonId: null,
46627
47077
  access: "create"
46628
47078
  },
46629
- "pipelineOrchestrator.saveTemplate": {
46630
- capName: "pipeline-orchestrator",
46631
- capScope: "system",
46632
- addonId: null,
46633
- access: "create"
46634
- },
46635
47079
  "pipelineOrchestrator.setAgentCapabilities": {
46636
47080
  capName: "pipeline-orchestrator",
46637
47081
  capScope: "system",
@@ -46644,12 +47088,6 @@ Object.freeze({
46644
47088
  addonId: null,
46645
47089
  access: "create"
46646
47090
  },
46647
- "pipelineOrchestrator.setAgentDetectWeight": {
46648
- capName: "pipeline-orchestrator",
46649
- capScope: "system",
46650
- addonId: null,
46651
- access: "create"
46652
- },
46653
47091
  "pipelineOrchestrator.setAgentInferenceDevices": {
46654
47092
  capName: "pipeline-orchestrator",
46655
47093
  capScope: "system",
@@ -46686,6 +47124,12 @@ Object.freeze({
46686
47124
  addonId: null,
46687
47125
  access: "create"
46688
47126
  },
47127
+ "pipelineOrchestrator.setCameraStepSettings": {
47128
+ capName: "pipeline-orchestrator",
47129
+ capScope: "system",
47130
+ addonId: null,
47131
+ access: "create"
47132
+ },
46689
47133
  "pipelineOrchestrator.setCameraStepToggle": {
46690
47134
  capName: "pipeline-orchestrator",
46691
47135
  capScope: "system",
@@ -46704,25 +47148,37 @@ Object.freeze({
46704
47148
  addonId: null,
46705
47149
  access: "create"
46706
47150
  },
47151
+ "pipelineOrchestrator.setLoadBalancingShares": {
47152
+ capName: "pipeline-orchestrator",
47153
+ capScope: "system",
47154
+ addonId: null,
47155
+ access: "create"
47156
+ },
46707
47157
  "pipelineOrchestrator.setPipelineDevicePin": {
46708
47158
  capName: "pipeline-orchestrator",
46709
47159
  capScope: "system",
46710
47160
  addonId: null,
46711
47161
  access: "create"
46712
47162
  },
46713
- "pipelineOrchestrator.unassignAudio": {
47163
+ "pipelineOrchestrator.setShareSource": {
46714
47164
  capName: "pipeline-orchestrator",
46715
47165
  capScope: "system",
46716
47166
  addonId: null,
46717
47167
  access: "create"
46718
47168
  },
46719
- "pipelineOrchestrator.unassignPipeline": {
47169
+ "pipelineOrchestrator.suggestShares": {
47170
+ capName: "pipeline-orchestrator",
47171
+ capScope: "system",
47172
+ addonId: null,
47173
+ access: "view"
47174
+ },
47175
+ "pipelineOrchestrator.unassignAudio": {
46720
47176
  capName: "pipeline-orchestrator",
46721
47177
  capScope: "system",
46722
47178
  addonId: null,
46723
47179
  access: "create"
46724
47180
  },
46725
- "pipelineOrchestrator.updateTemplate": {
47181
+ "pipelineOrchestrator.unassignPipeline": {
46726
47182
  capName: "pipeline-orchestrator",
46727
47183
  capScope: "system",
46728
47184
  addonId: null,
@@ -48162,12 +48618,6 @@ Object.freeze({
48162
48618
  addonId: null,
48163
48619
  access: "view"
48164
48620
  },
48165
- "streamBroker.pullFrameHandles": {
48166
- capName: "stream-broker",
48167
- capScope: "system",
48168
- addonId: null,
48169
- access: "view"
48170
- },
48171
48621
  "streamBroker.regenerateRtspToken": {
48172
48622
  capName: "stream-broker",
48173
48623
  capScope: "system",
@@ -48234,12 +48684,6 @@ Object.freeze({
48234
48684
  addonId: null,
48235
48685
  access: "create"
48236
48686
  },
48237
- "streamBroker.subscribeFrames": {
48238
- capName: "stream-broker",
48239
- capScope: "system",
48240
- addonId: null,
48241
- access: "create"
48242
- },
48243
48687
  "streamBroker.unassignProfile": {
48244
48688
  capName: "stream-broker",
48245
48689
  capScope: "system",
@@ -48252,12 +48696,6 @@ Object.freeze({
48252
48696
  addonId: null,
48253
48697
  access: "create"
48254
48698
  },
48255
- "streamBroker.unsubscribeFrames": {
48256
- capName: "stream-broker",
48257
- capScope: "system",
48258
- addonId: null,
48259
- access: "create"
48260
- },
48261
48699
  "streamCatalog.getCatalog": {
48262
48700
  capName: "stream-catalog",
48263
48701
  capScope: "device",
@@ -48954,6 +49392,12 @@ Object.freeze({
48954
49392
  addonId: null,
48955
49393
  access: "create"
48956
49394
  },
49395
+ "webrtcSession.applyDownlinkProbe": {
49396
+ capName: "webrtc-session",
49397
+ capScope: "device",
49398
+ addonId: null,
49399
+ access: "create"
49400
+ },
48957
49401
  "webrtcSession.closeSession": {
48958
49402
  capName: "webrtc-session",
48959
49403
  capScope: "device",
@@ -50765,11 +51209,6 @@ Object.freeze({
50765
51209
  form: "single",
50766
51210
  optional: false
50767
51211
  }],
50768
- "decoder.createSession": [{
50769
- name: "deviceId",
50770
- form: "single",
50771
- optional: true
50772
- }],
50773
51212
  "detectionPipeline.applyDeviceSettingsPatch": [{
50774
51213
  name: "deviceId",
50775
51214
  form: "single",
@@ -52000,6 +52439,11 @@ Object.freeze({
52000
52439
  form: "single",
52001
52440
  optional: false
52002
52441
  }],
52442
+ "pipelineExecutor.clearModelBoundDeviceOverrides": [{
52443
+ name: "deviceIds",
52444
+ form: "array",
52445
+ optional: true
52446
+ }],
52003
52447
  "pipelineExecutor.runPipeline": [{
52004
52448
  name: "deviceId",
52005
52449
  form: "single",
@@ -52105,6 +52549,11 @@ Object.freeze({
52105
52549
  form: "single",
52106
52550
  optional: false
52107
52551
  }],
52552
+ "pipelineOrchestrator.setCameraStepSettings": [{
52553
+ name: "deviceId",
52554
+ form: "single",
52555
+ optional: false
52556
+ }],
52108
52557
  "pipelineOrchestrator.setCameraStepToggle": [{
52109
52558
  name: "deviceId",
52110
52559
  form: "single",
@@ -52876,6 +53325,11 @@ Object.freeze({
52876
53325
  form: "single",
52877
53326
  optional: false
52878
53327
  }],
53328
+ "webrtcSession.applyDownlinkProbe": [{
53329
+ name: "deviceId",
53330
+ form: "single",
53331
+ optional: false
53332
+ }],
52879
53333
  "webrtcSession.closeSession": [{
52880
53334
  name: "deviceId",
52881
53335
  form: "single",
@@ -53105,6 +53559,8 @@ new Map(Object.entries({
53105
53559
  "detection-blind": "device-events",
53106
53560
  "node-online": "system",
53107
53561
  "node-offline": "system",
53562
+ "node-restarting": "system",
53563
+ "node-updating": "system",
53108
53564
  "node-inference-unavailable": "system",
53109
53565
  "addon-crash-loop": "system",
53110
53566
  "addon-update-available": "system",
@@ -53182,18 +53638,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53182
53638
  kinds: [
53183
53639
  "node-offline",
53184
53640
  "node-online",
53641
+ "node-restarting",
53185
53642
  "node-inference-unavailable"
53186
53643
  ]
53187
53644
  },
53188
53645
  {
53189
53646
  id: "addons",
53190
53647
  family: "system",
53191
- label: "Addons",
53192
- kinds: [
53193
- "addon-crash-loop",
53194
- "addon-update-available",
53195
- "addon-updated"
53196
- ]
53648
+ label: "Addons stopped",
53649
+ kinds: ["addon-crash-loop"]
53650
+ },
53651
+ {
53652
+ id: "addon-updates",
53653
+ family: "system",
53654
+ label: "Addon updates",
53655
+ kinds: ["addon-update-available", "addon-updated"]
53197
53656
  },
53198
53657
  {
53199
53658
  id: "updates",
@@ -53201,6 +53660,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53201
53660
  label: "Server & container updates",
53202
53661
  kinds: [
53203
53662
  "server-update-available",
53663
+ "node-updating",
53204
53664
  "server-updated",
53205
53665
  "wrapper-update-available"
53206
53666
  ]
@@ -53348,18 +53808,21 @@ var STATE_SUMMARY_SECTION_VARS = [
53348
53808
  kinds: [
53349
53809
  "node-offline",
53350
53810
  "node-online",
53811
+ "node-restarting",
53351
53812
  "node-inference-unavailable"
53352
53813
  ]
53353
53814
  },
53354
53815
  {
53355
53816
  name: "summaryAddons",
53356
- label: "Summary: addons",
53357
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
53358
- kinds: [
53359
- "addon-crash-loop",
53360
- "addon-update-available",
53361
- "addon-updated"
53362
- ]
53817
+ label: "Summary: addons stopped",
53818
+ example: "hub — recorder stopped after repeated crashes",
53819
+ kinds: ["addon-crash-loop"]
53820
+ },
53821
+ {
53822
+ name: "summaryAddonUpdates",
53823
+ label: "Summary: addon updates",
53824
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
53825
+ kinds: ["addon-update-available", "addon-updated"]
53363
53826
  },
53364
53827
  {
53365
53828
  name: "summaryUpdates",
@@ -53367,6 +53830,7 @@ var STATE_SUMMARY_SECTION_VARS = [
53367
53830
  example: "server 1.2.377 → 1.2.378",
53368
53831
  kinds: [
53369
53832
  "server-update-available",
53833
+ "node-updating",
53370
53834
  "server-updated",
53371
53835
  "wrapper-update-available"
53372
53836
  ]
@@ -53399,7 +53863,7 @@ var STATE_SUMMARY_VARS = [
53399
53863
  {
53400
53864
  name: "summarySection",
53401
53865
  label: "Summary: this section",
53402
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
53866
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
53403
53867
  example: "Batterie scariche",
53404
53868
  group: "system",
53405
53869
  families: ["rule"],
@@ -53443,6 +53907,7 @@ var STATE_SUMMARY_VARS = [
53443
53907
  [...RULE_BODY_ONLY],
53444
53908
  [...RULE_TEXT],
53445
53909
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53910
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
53446
53911
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
53447
53912
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
53448
53913
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -53483,6 +53948,8 @@ var STATE_SUMMARY_VARS = [
53483
53948
  [...RULE_TEXT],
53484
53949
  [...RULE_TEXT],
53485
53950
  [...RULE_TEXT],
53951
+ [...RULE_TEXT],
53952
+ [...RULE_TEXT],
53486
53953
  ...STATE_SUMMARY_VARS
53487
53954
  ];
53488
53955
  new Set([
@@ -54095,7 +54562,7 @@ function buildConnectionFormSchema() {
54095
54562
  key: "host",
54096
54563
  label: "Hub host / IP",
54097
54564
  required: true,
54098
- placeholder: "192.168.x.x"
54565
+ placeholder: "192.168.10.50"
54099
54566
  },
54100
54567
  {
54101
54568
  type: "password",