@camstack/addon-pipeline 1.1.43 → 1.1.44

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 (36) hide show
  1. package/dist/audio-analyzer/index.js +5 -4
  2. package/dist/audio-analyzer/index.mjs +1 -1
  3. package/dist/chunk-D6vf50IK.js +28 -0
  4. package/dist/detection-pipeline/index.js +526 -109
  5. package/dist/detection-pipeline/index.mjs +520 -104
  6. package/dist/{dist-GFd8M6KO.mjs → dist-CgBGV988.mjs} +214 -186
  7. package/dist/{dist-NvwN60Fq.js → dist-CySHUkXY.js} +219 -185
  8. package/dist/{model-download-service-C-IHWnXx-DxM2DSns.js → model-download-service-C-IHWnXx-BLXzxpRB.js} +3 -29
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/pipeline-runner/index.js +122 -287
  12. package/dist/pipeline-runner/index.mjs +118 -285
  13. package/dist/recorder/index.js +60 -20
  14. package/dist/recorder/index.mjs +57 -18
  15. package/dist/{frame-handle-plane-E_AsR77T.mjs → remote-source-plane-B4hRwchu.mjs} +219 -2
  16. package/dist/{frame-handle-plane-B3Fxww8H.js → remote-source-plane-D9m0z1N9.js} +236 -1
  17. package/dist/session-decode/decode-worker-child.js +86 -2
  18. package/dist/session-decode/decode-worker-child.mjs +83 -2
  19. package/dist/stream-broker/_stub.js +550 -523
  20. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CeielP5P.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-G6wtUb3G.mjs} +2 -2
  21. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Dlagq9X_.mjs +26 -0
  22. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BUpF966l.mjs +26 -0
  23. package/dist/stream-broker/{hostInit-DmjqskOR.mjs → hostInit-BSzP3BIj.mjs} +2 -2
  24. package/dist/stream-broker/index.js +746 -135
  25. package/dist/stream-broker/index.mjs +737 -127
  26. package/dist/stream-broker/remoteEntry.js +1 -1
  27. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-CEsPjwzT.js → MaskShapeCanvas-DI4BY7W2-D2ML5TPi.js} +1 -1
  28. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-D43fIRgB.js → MotionZonesSettings-NcxxQN8r-TTWGGaqv.js} +1 -1
  29. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-C3wJxG8V.js → PrivacyMaskSettings-APgPLF7p-CJqHU2nU.js} +1 -1
  30. package/embed-dist/assets/index-C1oaL9s7.js +81 -0
  31. package/embed-dist/assets/{index-CSFtK41z.css → index-CA4kv43T.css} +1 -1
  32. package/embed-dist/index.html +2 -2
  33. package/package.json +2 -2
  34. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DqJvWBKS.mjs +0 -26
  35. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-dGka8yZY.mjs +0 -26
  36. package/embed-dist/assets/index-CX-rILhw.js +0 -81
@@ -4627,7 +4627,7 @@ function _instanceof(cls, params = {}) {
4627
4627
  return inst;
4628
4628
  }
4629
4629
  //#endregion
4630
- //#region ../types/dist/sleep-CZDdRBua.mjs
4630
+ //#region ../types/dist/sleep-Cc14_yxc.mjs
4631
4631
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4632
4632
  EventCategory["SystemBoot"] = "system.boot";
4633
4633
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -4813,6 +4813,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
4813
4813
  */
4814
4814
  EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
4815
4815
  /**
4816
+ * The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
4817
+ * Emitted by addon-pipeline-orchestrator whenever it (re)derives node
4818
+ * capabilities — at boot, on agent online/offline, and on an ingest-node
4819
+ * flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
4820
+ * keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
4821
+ * cross-process `getIngestOwner` query (push the authority's decision instead
4822
+ * of polling it on the hot path). Idempotent state — re-emitted on every
4823
+ * topology change, so a dropped event self-heals on the next one (plus the
4824
+ * broker's long backstop reconcile query).
4825
+ */
4826
+ EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
4827
+ /**
4816
4828
  * Periodic snapshot of per-node pipeline-runner load
4817
4829
  * (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
4818
4830
  * subscribe instead of polling `pipelineRunner.getLocalLoad`.
@@ -5367,6 +5379,22 @@ function typeOf(field) {
5367
5379
  }
5368
5380
  }
5369
5381
  /**
5382
+ * Narrow a SystemEvent to a typed event by checking its category.
5383
+ * Returns `true` (and narrows the type) if the category matches.
5384
+ *
5385
+ * @example
5386
+ * ```typescript
5387
+ * eventBus.subscribe({ category: 'addon.started' }, (event) => {
5388
+ * if (isEvent(event, 'addon.started')) {
5389
+ * event.data.addonId // ✓ typed as string
5390
+ * }
5391
+ * })
5392
+ * ```
5393
+ */
5394
+ function isEvent(event, category) {
5395
+ return event.category === category;
5396
+ }
5397
+ /**
5370
5398
  * Create a typed event with less boilerplate.
5371
5399
  *
5372
5400
  * @example
@@ -7016,6 +7044,28 @@ var ModelFormatsSchema = object({
7016
7044
  tflite: ModelFormatEntrySchema.optional(),
7017
7045
  pt: ModelFormatEntrySchema.optional()
7018
7046
  });
7047
+ /**
7048
+ * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
7049
+ * the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
7050
+ * grouped Family→Tier→Variant picker renders identically in the config UI and
7051
+ * in the pipeline/device steppers. The flat `id` stays the source of truth for
7052
+ * resolution/download/persistence; this is a presentation overlay resolved back
7053
+ * to an `id`.
7054
+ */
7055
+ var ModelVariantGroupSchema = object({
7056
+ /** Top-level family, e.g. `yolo26` (later `d-fine`, `rf-detr`). */
7057
+ family: string(),
7058
+ /** Size within the family, e.g. `n` | `s` | `m` | `l`. */
7059
+ tier: string(),
7060
+ /** Quantization axis. Omit ⇒ the fp32 base build. */
7061
+ precision: _enum(["fp32", "int8"]).optional(),
7062
+ /**
7063
+ * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
7064
+ * latency-optimized export (e.g. ReLU-activation / reduced-input variant)
7065
+ * — the slot the future performance variants plug into.
7066
+ */
7067
+ optimization: _enum(["standard", "fast"]).optional()
7068
+ });
7019
7069
  var ModelCatalogEntrySchema = object({
7020
7070
  id: string(),
7021
7071
  name: string(),
@@ -7045,7 +7095,43 @@ var ModelCatalogEntrySchema = object({
7045
7095
  * Auxiliary files required at runtime (labels JSON, charset dict, etc.).
7046
7096
  * Downloaded into the same modelsDir alongside the model file.
7047
7097
  */
7048
- extraFiles: array(ModelExtraFileSchema).readonly().optional()
7098
+ extraFiles: array(ModelExtraFileSchema).readonly().optional(),
7099
+ /**
7100
+ * LEGACY entry — retained in the catalog so a persisted operator selection
7101
+ * still RESOLVES (and can be re-activated), but hidden from the selectable
7102
+ * model list and excluded from the auto format-default pick. Set on the
7103
+ * superseded / consolidated models (older lineages, redundant fp16 IRs) so
7104
+ * the active lineup stays the coherent curated ladder without deleting a
7105
+ * model anyone may still be pinned to. `resolveModelForFormat` keeps honoring
7106
+ * an explicit legacy id that has a build for the node's format.
7107
+ */
7108
+ legacy: boolean().optional(),
7109
+ /**
7110
+ * Measured quality/latency metadata — populated from the benchmark addon on
7111
+ * the real node classes. Absent = not yet measured (most entries today; the
7112
+ * catalog historically carried only `sizeMB`, a poor cross-architecture
7113
+ * speed proxy). `p95LatencyMs` is keyed by node class (e.g. `n100`, `mac`).
7114
+ */
7115
+ metrics: object({
7116
+ map50: number().optional(),
7117
+ p95LatencyMs: record(string(), number()).optional()
7118
+ }).optional(),
7119
+ /**
7120
+ * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
7121
+ * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
7122
+ * the retraining addon and any future commercial distribution.
7123
+ */
7124
+ license: string().optional(),
7125
+ /**
7126
+ * Variant-selector grouping. The UI groups models by `family` + `tier` and
7127
+ * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
7128
+ * of a family's sizes and quantizations collapse into one grouped picker
7129
+ * instead of a flat list of `yolo26s`, `yolo26s-int8`, … Absent ⇒ ungrouped
7130
+ * (legacy / custom models) — never shown in the grouped selector. The flat
7131
+ * `id` stays the source of truth for resolution/download/persistence; grouping
7132
+ * is a presentation overlay resolved back to an `id`.
7133
+ */
7134
+ group: ModelVariantGroupSchema.optional()
7049
7135
  });
7050
7136
  var ConvertTargetSchema = discriminatedUnion("format", [object({
7051
7137
  format: literal("openvino"),
@@ -7125,8 +7211,8 @@ var RecordingModeSchema = _enum([
7125
7211
  "onAudioThreshold"
7126
7212
  ]);
7127
7213
  /**
7128
- * First-class, authoritative per-camera storage mode — the netta choice the UI
7129
- * reads directly (never inferred from `rules`):
7214
+ * First-class, authoritative per-camera storage mode — the explicit choice the
7215
+ * UI reads directly (never inferred from `rules`):
7130
7216
  * - `off` — not recording.
7131
7217
  * - `events` — record only around triggers (motion / audio threshold),
7132
7218
  * with pre/post-buffer.
@@ -9338,26 +9424,13 @@ DeviceType.Light, method(object({
9338
9424
  percentage: number().min(0).max(100),
9339
9425
  lastChangedAt: number()
9340
9426
  });
9427
+ /** Stream delivery format. (Relocated from the retired `streaming-engine` cap.) */
9341
9428
  var StreamFormatSchema = _enum([
9342
9429
  "webrtc",
9343
9430
  "hls",
9344
9431
  "mjpeg",
9345
9432
  "rtsp"
9346
9433
  ]);
9347
- var StreamInfoSchema = object({
9348
- streamId: string(),
9349
- format: StreamFormatSchema,
9350
- url: string().nullable(),
9351
- active: boolean()
9352
- });
9353
- method(object({
9354
- streamId: string(),
9355
- sourceUrl: string(),
9356
- codec: string().optional()
9357
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
9358
- streamId: string(),
9359
- format: StreamFormatSchema
9360
- }), string().nullable()), method(_void(), array(StreamInfoSchema));
9361
9434
  var RtspRestreamEntrySchema = object({
9362
9435
  brokerId: string(),
9363
9436
  url: string(),
@@ -10225,7 +10298,7 @@ var ConsumablesStatusSchema = object({
10225
10298
  })),
10226
10299
  lastChangedAt: number()
10227
10300
  });
10228
- 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({
10301
+ Object.values(DeviceType), method(object({
10229
10302
  deviceId: number().int().nonnegative(),
10230
10303
  key: string().min(1)
10231
10304
  }), _void(), {
@@ -11288,7 +11361,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
11288
11361
  enabled: boolean(),
11289
11362
  modelId: string(),
11290
11363
  children: array(PipelineDefaultStepSchema).readonly(),
11291
- engine: PipelineEngineChoiceSchema.optional(),
11292
11364
  group: string().optional(),
11293
11365
  settings: record(string(), unknown()).optional()
11294
11366
  }));
@@ -11313,7 +11385,9 @@ var PipelineModelOptionSchema = object({
11313
11385
  formats: record(string(), object({
11314
11386
  downloaded: boolean(),
11315
11387
  sizeMB: number()
11316
- }))
11388
+ })),
11389
+ group: ModelVariantGroupSchema.optional(),
11390
+ legacy: boolean().optional()
11317
11391
  });
11318
11392
  var ConfigFieldBridge = custom();
11319
11393
  var PipelineAddonSchemaSchema = object({
@@ -11364,15 +11438,42 @@ var EngineProvisioningSchema = object({
11364
11438
  ]),
11365
11439
  progress: number().optional(),
11366
11440
  error: string().optional(),
11367
- nextRetryAt: number().optional()
11441
+ nextRetryAt: number().optional(),
11442
+ /**
11443
+ * Gate A (config-correctness gate at engine change): human-readable
11444
+ * config issues surfaced EAGERLY when the node's engine changes — model
11445
+ * substitutions ("chose X, running Y") and zero-build steps ("no model
11446
+ * has a <format> build"). Additive/optional: informational only, never
11447
+ * enforced here — `assertEngineReady` (readiness) still gates inference.
11448
+ * Absent/empty when the node-default tree resolves cleanly.
11449
+ */
11450
+ configIssues: array(string()).optional()
11368
11451
  });
11369
11452
  var PipelineStepInputSchema = lazy(() => object({
11370
11453
  addonId: string(),
11371
- modelId: string(),
11454
+ modelId: string().optional(),
11372
11455
  enabled: boolean().default(true),
11373
11456
  children: array(PipelineStepInputSchema).optional(),
11374
11457
  settings: record(string(), unknown()).optional()
11375
11458
  }));
11459
+ var ModelSubstitutionSchema = object({
11460
+ addonId: string(),
11461
+ chosen: string(),
11462
+ running: string(),
11463
+ format: string()
11464
+ });
11465
+ var PipelineValidationIssueSchema = object({
11466
+ addonId: string(),
11467
+ kind: _enum(["unknown-addon", "no-format-build"]),
11468
+ detail: string()
11469
+ });
11470
+ var PipelineValidationResultSchema = object({
11471
+ ok: boolean(),
11472
+ issues: array(PipelineValidationIssueSchema).readonly(),
11473
+ substitutions: array(ModelSubstitutionSchema).readonly(),
11474
+ /** The node's `currentEngine.format` this validation ran against. */
11475
+ format: string()
11476
+ });
11376
11477
  var ReferenceImageEntrySchema = object({
11377
11478
  filename: string(),
11378
11479
  stepIds: array(string()).readonly().optional()
@@ -11489,6 +11590,19 @@ var pipelineExecutorCapability = {
11489
11590
  getGlobalSteps: method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()),
11490
11591
  getGlobalPipelineConfig: method(_void(), PipelineConfigBridge),
11491
11592
  getOrchestratorConfigSchema: method(_void(), ConfigUISchemaBridge),
11593
+ /**
11594
+ * Gate B (pre-init config-correctness gate). PURE COMPUTE against this
11595
+ * node's `currentEngine.format` — resolves `steps` the same way the
11596
+ * runtime dispatch path would, and reports what WOULD happen without
11597
+ * touching any node-global state. Called by the orchestrator at attach
11598
+ * time (`attachOn`), node-pinned to the TARGET node, so config problems
11599
+ * surface BEFORE `pipelineRunner.attachCamera` rather than at the first
11600
+ * per-frame resolve. `ok` is false iff `issues` is non-empty (both
11601
+ * `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
11602
+ * is informational (a degraded-but-loadable model swap) and never
11603
+ * affects `ok`. Never throws.
11604
+ */
11605
+ validatePipeline: method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
11492
11606
  listTemplates: method(_void(), array(PipelineTemplateSchema$1).readonly()),
11493
11607
  saveTemplate: method(object({
11494
11608
  name: string(),
@@ -11838,6 +11952,13 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
11838
11952
  kind: literal("remote-restream"),
11839
11953
  /** The camera's source-owner node (slice 1: always the hub). */
11840
11954
  ownerNodeId: string(),
11955
+ /**
11956
+ * The owner's LAN-reachable host, resolved by the orchestrator from the
11957
+ * per-node `reachableHost` override (Cluster UI). When present the runner
11958
+ * dials THIS host for the owner's restream, in preference to the
11959
+ * `CAMSTACK_HUB_URL`-derived default. Absent → auto-detect fallback.
11960
+ */
11961
+ ownerReachableHost: string().optional(),
11841
11962
  /** Operator override for the owner host the runner dials. */
11842
11963
  hubHostnameOverride: string().optional()
11843
11964
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
@@ -11846,13 +11967,11 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
11846
11967
  * specific runner instance via `attachCamera`. Carries everything the
11847
11968
  * runner needs to subscribe to the local broker and execute inference.
11848
11969
  *
11849
- * Stateless-pipeline model: the full pipeline content (`engine`, `steps`,
11850
- * optional `audio`) travels with the attach payload. The runner keeps it
11851
- * in RAM for the lifetime of the attach — on rebalance, edit, or
11852
- * restart the orchestrator re-sends the latest snapshot.
11853
- *
11854
- * `engine`/`steps`/`audio` are optional during the additive migration
11855
- * window; once orchestrator + UI are migrated they become required.
11970
+ * Stateless-pipeline model: the pipeline content (`steps`, optional
11971
+ * `audio`) travels with the attach payload. The runner keeps it in RAM
11972
+ * for the lifetime of the attach — on rebalance, edit, or restart the
11973
+ * orchestrator re-sends the latest snapshot. Engine is NOT carried: it is
11974
+ * node-local, resolved by the executing runner at dispatch time.
11856
11975
  */
11857
11976
  var RunnerCameraConfigSchema = object({
11858
11977
  deviceId: number(),
@@ -11903,14 +12022,11 @@ var RunnerCameraConfigSchema = object({
11903
12022
  */
11904
12023
  motionSources: MotionSourcesSchema.default(["analyzer"]),
11905
12024
  pipelineEnabled: boolean().default(true),
11906
- /** Engine choice for video steps (runtime+backend+format). */
11907
- engine: PipelineEngineChoiceSchema.optional(),
11908
12025
  /** Ordered tree of video steps. Absent → runner skips video detection. */
11909
12026
  steps: array(PipelineStepInputSchema).readonly().optional(),
11910
12027
  /** Audio classification branch. `enabled:false` disables, null skips. */
11911
12028
  audio: object({
11912
- engine: PipelineEngineChoiceSchema,
11913
- modelId: string(),
12029
+ modelId: string().optional(),
11914
12030
  enabled: boolean()
11915
12031
  }).nullable().optional(),
11916
12032
  /**
@@ -16396,11 +16512,11 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
16396
16512
  timestamp: number()
16397
16513
  });
16398
16514
  var CameraPipelineConfigSchema = object({
16399
- engine: PipelineEngineChoiceSchema,
16515
+ engine: PipelineEngineChoiceSchema.optional(),
16400
16516
  steps: array(PipelineStepInputSchema).readonly(),
16401
16517
  audio: object({
16402
- engine: PipelineEngineChoiceSchema,
16403
- modelId: string(),
16518
+ engine: PipelineEngineChoiceSchema.optional(),
16519
+ modelId: string().optional(),
16404
16520
  enabled: boolean(),
16405
16521
  settings: record(string(), unknown()).readonly().optional()
16406
16522
  }).nullable().optional()
@@ -16415,7 +16531,7 @@ var PipelineTemplateSchema = object({
16415
16531
  });
16416
16532
  var AgentAddonConfigSchema = object({
16417
16533
  enabled: boolean(),
16418
- modelId: string(),
16534
+ modelId: string().optional(),
16419
16535
  settings: record(string(), unknown()).readonly()
16420
16536
  });
16421
16537
  var AgentPipelineSettingsSchema = object({
@@ -16430,7 +16546,15 @@ var AgentPipelineSettingsSchema = object({
16430
16546
  /** Node is eligible to run audio-analyzer sessions. */
16431
16547
  audio: boolean().optional(),
16432
16548
  /** Node is eligible to be the ingest / source-owner (serve the restream). */
16433
- ingest: boolean().optional()
16549
+ ingest: boolean().optional(),
16550
+ /**
16551
+ * Operator override for the LAN host a cross-node decoder dials to reach
16552
+ * THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
16553
+ * falls back to its `CAMSTACK_HUB_URL`-derived host (the Moleculer address
16554
+ * it already uses to reach the hub). Set this only when the auto-detected
16555
+ * address is wrong (multi-homed host, NAT, custom interface).
16556
+ */
16557
+ reachableHost: string().optional()
16434
16558
  });
16435
16559
  var CameraPipelineForAgentSchema = object({
16436
16560
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16536,6 +16660,15 @@ var GlobalMetricsSchema = object({
16536
16660
  * capability providers.
16537
16661
  */
16538
16662
  var CapabilityBindingsSchema = record(string(), string());
16663
+ /**
16664
+ * The cluster's single camera-source owner (`clusterRoles.ingestNode`) plus
16665
+ * its LAN-reachable host, if one is registered. See `getIngestOwner`.
16666
+ */
16667
+ var IngestOwnerSchema = object({
16668
+ ownerNodeId: string(),
16669
+ reachableHost: string().optional(),
16670
+ configIssue: string().optional()
16671
+ });
16539
16672
  /** Source block — always present; derives from the stream catalog. */
16540
16673
  var CameraSourceStatusSchema = object({ streams: array(object({
16541
16674
  camStreamId: string(),
@@ -16550,6 +16683,14 @@ var CameraAssignmentStatusSchema = object({
16550
16683
  detectionNodeId: string().nullable(),
16551
16684
  decoderNodeId: string().nullable(),
16552
16685
  audioNodeId: string().nullable(),
16686
+ /**
16687
+ * The node that OWNS this camera's physical source pull (dials the RTSP and
16688
+ * hosts the broker/restream) — the cluster ingest owner today
16689
+ * (`clusterRoles.ingestNode`), per-camera once source assignment lands. Lets
16690
+ * the UI show WHERE a camera is sourced without SSH/logs, and is the node the
16691
+ * broker block below was read from (pinned). Nullable only pre-wiring.
16692
+ */
16693
+ sourceNodeId: string().nullable(),
16553
16694
  pinned: object({
16554
16695
  detection: boolean(),
16555
16696
  decoder: boolean(),
@@ -16682,7 +16823,7 @@ method(object({
16682
16823
  }), object({ success: literal(true) }), {
16683
16824
  kind: "mutation",
16684
16825
  auth: "admin"
16685
- }), method(object({
16826
+ }), method(_void(), IngestOwnerSchema), method(object({
16686
16827
  deviceId: number(),
16687
16828
  nodeId: string()
16688
16829
  }), _void(), {
@@ -16751,6 +16892,12 @@ method(object({
16751
16892
  }), object({ success: literal(true) }), {
16752
16893
  kind: "mutation",
16753
16894
  auth: "admin"
16895
+ }), method(object({
16896
+ agentNodeId: string(),
16897
+ reachableHost: string().nullable()
16898
+ }), object({ success: literal(true) }), {
16899
+ kind: "mutation",
16900
+ auth: "admin"
16754
16901
  }), method(object({ deviceId: number() }), CameraPipelineSettingsSchema.nullable()), method(object({
16755
16902
  deviceId: number(),
16756
16903
  addonId: string(),
@@ -16795,22 +16942,6 @@ method(object({
16795
16942
  kind: "mutation",
16796
16943
  auth: "admin"
16797
16944
  });
16798
- var RegisteredStreamSchema = object({
16799
- streamId: string(),
16800
- label: string().optional(),
16801
- codec: string(),
16802
- type: _enum(["video", "audio"]),
16803
- sourceUrl: string()
16804
- });
16805
- var ExposedResourceSchema = object({
16806
- streamId: string(),
16807
- format: string(),
16808
- value: string()
16809
- });
16810
- method(object({
16811
- deviceId: number(),
16812
- streams: array(RegisteredStreamSchema).readonly()
16813
- }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), _void(), { kind: "mutation" }), method(object({ deviceId: number() }), array(ExposedResourceSchema).readonly());
16814
16945
  /**
16815
16946
  * Query filter for settings-store collections.
16816
16947
  */
@@ -16963,9 +17094,9 @@ method(SendEmailInputSchema, SendEmailResultSchema, {
16963
17094
  /**
16964
17095
  * A single device snapshot returned as base64 JPEG/PNG.
16965
17096
  *
16966
- * Shared with the `snapshot-provider` collection cap the orchestrator
16967
- * receives the same shape from each native provider and from the
16968
- * broker-based fallback.
17097
+ * The `SnapshotAddon` wrapper returns this shape whether the frame came from
17098
+ * the device-native provider (onboard capture) or from the stream-broker
17099
+ * prebuffer fallback.
16969
17100
  */
16970
17101
  var SnapshotImageSchema = object({
16971
17102
  base64: string(),
@@ -16997,10 +17128,6 @@ DeviceType.Camera, method(object({
16997
17128
  kind: "mutation",
16998
17129
  auth: "admin"
16999
17130
  });
17000
- method(object({ deviceId: number() }), boolean()), method(object({
17001
- deviceId: number(),
17002
- streamId: string().optional()
17003
- }), SnapshotImageSchema.nullable());
17004
17131
  /**
17005
17132
  * `sso-bridge` — internal hub-only cap that lets SSO-style auth
17006
17133
  * providers (OIDC, SAML, magic-link, …) mint an HMAC-signed token
@@ -17376,9 +17503,10 @@ method(object({
17376
17503
  auth: "admin"
17377
17504
  });
17378
17505
  /**
17379
- * Optional client-side hints sent at session creation to help the
17380
- * provider pick the best native source. All fields are optional —
17381
- * a viewer that knows nothing still gets a sane default.
17506
+ * Optional client-side hints sent at session creation to help the provider
17507
+ * pick the best native source. All fields optional — a viewer that knows
17508
+ * nothing still gets a sane default. (Relocated from the retired `webrtc`
17509
+ * collection cap; this `webrtc-session` cap is the live signaling surface.)
17382
17510
  */
17383
17511
  var webrtcClientHintsSchema = object({
17384
17512
  viewportWidth: number().int().positive().optional(),
@@ -17389,22 +17517,6 @@ var webrtcClientHintsSchema = object({
17389
17517
  /** Hard tier override; takes precedence over scoring when registered. */
17390
17518
  prefersTier: string().optional()
17391
17519
  }).partial();
17392
- method(object({
17393
- streamId: string(),
17394
- sdpOffer: string()
17395
- }), string(), { kind: "mutation" }), method(object({ streamId: string() }), boolean()), method(object({
17396
- streamId: string(),
17397
- codec: string()
17398
- }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), _void(), { kind: "mutation" }), method(object({
17399
- streamId: string(),
17400
- hints: webrtcClientHintsSchema.optional()
17401
- }), object({
17402
- sessionId: string(),
17403
- sdpOffer: string()
17404
- }), { kind: "mutation" }), method(object({
17405
- sessionId: string(),
17406
- sdpAnswer: string()
17407
- }), _void(), { kind: "mutation" }), method(object({ sessionId: string() }), _void(), { kind: "mutation" }), method(object({ streamId: string() }), boolean());
17408
17520
  /**
17409
17521
  * Discriminated target for a WebRTC session. The client sends this
17410
17522
  * structured object instead of building / parsing brokerId strings;
@@ -17677,7 +17789,7 @@ var webrtcSessionCapability = {
17677
17789
  }).nullable() }))
17678
17790
  },
17679
17791
  /** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
17680
- mount: { kind: "custom" }
17792
+ mount: { kind: "server-provided" }
17681
17793
  };
17682
17794
  object({
17683
17795
  /** All accessory children of the parent. */
@@ -22608,6 +22720,12 @@ Object.freeze({
22608
22720
  addonId: null,
22609
22721
  access: "create"
22610
22722
  },
22723
+ "pipelineExecutor.validatePipeline": {
22724
+ capName: "pipeline-executor",
22725
+ capScope: "system",
22726
+ addonId: null,
22727
+ access: "view"
22728
+ },
22611
22729
  "pipelineOrchestrator.assignAudio": {
22612
22730
  capName: "pipeline-orchestrator",
22613
22731
  capScope: "system",
@@ -22716,6 +22834,12 @@ Object.freeze({
22716
22834
  addonId: null,
22717
22835
  access: "view"
22718
22836
  },
22837
+ "pipelineOrchestrator.getIngestOwner": {
22838
+ capName: "pipeline-orchestrator",
22839
+ capScope: "system",
22840
+ addonId: null,
22841
+ access: "view"
22842
+ },
22719
22843
  "pipelineOrchestrator.getPipelineAssignment": {
22720
22844
  capName: "pipeline-orchestrator",
22721
22845
  capScope: "system",
@@ -22788,6 +22912,12 @@ Object.freeze({
22788
22912
  addonId: null,
22789
22913
  access: "create"
22790
22914
  },
22915
+ "pipelineOrchestrator.setAgentReachableHost": {
22916
+ capName: "pipeline-orchestrator",
22917
+ capScope: "system",
22918
+ addonId: null,
22919
+ access: "create"
22920
+ },
22791
22921
  "pipelineOrchestrator.setCameraPipelineForAgent": {
22792
22922
  capName: "pipeline-orchestrator",
22793
22923
  capScope: "system",
@@ -23118,24 +23248,6 @@ Object.freeze({
23118
23248
  addonId: null,
23119
23249
  access: "create"
23120
23250
  },
23121
- "restreamer.getExposedResources": {
23122
- capName: "restreamer",
23123
- capScope: "system",
23124
- addonId: null,
23125
- access: "view"
23126
- },
23127
- "restreamer.registerDevice": {
23128
- capName: "restreamer",
23129
- capScope: "system",
23130
- addonId: null,
23131
- access: "create"
23132
- },
23133
- "restreamer.unregisterDevice": {
23134
- capName: "restreamer",
23135
- capScope: "system",
23136
- addonId: null,
23137
- access: "delete"
23138
- },
23139
23251
  "scriptRunner.run": {
23140
23252
  capName: "script-runner",
23141
23253
  capScope: "device",
@@ -23238,18 +23350,6 @@ Object.freeze({
23238
23350
  addonId: null,
23239
23351
  access: "create"
23240
23352
  },
23241
- "snapshotProvider.getSnapshot": {
23242
- capName: "snapshot-provider",
23243
- capScope: "system",
23244
- addonId: null,
23245
- access: "view"
23246
- },
23247
- "snapshotProvider.supportsDevice": {
23248
- capName: "snapshot-provider",
23249
- capScope: "system",
23250
- addonId: null,
23251
- access: "view"
23252
- },
23253
23353
  "ssoBridge.signBridgeToken": {
23254
23354
  capName: "sso-bridge",
23255
23355
  capScope: "system",
@@ -23676,30 +23776,6 @@ Object.freeze({
23676
23776
  addonId: null,
23677
23777
  access: "view"
23678
23778
  },
23679
- "streamingEngine.getStreamUrl": {
23680
- capName: "streaming-engine",
23681
- capScope: "system",
23682
- addonId: null,
23683
- access: "view"
23684
- },
23685
- "streamingEngine.listStreams": {
23686
- capName: "streaming-engine",
23687
- capScope: "system",
23688
- addonId: null,
23689
- access: "view"
23690
- },
23691
- "streamingEngine.registerStream": {
23692
- capName: "streaming-engine",
23693
- capScope: "system",
23694
- addonId: null,
23695
- access: "create"
23696
- },
23697
- "streamingEngine.unregisterStream": {
23698
- capName: "streaming-engine",
23699
- capScope: "system",
23700
- addonId: null,
23701
- access: "delete"
23702
- },
23703
23779
  "streamParams.getConfigSchema": {
23704
23780
  capName: "stream-params",
23705
23781
  capScope: "device",
@@ -24066,54 +24142,6 @@ Object.freeze({
24066
24142
  addonId: null,
24067
24143
  access: "create"
24068
24144
  },
24069
- "webrtc.closeSession": {
24070
- capName: "webrtc",
24071
- capScope: "system",
24072
- addonId: null,
24073
- access: "create"
24074
- },
24075
- "webrtc.createSession": {
24076
- capName: "webrtc",
24077
- capScope: "system",
24078
- addonId: null,
24079
- access: "create"
24080
- },
24081
- "webrtc.handleAnswer": {
24082
- capName: "webrtc",
24083
- capScope: "system",
24084
- addonId: null,
24085
- access: "create"
24086
- },
24087
- "webrtc.handleOffer": {
24088
- capName: "webrtc",
24089
- capScope: "system",
24090
- addonId: null,
24091
- access: "create"
24092
- },
24093
- "webrtc.hasAdaptiveBitrate": {
24094
- capName: "webrtc",
24095
- capScope: "system",
24096
- addonId: null,
24097
- access: "view"
24098
- },
24099
- "webrtc.registerStream": {
24100
- capName: "webrtc",
24101
- capScope: "system",
24102
- addonId: null,
24103
- access: "create"
24104
- },
24105
- "webrtc.supportsStream": {
24106
- capName: "webrtc",
24107
- capScope: "system",
24108
- addonId: null,
24109
- access: "view"
24110
- },
24111
- "webrtc.unregisterStream": {
24112
- capName: "webrtc",
24113
- capScope: "system",
24114
- addonId: null,
24115
- access: "delete"
24116
- },
24117
24145
  "webrtcSession.addIceCandidate": {
24118
24146
  capName: "webrtc-session",
24119
24147
  capScope: "device",
@@ -24456,4 +24484,4 @@ function defaultDeviceFor(id) {
24456
24484
  return def(id).defaultDevice;
24457
24485
  }
24458
24486
  //#endregion
24459
- export { discriminatedUnion as $, recordingCapability as A, DeviceType as B, mapAudioLabelToMacro as C, nodePin as D, motionDetectionCapability as E, webrtcSessionCapability as F, makeSourceBrokerId as G, createEvent as H, errMsg as I, selectAssignedProfileSlots as J, parseJsonUnknown as K, BaseAddon as L, storageEvictableCapability as M, streamBrokerCapability as N, pipelineExecutorCapability as O, supportedRuntimes as P, boolean as Q, CAM_PROFILE_ORDER as R, hfModelUrl as S, migrateConfigToBands as T, hydrateSchema as U, EventCategory as V, makeProfileBrokerId as W, _enum as X, sleep as Y, array as Z, customAction as _, COCO_TO_MACRO as a, string as at, detectionPipelineCapability as b, EncodeProfileSchema as c, RingBuffer as d, lazy as et, YAMNET_TO_MACRO as f, cameraStreamsCapability as g, audioAnalyzerCapability as h, COCO_80_LABELS as i, record as it, runtimeDevices as j, pipelineRunnerCapability as k, HF_BASE_URL as l, audioAnalysisCapability as m, AUDIO_BACKEND_CHOICES as n, number as nt, DEFAULT_AUDIO_ANALYZER_CONFIG as o, union as ot, addonWidgetsSourceCapability as p, parseProfileBrokerId as q, AUDIO_MACRO_LABELS as r, object as rt, EVENT_PAD_MS as s, APPLE_SA_TO_MACRO as t, literal as tt, RecordingConfigSchema as u, defaultDeviceFor as v, maskUrlCredentials as w, evaluateZoneRules as x, defineCustomActions as y, DeviceFeature as z };
24487
+ export { boolean as $, recordingCapability as A, DeviceType as B, mapAudioLabelToMacro as C, nodePin as D, motionDetectionCapability as E, webrtcSessionCapability as F, makeProfileBrokerId as G, createEvent as H, errMsg as I, parseProfileBrokerId as J, makeSourceBrokerId as K, BaseAddon as L, storageEvictableCapability as M, streamBrokerCapability as N, pipelineExecutorCapability as O, supportedRuntimes as P, array as Q, CAM_PROFILE_ORDER as R, hfModelUrl as S, migrateConfigToBands as T, hydrateSchema as U, EventCategory as V, isEvent as W, sleep as X, selectAssignedProfileSlots as Y, _enum as Z, customAction as _, COCO_TO_MACRO as a, record as at, detectionPipelineCapability as b, EncodeProfileSchema as c, RingBuffer as d, discriminatedUnion as et, YAMNET_TO_MACRO as f, cameraStreamsCapability as g, audioAnalyzerCapability as h, COCO_80_LABELS as i, object as it, runtimeDevices as j, pipelineRunnerCapability as k, HF_BASE_URL as l, audioAnalysisCapability as m, AUDIO_BACKEND_CHOICES as n, literal as nt, DEFAULT_AUDIO_ANALYZER_CONFIG as o, string as ot, addonWidgetsSourceCapability as p, parseJsonUnknown as q, AUDIO_MACRO_LABELS as r, number as rt, EVENT_PAD_MS as s, union as st, APPLE_SA_TO_MACRO as t, lazy as tt, RecordingConfigSchema as u, defaultDeviceFor as v, maskUrlCredentials as w, evaluateZoneRules as x, defineCustomActions as y, DeviceFeature as z };