@camstack/addon-export-ha-mqtt 1.1.27 → 1.2.1

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.
@@ -7119,6 +7119,17 @@ var ModelCatalogEntrySchema = object({
7119
7119
  "imagenet",
7120
7120
  "none"
7121
7121
  ]).optional(),
7122
+ /**
7123
+ * The model already applies softmax IN-GRAPH — its raw output is a
7124
+ * probability distribution, not logits. When set, the `softmax`
7125
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7126
+ * probability vector collapses it toward uniform (top-1 score craters far
7127
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7128
+ * the output is raw logits and the postprocessor applies softmax (the normal
7129
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7130
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7131
+ */
7132
+ outputProbabilities: boolean().optional(),
7122
7133
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7123
7134
  /**
7124
7135
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11132,10 +11143,7 @@ var ConfigUISchemaNullableBridge = custom();
11132
11143
  var InferenceCapabilitiesBridge = custom();
11133
11144
  var ModelAvailabilityListBridge = custom();
11134
11145
  var PipelineRunResultBridge = custom();
11135
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11136
- kind: "mutation",
11137
- auth: "admin"
11138
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11146
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11139
11147
  modelId: string(),
11140
11148
  settings: record(string(), unknown()).readonly()
11141
11149
  }))), method(object({ steps: record(string(), object({
@@ -11195,13 +11203,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11195
11203
  * (inputClasses ≠ null) are skipped and served per-track via
11196
11204
  * pipelineRunner.runDetailSubtree (two-plane design).
11197
11205
  */
11198
- plane: _enum(["full", "frame"]).optional()
11206
+ plane: _enum(["full", "frame"]).optional(),
11207
+ /**
11208
+ * Inference-device selector (Phase 2 multi-device). Format
11209
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11210
+ * Omitted ⇒ the runner's default device (current single-engine
11211
+ * behaviour). Selects WHICH device pool of the node runs the call.
11212
+ */
11213
+ deviceKey: string().optional()
11199
11214
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11200
11215
  engine: PipelineEngineChoiceSchema.optional(),
11201
11216
  steps: array(PipelineStepInputSchema).min(1),
11202
11217
  frames: array(FrameInputSchema).min(1).max(255),
11203
11218
  deviceId: number$1().optional(),
11204
- sessionId: string().optional()
11219
+ sessionId: string().optional(),
11220
+ /**
11221
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11222
+ * the batch to the Python pool's bench preprocess cache
11223
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11224
+ * preprocessed ONCE and every later inference is a pure-inference cache
11225
+ * hit — the sustained-throughput run measures inference, not
11226
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11227
+ * full preprocess every call, correct). Fresh per sustained run;
11228
+ * released via `uncacheFrame`.
11229
+ */
11230
+ frameId: number$1().int().nonnegative().optional(),
11231
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11232
+ deviceKey: string().optional()
11205
11233
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11206
11234
  data: _instanceof(Uint8Array),
11207
11235
  width: number$1().int().positive(),
@@ -11233,8 +11261,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11233
11261
  * - `runtime` — main camera-serving engine (no idle TTL).
11234
11262
  * - `warm-override` — benchmark/test override held in the warm
11235
11263
  * cache; auto-disposed after the idle TTL.
11264
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11265
+ * multi-device, keyed by `deviceKey`) resolved
11266
+ * via `resolveDeviceFactory`. Runs alongside the
11267
+ * `runtime` engine on a DIFFERENT accelerator
11268
+ * (NPU / iGPU / Coral) — this is how the
11269
+ * Engines tab shows all pools running at once.
11236
11270
  */
11237
- kind: _enum(["runtime", "warm-override"]),
11271
+ kind: _enum([
11272
+ "runtime",
11273
+ "warm-override",
11274
+ "device-pool"
11275
+ ]),
11238
11276
  /** Native pid of the underlying Python pool (null when no pool). */
11239
11277
  poolPid: number$1().nullable(),
11240
11278
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11336,7 +11374,21 @@ var NativeCropResultSchema = object({
11336
11374
  /** Packed rgb (24-bit) pixels of the crop. */
11337
11375
  bytes: _instanceof(Uint8Array),
11338
11376
  width: number$1().int().positive(),
11339
- height: number$1().int().positive()
11377
+ height: number$1().int().positive(),
11378
+ /**
11379
+ * Which source served this crop, so a quality-sensitive consumer (the native
11380
+ * `keyFrame`) can reject a degraded fallback:
11381
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11382
+ * quality path).
11383
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11384
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11385
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11386
+ *
11387
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11388
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11389
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11390
+ */
11391
+ tier: _enum(["native", "ram-fullframe"]).optional()
11340
11392
  });
11341
11393
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11342
11394
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11576,7 +11628,14 @@ var RunnerCameraConfigSchema = object({
11576
11628
  * camera's detect node differs from its source-owner (P2d, gated by the
11577
11629
  * `remoteSourcingNodes` rollout setting).
11578
11630
  */
11579
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11631
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11632
+ /**
11633
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11634
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11635
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11636
+ * this only selects WHICH device pool of that node runs the session.
11637
+ */
11638
+ deviceKey: string().optional()
11580
11639
  });
11581
11640
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11582
11641
  /**
@@ -11597,6 +11656,19 @@ var RunnerLocalLoadSchema = object({
11597
11656
  avgInferenceTimeMs: number$1(),
11598
11657
  /** Total queue depth across motion + detection queues. */
11599
11658
  queueDepthTotal: number$1(),
11659
+ /**
11660
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11661
+ * this runner currently has attached cameras on, so the orchestrator's second
11662
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11663
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11664
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11665
+ */
11666
+ devices: array(object({
11667
+ deviceKey: string(),
11668
+ backend: string(),
11669
+ attachedCameras: number$1(),
11670
+ queueDepthTotal: number$1()
11671
+ })).default([]),
11600
11672
  /** Hardware capability flags reported by this node. */
11601
11673
  hardware: object({
11602
11674
  hasGpu: boolean(),
@@ -13072,6 +13144,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13072
13144
  kind: "mutation",
13073
13145
  auth: "admin"
13074
13146
  });
13147
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
13148
+ new Set(Object.values(DeviceType));
13075
13149
  /**
13076
13150
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13077
13151
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14670,7 +14744,8 @@ var LinkedDeviceSchema = object({
14670
14744
  deviceId: number$1(),
14671
14745
  name: string(),
14672
14746
  location: string().nullable(),
14673
- features: array(string())
14747
+ features: array(string()),
14748
+ producesTrackedEvents: boolean().optional()
14674
14749
  });
14675
14750
  var SavedDeviceRowSchema = object({
14676
14751
  /** Numeric id reserved at allocateDeviceId time. */
@@ -16300,6 +16375,7 @@ var TrackSchema = object({
16300
16375
  deviceId: number$1(),
16301
16376
  className: string(),
16302
16377
  label: string().optional(),
16378
+ producingDeviceName: string().optional(),
16303
16379
  /** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
16304
16380
  source: TrackSourceSchema.optional(),
16305
16381
  firstSeen: number$1(),
@@ -16437,7 +16513,8 @@ var MediaFileKindEnum = _enum([
16437
16513
  "fullFrameBoxed",
16438
16514
  "faceCrop",
16439
16515
  "plateCrop",
16440
- "keyFrame"
16516
+ "keyFrame",
16517
+ "keyFrameSmall"
16441
16518
  ]);
16442
16519
  var MediaFileSchema = object({
16443
16520
  key: string(),
@@ -16766,13 +16843,11 @@ var PipelineTemplateSchema = object({
16766
16843
  createdAt: string(),
16767
16844
  updatedAt: string()
16768
16845
  });
16769
- var AgentAddonConfigSchema = object({
16770
- enabled: boolean(),
16846
+ var DeviceStepConfigSchema = object({
16771
16847
  modelId: string().optional(),
16772
- settings: record(string(), unknown()).readonly()
16848
+ settings: record(string(), unknown()).optional()
16773
16849
  });
16774
16850
  var AgentPipelineSettingsSchema = object({
16775
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16776
16851
  maxCameras: number$1().int().nonnegative().nullable().default(null),
16777
16852
  /** Per-node detection weight (relative share for the quota balancer). */
16778
16853
  detectWeight: number$1().positive().optional(),
@@ -16796,7 +16871,22 @@ var AgentPipelineSettingsSchema = object({
16796
16871
  * it already uses to reach the hub). Set this only when the auto-detected
16797
16872
  * address is wrong (multi-homed host, NAT, custom interface).
16798
16873
  */
16799
- reachableHost: string().optional()
16874
+ reachableHost: string().optional(),
16875
+ /**
16876
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16877
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16878
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16879
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16880
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16881
+ * the default model/settings for every camera landing on that accelerator;
16882
+ * a stepId absent ⇒ the step uses that device's format default.
16883
+ */
16884
+ inferenceDevices: record(string(), object({
16885
+ enabled: boolean(),
16886
+ weight: number$1().positive().optional(),
16887
+ maxSessions: number$1().int().positive().optional(),
16888
+ steps: record(string(), DeviceStepConfigSchema).optional()
16889
+ })).optional()
16800
16890
  });
16801
16891
  var CameraPipelineForAgentSchema = object({
16802
16892
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16806,14 +16896,13 @@ var CameraPipelineForAgentSchema = object({
16806
16896
  }).nullable()
16807
16897
  });
16808
16898
  var CameraStepOverridePatchSchema = object({
16809
- enabled: boolean().optional(),
16810
16899
  modelId: string().optional(),
16811
16900
  settings: record(string(), unknown()).readonly().optional()
16812
16901
  });
16813
16902
  var CameraPipelineSettingsSchema = object({
16814
16903
  pinnedAgentNodeId: string().optional(),
16815
16904
  stepToggles: record(string(), boolean()).optional(),
16816
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16905
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16817
16906
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16818
16907
  });
16819
16908
  /**
@@ -17027,6 +17116,44 @@ var CameraStatusSchema = object({
17027
17116
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
17028
17117
  fetchedAt: number$1()
17029
17118
  });
17119
+ var NodeInferenceDeviceSchema = object({
17120
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17121
+ key: string(),
17122
+ backend: string(),
17123
+ device: string(),
17124
+ format: _enum(MODEL_FORMATS),
17125
+ /** Whether the node's live probe reports the device as usable right now. */
17126
+ available: boolean(),
17127
+ /**
17128
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17129
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17130
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17131
+ * not a balanced target). An explicit stored value always wins; a stored-only
17132
+ * (unavailable) key keeps its stored value.
17133
+ */
17134
+ enabled: boolean(),
17135
+ /** Relative balancer weight for the enabled device (default 1). */
17136
+ weight: number$1(),
17137
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17138
+ maxSessions: number$1().nullable(),
17139
+ /** Object-detection model the executor defaults to for this deviceKey. */
17140
+ defaultModelId: string(),
17141
+ /**
17142
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17143
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17144
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17145
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17146
+ * available per format; this is the stored selection that becomes the
17147
+ * default for EVERY camera landing on this accelerator.
17148
+ */
17149
+ steps: record(string(), DeviceStepConfigSchema).optional()
17150
+ });
17151
+ var NodeInferenceDevicesSchema = object({
17152
+ nodeId: string(),
17153
+ /** False when the node's platform-probe was unreachable (no live device set). */
17154
+ reachable: boolean(),
17155
+ devices: array(NodeInferenceDeviceSchema).readonly()
17156
+ });
17030
17157
  method(object({
17031
17158
  deviceId: number$1(),
17032
17159
  agentNodeId: string()
@@ -17036,7 +17163,13 @@ method(object({
17036
17163
  }), method(object({ deviceId: number$1() }), object({ success: literal(true) }), {
17037
17164
  kind: "mutation",
17038
17165
  auth: "admin"
17039
- }), method(_void(), object({ migrated: number$1() }), {
17166
+ }), method(object({
17167
+ deviceId: number$1(),
17168
+ deviceKey: string()
17169
+ }), object({ success: literal(true) }), {
17170
+ kind: "mutation",
17171
+ auth: "admin"
17172
+ }), method(object({ deviceId: number$1() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number$1() }), {
17040
17173
  kind: "mutation",
17041
17174
  auth: "admin"
17042
17175
  }), method(_void(), array(PipelineAssignmentSchema).readonly()), method(object({ deviceId: number$1() }), PipelineAssignmentSchema.nullable()), method(_void(), array(AgentLoadSummarySchema).readonly()), method(_void(), GlobalMetricsSchema), method(object({ deviceId: number$1() }), CameraMetricsSchema.nullable()), method(object({ nodeId: string() }), CapabilityBindingsSchema), method(object({
@@ -17070,13 +17203,7 @@ method(object({
17070
17203
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17071
17204
  nodeId: string(),
17072
17205
  settings: AgentPipelineSettingsSchema
17073
- })).readonly()), method(object({
17074
- agentNodeId: string(),
17075
- defaults: record(string(), AgentAddonConfigSchema)
17076
- }), object({ success: literal(true) }), {
17077
- kind: "mutation",
17078
- auth: "admin"
17079
- }), method(object({ agentNodeId: string() }), object({
17206
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17080
17207
  success: boolean(),
17081
17208
  removed: boolean()
17082
17209
  }), {
@@ -17108,7 +17235,18 @@ method(object({
17108
17235
  }), object({ success: literal(true) }), {
17109
17236
  kind: "mutation",
17110
17237
  auth: "admin"
17111
- }), method(object({ agentNodeId: string() }), object({
17238
+ }), method(object({
17239
+ agentNodeId: string(),
17240
+ inferenceDevices: record(string(), object({
17241
+ enabled: boolean(),
17242
+ weight: number$1().positive().optional(),
17243
+ maxSessions: number$1().int().positive().optional(),
17244
+ steps: record(string(), DeviceStepConfigSchema).optional()
17245
+ }))
17246
+ }), object({ success: literal(true) }), {
17247
+ kind: "mutation",
17248
+ auth: "admin"
17249
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17112
17250
  success: literal(true),
17113
17251
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17114
17252
  effectiveModelId: string().nullable(),
@@ -17124,9 +17262,10 @@ method(object({
17124
17262
  }), object({ success: literal(true) }), {
17125
17263
  kind: "mutation",
17126
17264
  auth: "admin"
17127
- }), method(object({ deviceId: number$1() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17265
+ }), method(object({ deviceId: number$1() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17128
17266
  deviceId: number$1(),
17129
17267
  agentNodeId: string(),
17268
+ deviceKey: string(),
17130
17269
  addonId: string(),
17131
17270
  patch: CameraStepOverridePatchSchema.nullable()
17132
17271
  }), object({ success: literal(true) }), {
@@ -17163,14 +17302,13 @@ method(object({
17163
17302
  });
17164
17303
  /**
17165
17304
  * server-management — per-NODE singleton capability for a node's ROOT
17166
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17167
- * agents).
17305
+ * package lifecycle (runtime-updatable node packages).
17168
17306
  *
17169
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
17170
- * on agents) carries the whole software stack in its npm dep tree, so ONE
17171
- * version describes the node. Updates install into
17172
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
17173
- * starter (probation boot + auto-rollback to N-1).
17307
+ * Every node role runs the SAME root package (`@camstack/server`), which
17308
+ * carries the whole software stack in its npm dep tree, so ONE version
17309
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17310
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17311
+ * no auto-rollback).
17174
17312
  *
17175
17313
  * Providers:
17176
17314
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17278,7 +17416,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17278
17416
  /** Explicit target version; omitted = latest from the registry. */
17279
17417
  version: string().optional() }), ServerUpdateActionResultSchema, {
17280
17418
  kind: "mutation",
17281
- auth: "admin"
17419
+ auth: "admin",
17420
+ timeoutMs: 16 * 6e4
17282
17421
  }), method(_void(), ServerUpdateActionResultSchema, {
17283
17422
  kind: "mutation",
17284
17423
  auth: "admin"
@@ -18322,22 +18461,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18322
18461
  var RestartAddonResultSchema = unknown();
18323
18462
  var InstallPackageResultSchema = unknown();
18324
18463
  var ReloadPackagesResultSchema = unknown();
18325
- /**
18326
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18327
- * server restarts so the admin UI can react to the `restartingAt`
18328
- * timestamp (shows reconnect overlay). The transition from
18329
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18330
- * `system.restart-completed` event after the new process boots.
18331
- *
18332
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18333
- */
18334
- var UpdateFrameworkPackageResultSchema = object({
18335
- packageName: string(),
18336
- fromVersion: string(),
18337
- toVersion: string(),
18338
- /** Ms-epoch the server scheduled its self-restart. */
18339
- restartingAt: number$1()
18340
- });
18341
18464
  var BulkUpdateItemStatusSchema = _enum([
18342
18465
  "queued",
18343
18466
  "updating",
@@ -18465,13 +18588,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18465
18588
  }), object({ success: literal(true) }), {
18466
18589
  kind: "mutation",
18467
18590
  auth: "admin"
18468
- }), method(object({
18469
- packageName: string().min(1),
18470
- version: string().optional(),
18471
- deferRestart: boolean().optional()
18472
- }), UpdateFrameworkPackageResultSchema, {
18473
- kind: "mutation",
18474
- auth: "admin"
18475
18591
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18476
18592
  kind: "mutation",
18477
18593
  auth: "admin"
@@ -19337,10 +19453,10 @@ var TopologyCategorySchema = object({
19337
19453
  addons: array(TopologyCategoryAddonSchema).readonly()
19338
19454
  });
19339
19455
  /**
19340
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19341
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19342
- * version visibility for the Server management surface. Nullable: offline
19343
- * rows and pre-phase-2 nodes report none.
19456
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19457
+ * root package for every node role) as reported by its `registerNode`
19458
+ * manifest — version visibility for the Server management surface. Nullable:
19459
+ * offline rows and nodes that never reported one.
19344
19460
  */
19345
19461
  var TopologyRootPackageSchema = object({
19346
19462
  name: string(),
@@ -19728,17 +19844,28 @@ var PlatformScoreSchema = object({
19728
19844
  format: _enum([
19729
19845
  "onnx",
19730
19846
  "coreml",
19731
- "openvino"
19847
+ "openvino",
19848
+ "tflite"
19732
19849
  ]),
19733
19850
  score: number$1(),
19734
19851
  reason: string(),
19735
19852
  available: boolean()
19736
19853
  });
19854
+ var InferenceDeviceDescriptorSchema = object({
19855
+ key: string(),
19856
+ backend: string(),
19857
+ device: string(),
19858
+ format: ModelFormatSchema,
19859
+ runtime: literal("python"),
19860
+ score: number$1(),
19861
+ available: boolean()
19862
+ });
19737
19863
  var PlatformCapabilitiesSchema = object({
19738
19864
  hardware: HardwareInfoSchema,
19739
19865
  scores: array(PlatformScoreSchema).readonly(),
19740
19866
  bestScore: PlatformScoreSchema,
19741
- pythonPath: string().nullable()
19867
+ pythonPath: string().nullable(),
19868
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19742
19869
  });
19743
19870
  var ModelRequirementSchema = object({
19744
19871
  modelId: string(),
@@ -20617,12 +20744,6 @@ Object.freeze({
20617
20744
  addonId: null,
20618
20745
  access: "delete"
20619
20746
  },
20620
- "addons.updateFrameworkPackage": {
20621
- capName: "addons",
20622
- capScope: "system",
20623
- addonId: null,
20624
- access: "create"
20625
- },
20626
20747
  "addons.updatePackage": {
20627
20748
  capName: "addons",
20628
20749
  capScope: "system",
@@ -23395,12 +23516,6 @@ Object.freeze({
23395
23516
  addonId: null,
23396
23517
  access: "view"
23397
23518
  },
23398
- "pipelineExecutor.reprobeEngine": {
23399
- capName: "pipeline-executor",
23400
- capScope: "system",
23401
- addonId: null,
23402
- access: "create"
23403
- },
23404
23519
  "pipelineExecutor.runAudioTest": {
23405
23520
  capName: "pipeline-executor",
23406
23521
  capScope: "system",
@@ -23551,6 +23666,12 @@ Object.freeze({
23551
23666
  addonId: null,
23552
23667
  access: "view"
23553
23668
  },
23669
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23670
+ capName: "pipeline-orchestrator",
23671
+ capScope: "system",
23672
+ addonId: null,
23673
+ access: "view"
23674
+ },
23554
23675
  "pipelineOrchestrator.getPipelineAssignment": {
23555
23676
  capName: "pipeline-orchestrator",
23556
23677
  capScope: "system",
@@ -23563,6 +23684,12 @@ Object.freeze({
23563
23684
  addonId: null,
23564
23685
  access: "view"
23565
23686
  },
23687
+ "pipelineOrchestrator.getPipelineDevicePin": {
23688
+ capName: "pipeline-orchestrator",
23689
+ capScope: "system",
23690
+ addonId: null,
23691
+ access: "view"
23692
+ },
23566
23693
  "pipelineOrchestrator.listAgentSettings": {
23567
23694
  capName: "pipeline-orchestrator",
23568
23695
  capScope: "system",
@@ -23605,19 +23732,19 @@ Object.freeze({
23605
23732
  addonId: null,
23606
23733
  access: "create"
23607
23734
  },
23608
- "pipelineOrchestrator.setAgentAddonDefaults": {
23735
+ "pipelineOrchestrator.setAgentCapabilities": {
23609
23736
  capName: "pipeline-orchestrator",
23610
23737
  capScope: "system",
23611
23738
  addonId: null,
23612
23739
  access: "create"
23613
23740
  },
23614
- "pipelineOrchestrator.setAgentCapabilities": {
23741
+ "pipelineOrchestrator.setAgentDetectWeight": {
23615
23742
  capName: "pipeline-orchestrator",
23616
23743
  capScope: "system",
23617
23744
  addonId: null,
23618
23745
  access: "create"
23619
23746
  },
23620
- "pipelineOrchestrator.setAgentDetectWeight": {
23747
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23621
23748
  capName: "pipeline-orchestrator",
23622
23749
  capScope: "system",
23623
23750
  addonId: null,
@@ -23659,6 +23786,12 @@ Object.freeze({
23659
23786
  addonId: null,
23660
23787
  access: "create"
23661
23788
  },
23789
+ "pipelineOrchestrator.setPipelineDevicePin": {
23790
+ capName: "pipeline-orchestrator",
23791
+ capScope: "system",
23792
+ addonId: null,
23793
+ access: "create"
23794
+ },
23662
23795
  "pipelineOrchestrator.unassignAudio": {
23663
23796
  capName: "pipeline-orchestrator",
23664
23797
  capScope: "system",
@@ -25211,32 +25344,6 @@ Object.freeze({
25211
25344
  "network-access": "ingress",
25212
25345
  "smtp-provider": "email"
25213
25346
  });
25214
- var frameworkSwapPackageSchema = object({
25215
- name: string(),
25216
- stagedPath: string(),
25217
- backupPath: string(),
25218
- toVersion: string(),
25219
- fromVersion: string().nullable()
25220
- });
25221
- object({
25222
- jobId: string(),
25223
- taskId: string(),
25224
- packages: array(frameworkSwapPackageSchema),
25225
- requestedAtMs: number$1(),
25226
- schemaVersion: literal(1)
25227
- });
25228
- object({
25229
- jobId: string(),
25230
- taskId: string(),
25231
- backups: array(object({
25232
- name: string(),
25233
- backupPath: string(),
25234
- livePath: string()
25235
- })),
25236
- appliedAtMs: number$1(),
25237
- bootAttempts: number$1(),
25238
- schemaVersion: literal(1)
25239
- });
25240
25347
  //#endregion
25241
25348
  //#region ../../node_modules/readable-stream/lib/ours/primordials.js
25242
25349
  var require_primordials = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -7117,6 +7117,17 @@ var ModelCatalogEntrySchema = object({
7117
7117
  "imagenet",
7118
7118
  "none"
7119
7119
  ]).optional(),
7120
+ /**
7121
+ * The model already applies softmax IN-GRAPH — its raw output is a
7122
+ * probability distribution, not logits. When set, the `softmax`
7123
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7124
+ * probability vector collapses it toward uniform (top-1 score craters far
7125
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7126
+ * the output is raw logits and the postprocessor applies softmax (the normal
7127
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7128
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7129
+ */
7130
+ outputProbabilities: boolean().optional(),
7120
7131
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7121
7132
  /**
7122
7133
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11130,10 +11141,7 @@ var ConfigUISchemaNullableBridge = custom();
11130
11141
  var InferenceCapabilitiesBridge = custom();
11131
11142
  var ModelAvailabilityListBridge = custom();
11132
11143
  var PipelineRunResultBridge = custom();
11133
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11134
- kind: "mutation",
11135
- auth: "admin"
11136
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11144
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11137
11145
  modelId: string(),
11138
11146
  settings: record(string(), unknown()).readonly()
11139
11147
  }))), method(object({ steps: record(string(), object({
@@ -11193,13 +11201,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11193
11201
  * (inputClasses ≠ null) are skipped and served per-track via
11194
11202
  * pipelineRunner.runDetailSubtree (two-plane design).
11195
11203
  */
11196
- plane: _enum(["full", "frame"]).optional()
11204
+ plane: _enum(["full", "frame"]).optional(),
11205
+ /**
11206
+ * Inference-device selector (Phase 2 multi-device). Format
11207
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11208
+ * Omitted ⇒ the runner's default device (current single-engine
11209
+ * behaviour). Selects WHICH device pool of the node runs the call.
11210
+ */
11211
+ deviceKey: string().optional()
11197
11212
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11198
11213
  engine: PipelineEngineChoiceSchema.optional(),
11199
11214
  steps: array(PipelineStepInputSchema).min(1),
11200
11215
  frames: array(FrameInputSchema).min(1).max(255),
11201
11216
  deviceId: number$1().optional(),
11202
- sessionId: string().optional()
11217
+ sessionId: string().optional(),
11218
+ /**
11219
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11220
+ * the batch to the Python pool's bench preprocess cache
11221
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11222
+ * preprocessed ONCE and every later inference is a pure-inference cache
11223
+ * hit — the sustained-throughput run measures inference, not
11224
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11225
+ * full preprocess every call, correct). Fresh per sustained run;
11226
+ * released via `uncacheFrame`.
11227
+ */
11228
+ frameId: number$1().int().nonnegative().optional(),
11229
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11230
+ deviceKey: string().optional()
11203
11231
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11204
11232
  data: _instanceof(Uint8Array),
11205
11233
  width: number$1().int().positive(),
@@ -11231,8 +11259,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11231
11259
  * - `runtime` — main camera-serving engine (no idle TTL).
11232
11260
  * - `warm-override` — benchmark/test override held in the warm
11233
11261
  * cache; auto-disposed after the idle TTL.
11262
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11263
+ * multi-device, keyed by `deviceKey`) resolved
11264
+ * via `resolveDeviceFactory`. Runs alongside the
11265
+ * `runtime` engine on a DIFFERENT accelerator
11266
+ * (NPU / iGPU / Coral) — this is how the
11267
+ * Engines tab shows all pools running at once.
11234
11268
  */
11235
- kind: _enum(["runtime", "warm-override"]),
11269
+ kind: _enum([
11270
+ "runtime",
11271
+ "warm-override",
11272
+ "device-pool"
11273
+ ]),
11236
11274
  /** Native pid of the underlying Python pool (null when no pool). */
11237
11275
  poolPid: number$1().nullable(),
11238
11276
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11334,7 +11372,21 @@ var NativeCropResultSchema = object({
11334
11372
  /** Packed rgb (24-bit) pixels of the crop. */
11335
11373
  bytes: _instanceof(Uint8Array),
11336
11374
  width: number$1().int().positive(),
11337
- height: number$1().int().positive()
11375
+ height: number$1().int().positive(),
11376
+ /**
11377
+ * Which source served this crop, so a quality-sensitive consumer (the native
11378
+ * `keyFrame`) can reject a degraded fallback:
11379
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11380
+ * quality path).
11381
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11382
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11383
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11384
+ *
11385
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11386
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11387
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11388
+ */
11389
+ tier: _enum(["native", "ram-fullframe"]).optional()
11338
11390
  });
11339
11391
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11340
11392
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11574,7 +11626,14 @@ var RunnerCameraConfigSchema = object({
11574
11626
  * camera's detect node differs from its source-owner (P2d, gated by the
11575
11627
  * `remoteSourcingNodes` rollout setting).
11576
11628
  */
11577
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11629
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11630
+ /**
11631
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11632
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11633
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11634
+ * this only selects WHICH device pool of that node runs the session.
11635
+ */
11636
+ deviceKey: string().optional()
11578
11637
  });
11579
11638
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11580
11639
  /**
@@ -11595,6 +11654,19 @@ var RunnerLocalLoadSchema = object({
11595
11654
  avgInferenceTimeMs: number$1(),
11596
11655
  /** Total queue depth across motion + detection queues. */
11597
11656
  queueDepthTotal: number$1(),
11657
+ /**
11658
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11659
+ * this runner currently has attached cameras on, so the orchestrator's second
11660
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11661
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11662
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11663
+ */
11664
+ devices: array(object({
11665
+ deviceKey: string(),
11666
+ backend: string(),
11667
+ attachedCameras: number$1(),
11668
+ queueDepthTotal: number$1()
11669
+ })).default([]),
11598
11670
  /** Hardware capability flags reported by this node. */
11599
11671
  hardware: object({
11600
11672
  hasGpu: boolean(),
@@ -13070,6 +13142,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13070
13142
  kind: "mutation",
13071
13143
  auth: "admin"
13072
13144
  });
13145
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
13146
+ new Set(Object.values(DeviceType));
13073
13147
  /**
13074
13148
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13075
13149
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14668,7 +14742,8 @@ var LinkedDeviceSchema = object({
14668
14742
  deviceId: number$1(),
14669
14743
  name: string(),
14670
14744
  location: string().nullable(),
14671
- features: array(string())
14745
+ features: array(string()),
14746
+ producesTrackedEvents: boolean().optional()
14672
14747
  });
14673
14748
  var SavedDeviceRowSchema = object({
14674
14749
  /** Numeric id reserved at allocateDeviceId time. */
@@ -16298,6 +16373,7 @@ var TrackSchema = object({
16298
16373
  deviceId: number$1(),
16299
16374
  className: string(),
16300
16375
  label: string().optional(),
16376
+ producingDeviceName: string().optional(),
16301
16377
  /** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
16302
16378
  source: TrackSourceSchema.optional(),
16303
16379
  firstSeen: number$1(),
@@ -16435,7 +16511,8 @@ var MediaFileKindEnum = _enum([
16435
16511
  "fullFrameBoxed",
16436
16512
  "faceCrop",
16437
16513
  "plateCrop",
16438
- "keyFrame"
16514
+ "keyFrame",
16515
+ "keyFrameSmall"
16439
16516
  ]);
16440
16517
  var MediaFileSchema = object({
16441
16518
  key: string(),
@@ -16764,13 +16841,11 @@ var PipelineTemplateSchema = object({
16764
16841
  createdAt: string(),
16765
16842
  updatedAt: string()
16766
16843
  });
16767
- var AgentAddonConfigSchema = object({
16768
- enabled: boolean(),
16844
+ var DeviceStepConfigSchema = object({
16769
16845
  modelId: string().optional(),
16770
- settings: record(string(), unknown()).readonly()
16846
+ settings: record(string(), unknown()).optional()
16771
16847
  });
16772
16848
  var AgentPipelineSettingsSchema = object({
16773
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16774
16849
  maxCameras: number$1().int().nonnegative().nullable().default(null),
16775
16850
  /** Per-node detection weight (relative share for the quota balancer). */
16776
16851
  detectWeight: number$1().positive().optional(),
@@ -16794,7 +16869,22 @@ var AgentPipelineSettingsSchema = object({
16794
16869
  * it already uses to reach the hub). Set this only when the auto-detected
16795
16870
  * address is wrong (multi-homed host, NAT, custom interface).
16796
16871
  */
16797
- reachableHost: string().optional()
16872
+ reachableHost: string().optional(),
16873
+ /**
16874
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16875
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16876
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16877
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16878
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16879
+ * the default model/settings for every camera landing on that accelerator;
16880
+ * a stepId absent ⇒ the step uses that device's format default.
16881
+ */
16882
+ inferenceDevices: record(string(), object({
16883
+ enabled: boolean(),
16884
+ weight: number$1().positive().optional(),
16885
+ maxSessions: number$1().int().positive().optional(),
16886
+ steps: record(string(), DeviceStepConfigSchema).optional()
16887
+ })).optional()
16798
16888
  });
16799
16889
  var CameraPipelineForAgentSchema = object({
16800
16890
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16804,14 +16894,13 @@ var CameraPipelineForAgentSchema = object({
16804
16894
  }).nullable()
16805
16895
  });
16806
16896
  var CameraStepOverridePatchSchema = object({
16807
- enabled: boolean().optional(),
16808
16897
  modelId: string().optional(),
16809
16898
  settings: record(string(), unknown()).readonly().optional()
16810
16899
  });
16811
16900
  var CameraPipelineSettingsSchema = object({
16812
16901
  pinnedAgentNodeId: string().optional(),
16813
16902
  stepToggles: record(string(), boolean()).optional(),
16814
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16903
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16815
16904
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16816
16905
  });
16817
16906
  /**
@@ -17025,6 +17114,44 @@ var CameraStatusSchema = object({
17025
17114
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
17026
17115
  fetchedAt: number$1()
17027
17116
  });
17117
+ var NodeInferenceDeviceSchema = object({
17118
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17119
+ key: string(),
17120
+ backend: string(),
17121
+ device: string(),
17122
+ format: _enum(MODEL_FORMATS),
17123
+ /** Whether the node's live probe reports the device as usable right now. */
17124
+ available: boolean(),
17125
+ /**
17126
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17127
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17128
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17129
+ * not a balanced target). An explicit stored value always wins; a stored-only
17130
+ * (unavailable) key keeps its stored value.
17131
+ */
17132
+ enabled: boolean(),
17133
+ /** Relative balancer weight for the enabled device (default 1). */
17134
+ weight: number$1(),
17135
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17136
+ maxSessions: number$1().nullable(),
17137
+ /** Object-detection model the executor defaults to for this deviceKey. */
17138
+ defaultModelId: string(),
17139
+ /**
17140
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17141
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17142
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17143
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17144
+ * available per format; this is the stored selection that becomes the
17145
+ * default for EVERY camera landing on this accelerator.
17146
+ */
17147
+ steps: record(string(), DeviceStepConfigSchema).optional()
17148
+ });
17149
+ var NodeInferenceDevicesSchema = object({
17150
+ nodeId: string(),
17151
+ /** False when the node's platform-probe was unreachable (no live device set). */
17152
+ reachable: boolean(),
17153
+ devices: array(NodeInferenceDeviceSchema).readonly()
17154
+ });
17028
17155
  method(object({
17029
17156
  deviceId: number$1(),
17030
17157
  agentNodeId: string()
@@ -17034,7 +17161,13 @@ method(object({
17034
17161
  }), method(object({ deviceId: number$1() }), object({ success: literal(true) }), {
17035
17162
  kind: "mutation",
17036
17163
  auth: "admin"
17037
- }), method(_void(), object({ migrated: number$1() }), {
17164
+ }), method(object({
17165
+ deviceId: number$1(),
17166
+ deviceKey: string()
17167
+ }), object({ success: literal(true) }), {
17168
+ kind: "mutation",
17169
+ auth: "admin"
17170
+ }), method(object({ deviceId: number$1() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number$1() }), {
17038
17171
  kind: "mutation",
17039
17172
  auth: "admin"
17040
17173
  }), method(_void(), array(PipelineAssignmentSchema).readonly()), method(object({ deviceId: number$1() }), PipelineAssignmentSchema.nullable()), method(_void(), array(AgentLoadSummarySchema).readonly()), method(_void(), GlobalMetricsSchema), method(object({ deviceId: number$1() }), CameraMetricsSchema.nullable()), method(object({ nodeId: string() }), CapabilityBindingsSchema), method(object({
@@ -17068,13 +17201,7 @@ method(object({
17068
17201
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17069
17202
  nodeId: string(),
17070
17203
  settings: AgentPipelineSettingsSchema
17071
- })).readonly()), method(object({
17072
- agentNodeId: string(),
17073
- defaults: record(string(), AgentAddonConfigSchema)
17074
- }), object({ success: literal(true) }), {
17075
- kind: "mutation",
17076
- auth: "admin"
17077
- }), method(object({ agentNodeId: string() }), object({
17204
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17078
17205
  success: boolean(),
17079
17206
  removed: boolean()
17080
17207
  }), {
@@ -17106,7 +17233,18 @@ method(object({
17106
17233
  }), object({ success: literal(true) }), {
17107
17234
  kind: "mutation",
17108
17235
  auth: "admin"
17109
- }), method(object({ agentNodeId: string() }), object({
17236
+ }), method(object({
17237
+ agentNodeId: string(),
17238
+ inferenceDevices: record(string(), object({
17239
+ enabled: boolean(),
17240
+ weight: number$1().positive().optional(),
17241
+ maxSessions: number$1().int().positive().optional(),
17242
+ steps: record(string(), DeviceStepConfigSchema).optional()
17243
+ }))
17244
+ }), object({ success: literal(true) }), {
17245
+ kind: "mutation",
17246
+ auth: "admin"
17247
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17110
17248
  success: literal(true),
17111
17249
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17112
17250
  effectiveModelId: string().nullable(),
@@ -17122,9 +17260,10 @@ method(object({
17122
17260
  }), object({ success: literal(true) }), {
17123
17261
  kind: "mutation",
17124
17262
  auth: "admin"
17125
- }), method(object({ deviceId: number$1() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17263
+ }), method(object({ deviceId: number$1() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17126
17264
  deviceId: number$1(),
17127
17265
  agentNodeId: string(),
17266
+ deviceKey: string(),
17128
17267
  addonId: string(),
17129
17268
  patch: CameraStepOverridePatchSchema.nullable()
17130
17269
  }), object({ success: literal(true) }), {
@@ -17161,14 +17300,13 @@ method(object({
17161
17300
  });
17162
17301
  /**
17163
17302
  * server-management — per-NODE singleton capability for a node's ROOT
17164
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17165
- * agents).
17303
+ * package lifecycle (runtime-updatable node packages).
17166
17304
  *
17167
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
17168
- * on agents) carries the whole software stack in its npm dep tree, so ONE
17169
- * version describes the node. Updates install into
17170
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
17171
- * starter (probation boot + auto-rollback to N-1).
17305
+ * Every node role runs the SAME root package (`@camstack/server`), which
17306
+ * carries the whole software stack in its npm dep tree, so ONE version
17307
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17308
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17309
+ * no auto-rollback).
17172
17310
  *
17173
17311
  * Providers:
17174
17312
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17276,7 +17414,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17276
17414
  /** Explicit target version; omitted = latest from the registry. */
17277
17415
  version: string().optional() }), ServerUpdateActionResultSchema, {
17278
17416
  kind: "mutation",
17279
- auth: "admin"
17417
+ auth: "admin",
17418
+ timeoutMs: 16 * 6e4
17280
17419
  }), method(_void(), ServerUpdateActionResultSchema, {
17281
17420
  kind: "mutation",
17282
17421
  auth: "admin"
@@ -18320,22 +18459,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18320
18459
  var RestartAddonResultSchema = unknown();
18321
18460
  var InstallPackageResultSchema = unknown();
18322
18461
  var ReloadPackagesResultSchema = unknown();
18323
- /**
18324
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18325
- * server restarts so the admin UI can react to the `restartingAt`
18326
- * timestamp (shows reconnect overlay). The transition from
18327
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18328
- * `system.restart-completed` event after the new process boots.
18329
- *
18330
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18331
- */
18332
- var UpdateFrameworkPackageResultSchema = object({
18333
- packageName: string(),
18334
- fromVersion: string(),
18335
- toVersion: string(),
18336
- /** Ms-epoch the server scheduled its self-restart. */
18337
- restartingAt: number$1()
18338
- });
18339
18462
  var BulkUpdateItemStatusSchema = _enum([
18340
18463
  "queued",
18341
18464
  "updating",
@@ -18463,13 +18586,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18463
18586
  }), object({ success: literal(true) }), {
18464
18587
  kind: "mutation",
18465
18588
  auth: "admin"
18466
- }), method(object({
18467
- packageName: string().min(1),
18468
- version: string().optional(),
18469
- deferRestart: boolean().optional()
18470
- }), UpdateFrameworkPackageResultSchema, {
18471
- kind: "mutation",
18472
- auth: "admin"
18473
18589
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18474
18590
  kind: "mutation",
18475
18591
  auth: "admin"
@@ -19335,10 +19451,10 @@ var TopologyCategorySchema = object({
19335
19451
  addons: array(TopologyCategoryAddonSchema).readonly()
19336
19452
  });
19337
19453
  /**
19338
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19339
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19340
- * version visibility for the Server management surface. Nullable: offline
19341
- * rows and pre-phase-2 nodes report none.
19454
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19455
+ * root package for every node role) as reported by its `registerNode`
19456
+ * manifest — version visibility for the Server management surface. Nullable:
19457
+ * offline rows and nodes that never reported one.
19342
19458
  */
19343
19459
  var TopologyRootPackageSchema = object({
19344
19460
  name: string(),
@@ -19726,17 +19842,28 @@ var PlatformScoreSchema = object({
19726
19842
  format: _enum([
19727
19843
  "onnx",
19728
19844
  "coreml",
19729
- "openvino"
19845
+ "openvino",
19846
+ "tflite"
19730
19847
  ]),
19731
19848
  score: number$1(),
19732
19849
  reason: string(),
19733
19850
  available: boolean()
19734
19851
  });
19852
+ var InferenceDeviceDescriptorSchema = object({
19853
+ key: string(),
19854
+ backend: string(),
19855
+ device: string(),
19856
+ format: ModelFormatSchema,
19857
+ runtime: literal("python"),
19858
+ score: number$1(),
19859
+ available: boolean()
19860
+ });
19735
19861
  var PlatformCapabilitiesSchema = object({
19736
19862
  hardware: HardwareInfoSchema,
19737
19863
  scores: array(PlatformScoreSchema).readonly(),
19738
19864
  bestScore: PlatformScoreSchema,
19739
- pythonPath: string().nullable()
19865
+ pythonPath: string().nullable(),
19866
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19740
19867
  });
19741
19868
  var ModelRequirementSchema = object({
19742
19869
  modelId: string(),
@@ -20615,12 +20742,6 @@ Object.freeze({
20615
20742
  addonId: null,
20616
20743
  access: "delete"
20617
20744
  },
20618
- "addons.updateFrameworkPackage": {
20619
- capName: "addons",
20620
- capScope: "system",
20621
- addonId: null,
20622
- access: "create"
20623
- },
20624
20745
  "addons.updatePackage": {
20625
20746
  capName: "addons",
20626
20747
  capScope: "system",
@@ -23393,12 +23514,6 @@ Object.freeze({
23393
23514
  addonId: null,
23394
23515
  access: "view"
23395
23516
  },
23396
- "pipelineExecutor.reprobeEngine": {
23397
- capName: "pipeline-executor",
23398
- capScope: "system",
23399
- addonId: null,
23400
- access: "create"
23401
- },
23402
23517
  "pipelineExecutor.runAudioTest": {
23403
23518
  capName: "pipeline-executor",
23404
23519
  capScope: "system",
@@ -23549,6 +23664,12 @@ Object.freeze({
23549
23664
  addonId: null,
23550
23665
  access: "view"
23551
23666
  },
23667
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23668
+ capName: "pipeline-orchestrator",
23669
+ capScope: "system",
23670
+ addonId: null,
23671
+ access: "view"
23672
+ },
23552
23673
  "pipelineOrchestrator.getPipelineAssignment": {
23553
23674
  capName: "pipeline-orchestrator",
23554
23675
  capScope: "system",
@@ -23561,6 +23682,12 @@ Object.freeze({
23561
23682
  addonId: null,
23562
23683
  access: "view"
23563
23684
  },
23685
+ "pipelineOrchestrator.getPipelineDevicePin": {
23686
+ capName: "pipeline-orchestrator",
23687
+ capScope: "system",
23688
+ addonId: null,
23689
+ access: "view"
23690
+ },
23564
23691
  "pipelineOrchestrator.listAgentSettings": {
23565
23692
  capName: "pipeline-orchestrator",
23566
23693
  capScope: "system",
@@ -23603,19 +23730,19 @@ Object.freeze({
23603
23730
  addonId: null,
23604
23731
  access: "create"
23605
23732
  },
23606
- "pipelineOrchestrator.setAgentAddonDefaults": {
23733
+ "pipelineOrchestrator.setAgentCapabilities": {
23607
23734
  capName: "pipeline-orchestrator",
23608
23735
  capScope: "system",
23609
23736
  addonId: null,
23610
23737
  access: "create"
23611
23738
  },
23612
- "pipelineOrchestrator.setAgentCapabilities": {
23739
+ "pipelineOrchestrator.setAgentDetectWeight": {
23613
23740
  capName: "pipeline-orchestrator",
23614
23741
  capScope: "system",
23615
23742
  addonId: null,
23616
23743
  access: "create"
23617
23744
  },
23618
- "pipelineOrchestrator.setAgentDetectWeight": {
23745
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23619
23746
  capName: "pipeline-orchestrator",
23620
23747
  capScope: "system",
23621
23748
  addonId: null,
@@ -23657,6 +23784,12 @@ Object.freeze({
23657
23784
  addonId: null,
23658
23785
  access: "create"
23659
23786
  },
23787
+ "pipelineOrchestrator.setPipelineDevicePin": {
23788
+ capName: "pipeline-orchestrator",
23789
+ capScope: "system",
23790
+ addonId: null,
23791
+ access: "create"
23792
+ },
23660
23793
  "pipelineOrchestrator.unassignAudio": {
23661
23794
  capName: "pipeline-orchestrator",
23662
23795
  capScope: "system",
@@ -25209,32 +25342,6 @@ Object.freeze({
25209
25342
  "network-access": "ingress",
25210
25343
  "smtp-provider": "email"
25211
25344
  });
25212
- var frameworkSwapPackageSchema = object({
25213
- name: string(),
25214
- stagedPath: string(),
25215
- backupPath: string(),
25216
- toVersion: string(),
25217
- fromVersion: string().nullable()
25218
- });
25219
- object({
25220
- jobId: string(),
25221
- taskId: string(),
25222
- packages: array(frameworkSwapPackageSchema),
25223
- requestedAtMs: number$1(),
25224
- schemaVersion: literal(1)
25225
- });
25226
- object({
25227
- jobId: string(),
25228
- taskId: string(),
25229
- backups: array(object({
25230
- name: string(),
25231
- backupPath: string(),
25232
- livePath: string()
25233
- })),
25234
- appliedAtMs: number$1(),
25235
- bootAttempts: number$1(),
25236
- schemaVersion: literal(1)
25237
- });
25238
25345
  //#endregion
25239
25346
  //#region ../../node_modules/readable-stream/lib/ours/primordials.js
25240
25347
  var require_primordials = /* @__PURE__ */ __commonJSMin(((exports, module) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-ha-mqtt",
3
- "version": "1.1.27",
3
+ "version": "1.2.1",
4
4
  "description": "HomeAssistant MQTT discovery exporter for CamStack devices. Publishes discovery topics so HA auto-creates entities for exposed cameras/switches/intercoms/sensors.",
5
5
  "keywords": [
6
6
  "camstack",