@camstack/addon-admin-ui 1.1.34 → 1.1.35

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 (80) hide show
  1. package/dist/assets/{AddLocationWizard-Bi0ljsVA.js → AddLocationWizard-CLq90_u2.js} +1 -1
  2. package/dist/assets/{AddonCollectionPage-DBF9Z9As.js → AddonCollectionPage-BA8X6RO6.js} +1 -1
  3. package/dist/assets/{Addons-B-__KXJU.js → Addons-Dmny2oi6.js} +1 -1
  4. package/dist/assets/{AdminTabs-BuqsvGrG.js → AdminTabs-5A6P8O_a.js} +1 -1
  5. package/dist/assets/{BrokerForm-_89nTW-H.js → BrokerForm-CUx6NDtG.js} +1 -1
  6. package/dist/assets/{Capabilities-ClcXLZXO.js → Capabilities-BVszL1LF.js} +1 -1
  7. package/dist/assets/{CapabilityBadges-D17MpdW-.js → CapabilityBadges-CwTPT3fD.js} +1 -1
  8. package/dist/assets/{Cluster-Duon566q.js → Cluster-Chv9G6_O.js} +1 -1
  9. package/dist/assets/{Dashboard-DRCyjJak.js → Dashboard-DbC62uqI.js} +1 -1
  10. package/dist/assets/{Data-CeLbKmt6.js → Data-BUznBWyr.js} +1 -1
  11. package/dist/assets/{DetectionIntelligence-Co-3EN_y.js → DetectionIntelligence-HeQ6GTUQ.js} +1 -1
  12. package/dist/assets/DeviceDetail-DnWTJJ-h.js +2 -0
  13. package/dist/assets/{Devices-DanUITRF.js → Devices-c-bVBfeY.js} +1 -1
  14. package/dist/assets/{EmbedPlayerPage-g2S5bdPi.js → EmbedPlayerPage-DFmRx9R4.js} +1 -1
  15. package/dist/assets/{FormBuilder-BKE262Ak.js → FormBuilder-D51o_7oF.js} +1 -1
  16. package/dist/assets/{Identity-CzZXW3_y.js → Identity-FvciUSAp.js} +1 -1
  17. package/dist/assets/{IntegrationDetail-Cd9xdRi_.js → IntegrationDetail-BaUaXA30.js} +1 -1
  18. package/dist/assets/{Integrations-B4fhe1Gb.js → Integrations-BNOKmbhn.js} +1 -1
  19. package/dist/assets/{Integrations-D3majjXx.js → Integrations-DpjLzdQ7.js} +1 -1
  20. package/dist/assets/{Logs-CgKEHupO.js → Logs-BG8Ez3x2.js} +1 -1
  21. package/dist/assets/{MotionZonesSettings-A8_xE3RR.js → MotionZonesSettings-C0tKy6bY.js} +1 -1
  22. package/dist/assets/{MyAccess-CQ4EIWqU.js → MyAccess-DlE2hFZQ.js} +1 -1
  23. package/dist/assets/{Network-BajDLc8U.js → Network-BT8kfPzC.js} +1 -1
  24. package/dist/assets/{NodeAddonsSettingsPanel-G-afOE2k.js → NodeAddonsSettingsPanel-C4ZZS81s.js} +1 -1
  25. package/dist/assets/{NotificationTargets-DQmAITEb.js → NotificationTargets-AOV4c2fk.js} +1 -1
  26. package/dist/assets/Pipeline-v6Z2AYXa.js +1 -0
  27. package/dist/assets/{PrivacyMaskSettings-D-Yfij0p.js → PrivacyMaskSettings-C2PhImNZ.js} +1 -1
  28. package/dist/assets/{ProviderIcon-D2GVIM6D.js → ProviderIcon-CuwKEs4L.js} +1 -1
  29. package/dist/assets/{ScanNetworkModal-CXe1ZhrW.js → ScanNetworkModal-HQUtzQKi.js} +1 -1
  30. package/dist/assets/{Settings-duX068YK.js → Settings-CDFLQvK-.js} +1 -1
  31. package/dist/assets/{Showroom-tEsQLYvU.js → Showroom-4xn4qcYE.js} +1 -1
  32. package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DpZ6S4A1.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-v6CK7VHn.js} +1 -1
  33. package/dist/assets/{build-cluster-graph-DEgurNYu.js → build-cluster-graph-CuGELXYk.js} +1 -1
  34. package/dist/assets/circle-check-big-7qTjhOxp.js +1 -0
  35. package/dist/assets/{copy-BZEouQxh.js → copy-DL-OGc1S.js} +1 -1
  36. package/dist/assets/{dist-B5BcBM_J.js → dist-BJubQcYg.js} +1 -1
  37. package/dist/assets/dist-d0TPfAUt.js +7 -0
  38. package/dist/assets/{download-BdD4jpmM.js → download-CZaTdXZn.js} +1 -1
  39. package/dist/assets/{hostInit-DL0Pq8FG.js → hostInit-w8EphiS8.js} +1 -1
  40. package/dist/assets/index-BCSsSQW7.js +4 -0
  41. package/dist/assets/index-CGxuGDXN.css +2 -0
  42. package/dist/assets/{key-round-Co1IZCyf.js → key-round-ioZ-USeC.js} +1 -1
  43. package/dist/assets/{mf-entry-bootstrap-0-9f7f6a36.js → mf-entry-bootstrap-0-c13e5d05.js} +2 -2
  44. package/dist/assets/{pencil-Ctcgfyao.js → pencil-D5sySkML.js} +1 -1
  45. package/dist/assets/{player-overlays-D_uAA1FM.js → player-overlays-xMPaP_6Y.js} +1 -1
  46. package/dist/assets/plus-Cxu4qVNH.js +1 -0
  47. package/dist/assets/{radio-COzWf8RL.js → radio-C6T7cOsl.js} +1 -1
  48. package/dist/assets/{refresh-cw-DPd788Ly.js → refresh-cw-DLg593XV.js} +1 -1
  49. package/dist/assets/remoteEntry-C5R-yGp5.js +1 -0
  50. package/dist/assets/{rotate-ccw-D4xWcHzx.js → rotate-ccw-CY-8uJk2.js} +1 -1
  51. package/dist/assets/rotate-cw-DNHvuBgr.js +1 -0
  52. package/dist/assets/search-VCa-IBNw.js +1 -0
  53. package/dist/assets/{server-DCZCFjSL.js → server-B5N0HCvj.js} +1 -1
  54. package/dist/assets/{sparkles-DL5wzv3h.js → sparkles-_ITqssg1.js} +1 -1
  55. package/dist/assets/square--lnhYpeY.js +1 -0
  56. package/dist/assets/{square-check-big-DXqD6BOi.js → square-check-big-pBYly1ij.js} +1 -1
  57. package/dist/assets/src-CCcR9uxQ.js +7 -0
  58. package/dist/assets/src-D94s72CH.js +67 -0
  59. package/dist/assets/{upload-CnDk7r-2.js → upload-Blub_jbd.js} +1 -1
  60. package/dist/assets/{useDevice-CSvcJkG5.js → useDevice-ClhbzL4d.js} +1 -1
  61. package/dist/assets/{useEventInvalidation-D85JeECP.js → useEventInvalidation-DbaSngzX.js} +1 -1
  62. package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-wsjHIjiy.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_--SLJN82f.js} +2 -2
  63. package/dist/assets/{wifi-DZtU-62o.js → wifi-AoyLxGvB.js} +1 -1
  64. package/dist/assets/{zap-C4RnkQsi.js → zap-NzcDY2_X.js} +1 -1
  65. package/dist/index.html +6 -6
  66. package/dist/server/addon.js +185 -186
  67. package/package.json +1 -1
  68. package/dist/assets/DeviceDetail-BbrCW8vA.js +0 -2
  69. package/dist/assets/Pipeline-CzR4gmRW.js +0 -1
  70. package/dist/assets/circle-check-big-djmpxb6e.js +0 -1
  71. package/dist/assets/dist-BEwW84yT.js +0 -7
  72. package/dist/assets/index-2HwvWrOH.css +0 -2
  73. package/dist/assets/index-BGSe7zm2.js +0 -4
  74. package/dist/assets/plus-BPews3hd.js +0 -1
  75. package/dist/assets/remoteEntry-DUPeCPoh.js +0 -1
  76. package/dist/assets/rotate-cw-DXeseGvV.js +0 -1
  77. package/dist/assets/search-D3qB3OId.js +0 -1
  78. package/dist/assets/square-DaYEm0Ao.js +0 -1
  79. package/dist/assets/src-CSLY6BPe.js +0 -67
  80. package/dist/assets/src-DkLajgHy.js +0 -7
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-CZDdRBua.mjs
4632
+ //#region ../types/dist/sleep-Cc14_yxc.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -4815,6 +4815,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4815
4815
  */
4816
4816
  EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
4817
4817
  /**
4818
+ * The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
4819
+ * Emitted by addon-pipeline-orchestrator whenever it (re)derives node
4820
+ * capabilities — at boot, on agent online/offline, and on an ingest-node
4821
+ * flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
4822
+ * keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
4823
+ * cross-process `getIngestOwner` query (push the authority's decision instead
4824
+ * of polling it on the hot path). Idempotent state — re-emitted on every
4825
+ * topology change, so a dropped event self-heals on the next one (plus the
4826
+ * broker's long backstop reconcile query).
4827
+ */
4828
+ EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
4829
+ /**
4818
4830
  * Periodic snapshot of per-node pipeline-runner load
4819
4831
  * (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
4820
4832
  * subscribe instead of polling `pipelineRunner.getLocalLoad`.
@@ -6903,6 +6915,28 @@ var ModelFormatsSchema = object({
6903
6915
  tflite: ModelFormatEntrySchema.optional(),
6904
6916
  pt: ModelFormatEntrySchema.optional()
6905
6917
  });
6918
+ /**
6919
+ * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
6920
+ * the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
6921
+ * grouped Family→Tier→Variant picker renders identically in the config UI and
6922
+ * in the pipeline/device steppers. The flat `id` stays the source of truth for
6923
+ * resolution/download/persistence; this is a presentation overlay resolved back
6924
+ * to an `id`.
6925
+ */
6926
+ var ModelVariantGroupSchema = object({
6927
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
6928
+ family: string(),
6929
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
6930
+ tier: string(),
6931
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
6932
+ precision: _enum(["fp32", "int8"]).optional(),
6933
+ /**
6934
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
6935
+ * latency-optimized export (e.g. ReLU-activation / reduced-input variant)
6936
+ * — the slot the future performance variants plug into.
6937
+ */
6938
+ optimization: _enum(["standard", "fast"]).optional()
6939
+ });
6906
6940
  var ModelCatalogEntrySchema = object({
6907
6941
  id: string(),
6908
6942
  name: string(),
@@ -6932,7 +6966,43 @@ var ModelCatalogEntrySchema = object({
6932
6966
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
6933
6967
  * Downloaded into the same modelsDir alongside the model file.
6934
6968
  */
6935
- extraFiles: array(ModelExtraFileSchema).readonly().optional()
6969
+ extraFiles: array(ModelExtraFileSchema).readonly().optional(),
6970
+ /**
6971
+ * LEGACY entry — retained in the catalog so a persisted operator selection
6972
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
6973
+ * model list and excluded from the auto format-default pick. Set on the
6974
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
6975
+ * the active lineup stays the coherent curated ladder without deleting a
6976
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
6977
+ * an explicit legacy id that has a build for the node's format.
6978
+ */
6979
+ legacy: boolean().optional(),
6980
+ /**
6981
+ * Measured quality/latency metadata — populated from the benchmark addon on
6982
+ * the real node classes. Absent = not yet measured (most entries today; the
6983
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
6984
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
6985
+ */
6986
+ metrics: object({
6987
+ map50: number().optional(),
6988
+ p95LatencyMs: record(string(), number()).optional()
6989
+ }).optional(),
6990
+ /**
6991
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
6992
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
6993
+ * the retraining addon and any future commercial distribution.
6994
+ */
6995
+ license: string().optional(),
6996
+ /**
6997
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
6998
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
6999
+ * of a family's sizes and quantizations collapse into one grouped picker
7000
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
7001
+ * (legacy / custom models) — never shown in the grouped selector. The flat
7002
+ * `id` stays the source of truth for resolution/download/persistence; grouping
7003
+ * is a presentation overlay resolved back to an `id`.
7004
+ */
7005
+ group: ModelVariantGroupSchema.optional()
6936
7006
  });
6937
7007
  var ConvertTargetSchema = discriminatedUnion("format", [object({
6938
7008
  format: literal("openvino"),
@@ -6993,8 +7063,8 @@ var RecordingModeSchema = _enum([
6993
7063
  "onAudioThreshold"
6994
7064
  ]);
6995
7065
  /**
6996
- * First-class, authoritative per-camera storage mode — the netta choice the UI
6997
- * reads directly (never inferred from `rules`):
7066
+ * First-class, authoritative per-camera storage mode — the explicit choice the
7067
+ * UI reads directly (never inferred from `rules`):
6998
7068
  * - `off` — not recording.
6999
7069
  * - `events` — record only around triggers (motion / audio threshold),
7000
7070
  * with pre/post-buffer.
@@ -8642,26 +8712,13 @@ DeviceType.Light, method(object({
8642
8712
  percentage: number().min(0).max(100),
8643
8713
  lastChangedAt: number()
8644
8714
  });
8715
+ /** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
8645
8716
  var StreamFormatSchema = _enum([
8646
8717
  "webrtc",
8647
8718
  "hls",
8648
8719
  "mjpeg",
8649
8720
  "rtsp"
8650
8721
  ]);
8651
- var StreamInfoSchema = object({
8652
- streamId: string(),
8653
- format: StreamFormatSchema,
8654
- url: string().nullable(),
8655
- active: boolean()
8656
- });
8657
- method(object({
8658
- streamId: string(),
8659
- sourceUrl: string(),
8660
- codec: string().optional()
8661
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
8662
- streamId: string(),
8663
- format: StreamFormatSchema
8664
- }), string().nullable()), method(_void(), array(StreamInfoSchema));
8665
8722
  var RtspRestreamEntrySchema = object({
8666
8723
  brokerId: string(),
8667
8724
  url: string(),
@@ -9326,7 +9383,7 @@ var ConsumablesStatusSchema = object({
9326
9383
  })),
9327
9384
  lastChangedAt: number()
9328
9385
  });
9329
- DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, method(object({
9386
+ Object.values(DeviceType), method(object({
9330
9387
  deviceId: number().int().nonnegative(),
9331
9388
  key: string().min(1)
9332
9389
  }), _void(), {
@@ -10376,7 +10433,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
10376
10433
  enabled: boolean(),
10377
10434
  modelId: string(),
10378
10435
  children: array(PipelineDefaultStepSchema).readonly(),
10379
- engine: PipelineEngineChoiceSchema.optional(),
10380
10436
  group: string().optional(),
10381
10437
  settings: record(string(), unknown()).optional()
10382
10438
  }));
@@ -10401,7 +10457,9 @@ var PipelineModelOptionSchema = object({
10401
10457
  formats: record(string(), object({
10402
10458
  downloaded: boolean(),
10403
10459
  sizeMB: number()
10404
- }))
10460
+ })),
10461
+ group: ModelVariantGroupSchema.optional(),
10462
+ legacy: boolean().optional()
10405
10463
  });
10406
10464
  var ConfigFieldBridge = custom();
10407
10465
  var PipelineAddonSchemaSchema = object({
@@ -10452,15 +10510,42 @@ var EngineProvisioningSchema = object({
10452
10510
  ]),
10453
10511
  progress: number().optional(),
10454
10512
  error: string().optional(),
10455
- nextRetryAt: number().optional()
10513
+ nextRetryAt: number().optional(),
10514
+ /**
10515
+ * Gate A (config-correctness gate at engine change): human-readable
10516
+ * config issues surfaced EAGERLY when the node's engine changes — model
10517
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
10518
+ * has a <format> build"). Additive/optional: informational only, never
10519
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
10520
+ * Absent/empty when the node-default tree resolves cleanly.
10521
+ */
10522
+ configIssues: array(string()).optional()
10456
10523
  });
10457
10524
  var PipelineStepInputSchema = lazy(() => object({
10458
10525
  addonId: string(),
10459
- modelId: string(),
10526
+ modelId: string().optional(),
10460
10527
  enabled: boolean().default(true),
10461
10528
  children: array(PipelineStepInputSchema).optional(),
10462
10529
  settings: record(string(), unknown()).optional()
10463
10530
  }));
10531
+ var ModelSubstitutionSchema = object({
10532
+ addonId: string(),
10533
+ chosen: string(),
10534
+ running: string(),
10535
+ format: string()
10536
+ });
10537
+ var PipelineValidationIssueSchema = object({
10538
+ addonId: string(),
10539
+ kind: _enum(["unknown-addon", "no-format-build"]),
10540
+ detail: string()
10541
+ });
10542
+ var PipelineValidationResultSchema = object({
10543
+ ok: boolean(),
10544
+ issues: array(PipelineValidationIssueSchema).readonly(),
10545
+ substitutions: array(ModelSubstitutionSchema).readonly(),
10546
+ /** The node's `currentEngine.format` this validation ran against. */
10547
+ format: string()
10548
+ });
10464
10549
  var ReferenceImageEntrySchema = object({
10465
10550
  filename: string(),
10466
10551
  stepIds: array(string()).readonly().optional()
@@ -10531,7 +10616,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
10531
10616
  })) }), object({ success: literal(true) }), {
10532
10617
  kind: "mutation",
10533
10618
  auth: "admin"
10534
- }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10619
+ }), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
10535
10620
  name: string(),
10536
10621
  steps: array(PipelineTemplateStepSchema).readonly(),
10537
10622
  engine: PipelineEngineChoiceSchema
@@ -10791,6 +10876,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10791
10876
  kind: literal("remote-restream"),
10792
10877
  /** The camera's source-owner node (slice 1: always the hub). */
10793
10878
  ownerNodeId: string(),
10879
+ /**
10880
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
10881
+ * per-node `reachableHost` override (Cluster UI). When present the runner
10882
+ * dials THIS host for the owner's restream, in preference to the
10883
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
10884
+ */
10885
+ ownerReachableHost: string().optional(),
10794
10886
  /** Operator override for the owner host the runner dials. */
10795
10887
  hubHostnameOverride: string().optional()
10796
10888
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -10799,13 +10891,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
10799
10891
  * specific runner instance via `attachCamera`. Carries everything the
10800
10892
  * runner needs to subscribe to the local broker and execute inference.
10801
10893
  *
10802
- * Stateless-pipeline model: the full pipeline content (`engine`, `steps`,
10803
- * optional `audio`) travels with the attach payload. The runner keeps it
10804
- * in RAM for the lifetime of the attach — on rebalance, edit, or
10805
- * restart the orchestrator re-sends the latest snapshot.
10806
- *
10807
- * `engine`/`steps`/`audio` are optional during the additive migration
10808
- * window; once orchestrator + UI are migrated they become required.
10894
+ * Stateless-pipeline model: the pipeline content (`steps`, optional
10895
+ * `audio`) travels with the attach payload. The runner keeps it in RAM
10896
+ * for the lifetime of the attach — on rebalance, edit, or restart the
10897
+ * orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
10898
+ * node-local, resolved by the executing runner at dispatch time.
10809
10899
  */
10810
10900
  var RunnerCameraConfigSchema = object({
10811
10901
  deviceId: number(),
@@ -10856,14 +10946,11 @@ var RunnerCameraConfigSchema = object({
10856
10946
  */
10857
10947
  motionSources: MotionSourcesSchema.default(["analyzer"]),
10858
10948
  pipelineEnabled: boolean().default(true),
10859
- /** Engine choice for video steps (runtime+backend+format). */
10860
- engine: PipelineEngineChoiceSchema.optional(),
10861
10949
  /** Ordered tree of video steps. Absent → runner skips video detection. */
10862
10950
  steps: array(PipelineStepInputSchema).readonly().optional(),
10863
10951
  /** Audio classification branch. `enabled:false` disables, null skips. */
10864
10952
  audio: object({
10865
- engine: PipelineEngineChoiceSchema,
10866
- modelId: string(),
10953
+ modelId: string().optional(),
10867
10954
  enabled: boolean()
10868
10955
  }).nullable().optional(),
10869
10956
  /**
@@ -15089,11 +15176,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
15089
15176
  timestamp: number()
15090
15177
  });
15091
15178
  var CameraPipelineConfigSchema = object({
15092
- engine: PipelineEngineChoiceSchema,
15179
+ engine: PipelineEngineChoiceSchema.optional(),
15093
15180
  steps: array(PipelineStepInputSchema).readonly(),
15094
15181
  audio: object({
15095
- engine: PipelineEngineChoiceSchema,
15096
- modelId: string(),
15182
+ engine: PipelineEngineChoiceSchema.optional(),
15183
+ modelId: string().optional(),
15097
15184
  enabled: boolean(),
15098
15185
  settings: record(string(), unknown()).readonly().optional()
15099
15186
  }).nullable().optional()
@@ -15108,7 +15195,7 @@ var PipelineTemplateSchema = object({
15108
15195
  });
15109
15196
  var AgentAddonConfigSchema = object({
15110
15197
  enabled: boolean(),
15111
- modelId: string(),
15198
+ modelId: string().optional(),
15112
15199
  settings: record(string(), unknown()).readonly()
15113
15200
  });
15114
15201
  var AgentPipelineSettingsSchema = object({
@@ -15123,7 +15210,15 @@ var AgentPipelineSettingsSchema = object({
15123
15210
  /** Node is eligible to run audio-analyzer sessions. */
15124
15211
  audio: boolean().optional(),
15125
15212
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
15126
- ingest: boolean().optional()
15213
+ ingest: boolean().optional(),
15214
+ /**
15215
+ * Operator override for the LAN host a cross-node decoder dials to reach
15216
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
15217
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
15218
+ * it already uses to reach the hub). Set this only when the auto-detected
15219
+ * address is wrong (multi-homed host, NAT, custom interface).
15220
+ */
15221
+ reachableHost: string().optional()
15127
15222
  });
15128
15223
  var CameraPipelineForAgentSchema = object({
15129
15224
  steps: array(PipelineStepInputSchema).readonly(),
@@ -15229,6 +15324,15 @@ var GlobalMetricsSchema = object({
15229
15324
  * capability providers.
15230
15325
  */
15231
15326
  var CapabilityBindingsSchema = record(string(), string());
15327
+ /**
15328
+ * The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
15329
+ * its LAN-reachable host, if one is registered. See `getIngestOwner`.
15330
+ */
15331
+ var IngestOwnerSchema = object({
15332
+ ownerNodeId: string(),
15333
+ reachableHost: string().optional(),
15334
+ configIssue: string().optional()
15335
+ });
15232
15336
  /** Source block — always present; derives from the stream catalog. */
15233
15337
  var CameraSourceStatusSchema = object({ streams: array(object({
15234
15338
  camStreamId: string(),
@@ -15243,6 +15347,14 @@ var CameraAssignmentStatusSchema = object({
15243
15347
  detectionNodeId: string().nullable(),
15244
15348
  decoderNodeId: string().nullable(),
15245
15349
  audioNodeId: string().nullable(),
15350
+ /**
15351
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
15352
+ * hosts the broker/restream) — the cluster ingest owner today
15353
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
15354
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
15355
+ * broker block below was read from (pinned). Nullable only pre-wiring.
15356
+ */
15357
+ sourceNodeId: string().nullable(),
15246
15358
  pinned: object({
15247
15359
  detection: boolean(),
15248
15360
  decoder: boolean(),
@@ -15375,7 +15487,7 @@ method(object({
15375
15487
  }), object({ success: literal(true) }), {
15376
15488
  kind: "mutation",
15377
15489
  auth: "admin"
15378
- }), method(object({
15490
+ }), method(_void(), IngestOwnerSchema), method(object({
15379
15491
  deviceId: number(),
15380
15492
  nodeId: string()
15381
15493
  }), _void(), {
@@ -15444,6 +15556,12 @@ method(object({
15444
15556
  }), object({ success: literal(true) }), {
15445
15557
  kind: "mutation",
15446
15558
  auth: "admin"
15559
+ }), method(object({
15560
+ agentNodeId: string(),
15561
+ reachableHost: string().nullable()
15562
+ }), object({ success: literal(true) }), {
15563
+ kind: "mutation",
15564
+ auth: "admin"
15447
15565
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
15448
15566
  deviceId: number(),
15449
15567
  addonId: string(),
@@ -15488,22 +15606,6 @@ method(object({
15488
15606
  kind: "mutation",
15489
15607
  auth: "admin"
15490
15608
  });
15491
- var RegisteredStreamSchema = object({
15492
- streamId: string(),
15493
- label: string().optional(),
15494
- codec: string(),
15495
- type: _enum(["video", "audio"]),
15496
- sourceUrl: string()
15497
- });
15498
- var ExposedResourceSchema = object({
15499
- streamId: string(),
15500
- format: string(),
15501
- value: string()
15502
- });
15503
- method(object({
15504
- deviceId: number(),
15505
- streams: array(RegisteredStreamSchema).readonly()
15506
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
15507
15609
  /**
15508
15610
  * Query filter for settings-store collections.
15509
15611
  */
@@ -15656,9 +15758,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
15656
15758
  /**
15657
15759
  * A single device snapshot returned as base64 JPEG/PNG.
15658
15760
  *
15659
- * Shared with the `snapshot-provider` collection cap the orchestrator
15660
- * receives the same shape from each native provider and from the
15661
- * broker-based fallback.
15761
+ * The `SnapshotAddon` wrapper returns this shape whether the frame came from
15762
+ * the device-native provider (onboard capture) or from the stream-broker
15763
+ * prebuffer fallback.
15662
15764
  */
15663
15765
  var SnapshotImageSchema = object({
15664
15766
  base64: string(),
@@ -15690,10 +15792,6 @@ DeviceType.Camera, method(object({
15690
15792
  kind: "mutation",
15691
15793
  auth: "admin"
15692
15794
  });
15693
- method(object({ deviceId: number() }), boolean()), method(object({
15694
- deviceId: number(),
15695
- streamId: string().optional()
15696
- }), SnapshotImageSchema.nullable());
15697
15795
  /**
15698
15796
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
15699
15797
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -16054,9 +16152,10 @@ method(object({
16054
16152
  auth: "admin"
16055
16153
  });
16056
16154
  /**
16057
- * Optional client-side hints sent at session creation to help the
16058
- * provider pick the best native source. All fields are optional —
16059
- * a viewer that knows nothing still gets a sane default.
16155
+ * Optional client-side hints sent at session creation to help the provider
16156
+ * pick the best native source. All fields optional — a viewer that knows
16157
+ * nothing still gets a sane default. (Relocated from the retired `webrtc`
16158
+ * collection cap; this `webrtc-session` cap is the live signaling surface.)
16060
16159
  */
16061
16160
  var webrtcClientHintsSchema = object({
16062
16161
  viewportWidth: number().int().positive().optional(),
@@ -16067,22 +16166,6 @@ var webrtcClientHintsSchema = object({
16067
16166
  /** Hard tier override; takes precedence over scoring when registered. */
16068
16167
  prefersTier: string().optional()
16069
16168
  }).partial();
16070
- method(object({
16071
- streamId: string(),
16072
- sdpOffer: string()
16073
- }), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
16074
- streamId: string(),
16075
- codec: string()
16076
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
16077
- streamId: string(),
16078
- hints: webrtcClientHintsSchema.optional()
16079
- }), object({
16080
- sessionId: string(),
16081
- sdpOffer: string()
16082
- }), { kind: "mutation" }), method(object({
16083
- sessionId: string(),
16084
- sdpAnswer: string()
16085
- }), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
16086
16169
  /**
16087
16170
  * Discriminated target for a WebRTC session. The client sends this
16088
16171
  * structured object instead of building / parsing brokerId strings;
@@ -21173,6 +21256,12 @@ Object.freeze({
21173
21256
  addonId: null,
21174
21257
  access: "create"
21175
21258
  },
21259
+ "pipelineExecutor.validatePipeline": {
21260
+ capName: "pipeline-executor",
21261
+ capScope: "system",
21262
+ addonId: null,
21263
+ access: "view"
21264
+ },
21176
21265
  "pipelineOrchestrator.assignAudio": {
21177
21266
  capName: "pipeline-orchestrator",
21178
21267
  capScope: "system",
@@ -21281,6 +21370,12 @@ Object.freeze({
21281
21370
  addonId: null,
21282
21371
  access: "view"
21283
21372
  },
21373
+ "pipelineOrchestrator.getIngestOwner": {
21374
+ capName: "pipeline-orchestrator",
21375
+ capScope: "system",
21376
+ addonId: null,
21377
+ access: "view"
21378
+ },
21284
21379
  "pipelineOrchestrator.getPipelineAssignment": {
21285
21380
  capName: "pipeline-orchestrator",
21286
21381
  capScope: "system",
@@ -21353,6 +21448,12 @@ Object.freeze({
21353
21448
  addonId: null,
21354
21449
  access: "create"
21355
21450
  },
21451
+ "pipelineOrchestrator.setAgentReachableHost": {
21452
+ capName: "pipeline-orchestrator",
21453
+ capScope: "system",
21454
+ addonId: null,
21455
+ access: "create"
21456
+ },
21356
21457
  "pipelineOrchestrator.setCameraPipelineForAgent": {
21357
21458
  capName: "pipeline-orchestrator",
21358
21459
  capScope: "system",
@@ -21683,24 +21784,6 @@ Object.freeze({
21683
21784
  addonId: null,
21684
21785
  access: "create"
21685
21786
  },
21686
- "restreamer.getExposedResources": {
21687
- capName: "restreamer",
21688
- capScope: "system",
21689
- addonId: null,
21690
- access: "view"
21691
- },
21692
- "restreamer.registerDevice": {
21693
- capName: "restreamer",
21694
- capScope: "system",
21695
- addonId: null,
21696
- access: "create"
21697
- },
21698
- "restreamer.unregisterDevice": {
21699
- capName: "restreamer",
21700
- capScope: "system",
21701
- addonId: null,
21702
- access: "delete"
21703
- },
21704
21787
  "scriptRunner.run": {
21705
21788
  capName: "script-runner",
21706
21789
  capScope: "device",
@@ -21803,18 +21886,6 @@ Object.freeze({
21803
21886
  addonId: null,
21804
21887
  access: "create"
21805
21888
  },
21806
- "snapshotProvider.getSnapshot": {
21807
- capName: "snapshot-provider",
21808
- capScope: "system",
21809
- addonId: null,
21810
- access: "view"
21811
- },
21812
- "snapshotProvider.supportsDevice": {
21813
- capName: "snapshot-provider",
21814
- capScope: "system",
21815
- addonId: null,
21816
- access: "view"
21817
- },
21818
21889
  "ssoBridge.signBridgeToken": {
21819
21890
  capName: "sso-bridge",
21820
21891
  capScope: "system",
@@ -22241,30 +22312,6 @@ Object.freeze({
22241
22312
  addonId: null,
22242
22313
  access: "view"
22243
22314
  },
22244
- "streamingEngine.getStreamUrl": {
22245
- capName: "streaming-engine",
22246
- capScope: "system",
22247
- addonId: null,
22248
- access: "view"
22249
- },
22250
- "streamingEngine.listStreams": {
22251
- capName: "streaming-engine",
22252
- capScope: "system",
22253
- addonId: null,
22254
- access: "view"
22255
- },
22256
- "streamingEngine.registerStream": {
22257
- capName: "streaming-engine",
22258
- capScope: "system",
22259
- addonId: null,
22260
- access: "create"
22261
- },
22262
- "streamingEngine.unregisterStream": {
22263
- capName: "streaming-engine",
22264
- capScope: "system",
22265
- addonId: null,
22266
- access: "delete"
22267
- },
22268
22315
  "streamParams.getConfigSchema": {
22269
22316
  capName: "stream-params",
22270
22317
  capScope: "device",
@@ -22631,54 +22678,6 @@ Object.freeze({
22631
22678
  addonId: null,
22632
22679
  access: "create"
22633
22680
  },
22634
- "webrtc.closeSession": {
22635
- capName: "webrtc",
22636
- capScope: "system",
22637
- addonId: null,
22638
- access: "create"
22639
- },
22640
- "webrtc.createSession": {
22641
- capName: "webrtc",
22642
- capScope: "system",
22643
- addonId: null,
22644
- access: "create"
22645
- },
22646
- "webrtc.handleAnswer": {
22647
- capName: "webrtc",
22648
- capScope: "system",
22649
- addonId: null,
22650
- access: "create"
22651
- },
22652
- "webrtc.handleOffer": {
22653
- capName: "webrtc",
22654
- capScope: "system",
22655
- addonId: null,
22656
- access: "create"
22657
- },
22658
- "webrtc.hasAdaptiveBitrate": {
22659
- capName: "webrtc",
22660
- capScope: "system",
22661
- addonId: null,
22662
- access: "view"
22663
- },
22664
- "webrtc.registerStream": {
22665
- capName: "webrtc",
22666
- capScope: "system",
22667
- addonId: null,
22668
- access: "create"
22669
- },
22670
- "webrtc.supportsStream": {
22671
- capName: "webrtc",
22672
- capScope: "system",
22673
- addonId: null,
22674
- access: "view"
22675
- },
22676
- "webrtc.unregisterStream": {
22677
- capName: "webrtc",
22678
- capScope: "system",
22679
- addonId: null,
22680
- access: "delete"
22681
- },
22682
22681
  "webrtcSession.addIceCandidate": {
22683
22682
  capName: "webrtc-session",
22684
22683
  capScope: "device",
@@ -22847,7 +22846,7 @@ var AdminUIAddon = class extends BaseAddon {
22847
22846
  capability: adminUiCapability,
22848
22847
  provider: {
22849
22848
  getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
22850
- getVersion: async () => ({ version: "1.1.34" })
22849
+ getVersion: async () => ({ version: "1.1.35" })
22851
22850
  }
22852
22851
  }];
22853
22852
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-admin-ui",
3
- "version": "1.1.34",
3
+ "version": "1.1.35",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "CamStack Admin UI — Vite frontend build and server-side addon",