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

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). */
@@ -11576,7 +11614,14 @@ var RunnerCameraConfigSchema = object({
11576
11614
  * camera's detect node differs from its source-owner (P2d, gated by the
11577
11615
  * `remoteSourcingNodes` rollout setting).
11578
11616
  */
11579
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11617
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11618
+ /**
11619
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11620
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11621
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11622
+ * this only selects WHICH device pool of that node runs the session.
11623
+ */
11624
+ deviceKey: string().optional()
11580
11625
  });
11581
11626
  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
11627
  /**
@@ -11597,6 +11642,19 @@ var RunnerLocalLoadSchema = object({
11597
11642
  avgInferenceTimeMs: number$1(),
11598
11643
  /** Total queue depth across motion + detection queues. */
11599
11644
  queueDepthTotal: number$1(),
11645
+ /**
11646
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11647
+ * this runner currently has attached cameras on, so the orchestrator's second
11648
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11649
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11650
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11651
+ */
11652
+ devices: array(object({
11653
+ deviceKey: string(),
11654
+ backend: string(),
11655
+ attachedCameras: number$1(),
11656
+ queueDepthTotal: number$1()
11657
+ })).default([]),
11600
11658
  /** Hardware capability flags reported by this node. */
11601
11659
  hardware: object({
11602
11660
  hasGpu: boolean(),
@@ -13072,6 +13130,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13072
13130
  kind: "mutation",
13073
13131
  auth: "admin"
13074
13132
  });
13133
+ 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;
13134
+ new Set(Object.values(DeviceType));
13075
13135
  /**
13076
13136
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13077
13137
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -16766,13 +16826,11 @@ var PipelineTemplateSchema = object({
16766
16826
  createdAt: string(),
16767
16827
  updatedAt: string()
16768
16828
  });
16769
- var AgentAddonConfigSchema = object({
16770
- enabled: boolean(),
16829
+ var DeviceStepConfigSchema = object({
16771
16830
  modelId: string().optional(),
16772
- settings: record(string(), unknown()).readonly()
16831
+ settings: record(string(), unknown()).optional()
16773
16832
  });
16774
16833
  var AgentPipelineSettingsSchema = object({
16775
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16776
16834
  maxCameras: number$1().int().nonnegative().nullable().default(null),
16777
16835
  /** Per-node detection weight (relative share for the quota balancer). */
16778
16836
  detectWeight: number$1().positive().optional(),
@@ -16796,7 +16854,22 @@ var AgentPipelineSettingsSchema = object({
16796
16854
  * it already uses to reach the hub). Set this only when the auto-detected
16797
16855
  * address is wrong (multi-homed host, NAT, custom interface).
16798
16856
  */
16799
- reachableHost: string().optional()
16857
+ reachableHost: string().optional(),
16858
+ /**
16859
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16860
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16861
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16862
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16863
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16864
+ * the default model/settings for every camera landing on that accelerator;
16865
+ * a stepId absent ⇒ the step uses that device's format default.
16866
+ */
16867
+ inferenceDevices: record(string(), object({
16868
+ enabled: boolean(),
16869
+ weight: number$1().positive().optional(),
16870
+ maxSessions: number$1().int().positive().optional(),
16871
+ steps: record(string(), DeviceStepConfigSchema).optional()
16872
+ })).optional()
16800
16873
  });
16801
16874
  var CameraPipelineForAgentSchema = object({
16802
16875
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16806,14 +16879,13 @@ var CameraPipelineForAgentSchema = object({
16806
16879
  }).nullable()
16807
16880
  });
16808
16881
  var CameraStepOverridePatchSchema = object({
16809
- enabled: boolean().optional(),
16810
16882
  modelId: string().optional(),
16811
16883
  settings: record(string(), unknown()).readonly().optional()
16812
16884
  });
16813
16885
  var CameraPipelineSettingsSchema = object({
16814
16886
  pinnedAgentNodeId: string().optional(),
16815
16887
  stepToggles: record(string(), boolean()).optional(),
16816
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16888
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16817
16889
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16818
16890
  });
16819
16891
  /**
@@ -17027,6 +17099,44 @@ var CameraStatusSchema = object({
17027
17099
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
17028
17100
  fetchedAt: number$1()
17029
17101
  });
17102
+ var NodeInferenceDeviceSchema = object({
17103
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17104
+ key: string(),
17105
+ backend: string(),
17106
+ device: string(),
17107
+ format: _enum(MODEL_FORMATS),
17108
+ /** Whether the node's live probe reports the device as usable right now. */
17109
+ available: boolean(),
17110
+ /**
17111
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17112
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17113
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17114
+ * not a balanced target). An explicit stored value always wins; a stored-only
17115
+ * (unavailable) key keeps its stored value.
17116
+ */
17117
+ enabled: boolean(),
17118
+ /** Relative balancer weight for the enabled device (default 1). */
17119
+ weight: number$1(),
17120
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17121
+ maxSessions: number$1().nullable(),
17122
+ /** Object-detection model the executor defaults to for this deviceKey. */
17123
+ defaultModelId: string(),
17124
+ /**
17125
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17126
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17127
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17128
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17129
+ * available per format; this is the stored selection that becomes the
17130
+ * default for EVERY camera landing on this accelerator.
17131
+ */
17132
+ steps: record(string(), DeviceStepConfigSchema).optional()
17133
+ });
17134
+ var NodeInferenceDevicesSchema = object({
17135
+ nodeId: string(),
17136
+ /** False when the node's platform-probe was unreachable (no live device set). */
17137
+ reachable: boolean(),
17138
+ devices: array(NodeInferenceDeviceSchema).readonly()
17139
+ });
17030
17140
  method(object({
17031
17141
  deviceId: number$1(),
17032
17142
  agentNodeId: string()
@@ -17036,7 +17146,13 @@ method(object({
17036
17146
  }), method(object({ deviceId: number$1() }), object({ success: literal(true) }), {
17037
17147
  kind: "mutation",
17038
17148
  auth: "admin"
17039
- }), method(_void(), object({ migrated: number$1() }), {
17149
+ }), method(object({
17150
+ deviceId: number$1(),
17151
+ deviceKey: string()
17152
+ }), object({ success: literal(true) }), {
17153
+ kind: "mutation",
17154
+ auth: "admin"
17155
+ }), method(object({ deviceId: number$1() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number$1() }), {
17040
17156
  kind: "mutation",
17041
17157
  auth: "admin"
17042
17158
  }), 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 +17186,7 @@ method(object({
17070
17186
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17071
17187
  nodeId: string(),
17072
17188
  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({
17189
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17080
17190
  success: boolean(),
17081
17191
  removed: boolean()
17082
17192
  }), {
@@ -17108,7 +17218,18 @@ method(object({
17108
17218
  }), object({ success: literal(true) }), {
17109
17219
  kind: "mutation",
17110
17220
  auth: "admin"
17111
- }), method(object({ agentNodeId: string() }), object({
17221
+ }), method(object({
17222
+ agentNodeId: string(),
17223
+ inferenceDevices: record(string(), object({
17224
+ enabled: boolean(),
17225
+ weight: number$1().positive().optional(),
17226
+ maxSessions: number$1().int().positive().optional(),
17227
+ steps: record(string(), DeviceStepConfigSchema).optional()
17228
+ }))
17229
+ }), object({ success: literal(true) }), {
17230
+ kind: "mutation",
17231
+ auth: "admin"
17232
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17112
17233
  success: literal(true),
17113
17234
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17114
17235
  effectiveModelId: string().nullable(),
@@ -17124,9 +17245,10 @@ method(object({
17124
17245
  }), object({ success: literal(true) }), {
17125
17246
  kind: "mutation",
17126
17247
  auth: "admin"
17127
- }), method(object({ deviceId: number$1() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17248
+ }), method(object({ deviceId: number$1() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17128
17249
  deviceId: number$1(),
17129
17250
  agentNodeId: string(),
17251
+ deviceKey: string(),
17130
17252
  addonId: string(),
17131
17253
  patch: CameraStepOverridePatchSchema.nullable()
17132
17254
  }), object({ success: literal(true) }), {
@@ -17163,14 +17285,13 @@ method(object({
17163
17285
  });
17164
17286
  /**
17165
17287
  * server-management — per-NODE singleton capability for a node's ROOT
17166
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17167
- * agents).
17288
+ * package lifecycle (runtime-updatable node packages).
17168
17289
  *
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).
17290
+ * Every node role runs the SAME root package (`@camstack/server`), which
17291
+ * carries the whole software stack in its npm dep tree, so ONE version
17292
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17293
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17294
+ * no auto-rollback).
17174
17295
  *
17175
17296
  * Providers:
17176
17297
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17278,7 +17399,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17278
17399
  /** Explicit target version; omitted = latest from the registry. */
17279
17400
  version: string().optional() }), ServerUpdateActionResultSchema, {
17280
17401
  kind: "mutation",
17281
- auth: "admin"
17402
+ auth: "admin",
17403
+ timeoutMs: 16 * 6e4
17282
17404
  }), method(_void(), ServerUpdateActionResultSchema, {
17283
17405
  kind: "mutation",
17284
17406
  auth: "admin"
@@ -18322,22 +18444,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18322
18444
  var RestartAddonResultSchema = unknown();
18323
18445
  var InstallPackageResultSchema = unknown();
18324
18446
  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
18447
  var BulkUpdateItemStatusSchema = _enum([
18342
18448
  "queued",
18343
18449
  "updating",
@@ -18465,13 +18571,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18465
18571
  }), object({ success: literal(true) }), {
18466
18572
  kind: "mutation",
18467
18573
  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
18574
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18476
18575
  kind: "mutation",
18477
18576
  auth: "admin"
@@ -19337,10 +19436,10 @@ var TopologyCategorySchema = object({
19337
19436
  addons: array(TopologyCategoryAddonSchema).readonly()
19338
19437
  });
19339
19438
  /**
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.
19439
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19440
+ * root package for every node role) as reported by its `registerNode`
19441
+ * manifest — version visibility for the Server management surface. Nullable:
19442
+ * offline rows and nodes that never reported one.
19344
19443
  */
19345
19444
  var TopologyRootPackageSchema = object({
19346
19445
  name: string(),
@@ -19728,17 +19827,28 @@ var PlatformScoreSchema = object({
19728
19827
  format: _enum([
19729
19828
  "onnx",
19730
19829
  "coreml",
19731
- "openvino"
19830
+ "openvino",
19831
+ "tflite"
19732
19832
  ]),
19733
19833
  score: number$1(),
19734
19834
  reason: string(),
19735
19835
  available: boolean()
19736
19836
  });
19837
+ var InferenceDeviceDescriptorSchema = object({
19838
+ key: string(),
19839
+ backend: string(),
19840
+ device: string(),
19841
+ format: ModelFormatSchema,
19842
+ runtime: literal("python"),
19843
+ score: number$1(),
19844
+ available: boolean()
19845
+ });
19737
19846
  var PlatformCapabilitiesSchema = object({
19738
19847
  hardware: HardwareInfoSchema,
19739
19848
  scores: array(PlatformScoreSchema).readonly(),
19740
19849
  bestScore: PlatformScoreSchema,
19741
- pythonPath: string().nullable()
19850
+ pythonPath: string().nullable(),
19851
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19742
19852
  });
19743
19853
  var ModelRequirementSchema = object({
19744
19854
  modelId: string(),
@@ -20617,12 +20727,6 @@ Object.freeze({
20617
20727
  addonId: null,
20618
20728
  access: "delete"
20619
20729
  },
20620
- "addons.updateFrameworkPackage": {
20621
- capName: "addons",
20622
- capScope: "system",
20623
- addonId: null,
20624
- access: "create"
20625
- },
20626
20730
  "addons.updatePackage": {
20627
20731
  capName: "addons",
20628
20732
  capScope: "system",
@@ -23395,12 +23499,6 @@ Object.freeze({
23395
23499
  addonId: null,
23396
23500
  access: "view"
23397
23501
  },
23398
- "pipelineExecutor.reprobeEngine": {
23399
- capName: "pipeline-executor",
23400
- capScope: "system",
23401
- addonId: null,
23402
- access: "create"
23403
- },
23404
23502
  "pipelineExecutor.runAudioTest": {
23405
23503
  capName: "pipeline-executor",
23406
23504
  capScope: "system",
@@ -23551,6 +23649,12 @@ Object.freeze({
23551
23649
  addonId: null,
23552
23650
  access: "view"
23553
23651
  },
23652
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23653
+ capName: "pipeline-orchestrator",
23654
+ capScope: "system",
23655
+ addonId: null,
23656
+ access: "view"
23657
+ },
23554
23658
  "pipelineOrchestrator.getPipelineAssignment": {
23555
23659
  capName: "pipeline-orchestrator",
23556
23660
  capScope: "system",
@@ -23563,6 +23667,12 @@ Object.freeze({
23563
23667
  addonId: null,
23564
23668
  access: "view"
23565
23669
  },
23670
+ "pipelineOrchestrator.getPipelineDevicePin": {
23671
+ capName: "pipeline-orchestrator",
23672
+ capScope: "system",
23673
+ addonId: null,
23674
+ access: "view"
23675
+ },
23566
23676
  "pipelineOrchestrator.listAgentSettings": {
23567
23677
  capName: "pipeline-orchestrator",
23568
23678
  capScope: "system",
@@ -23605,19 +23715,19 @@ Object.freeze({
23605
23715
  addonId: null,
23606
23716
  access: "create"
23607
23717
  },
23608
- "pipelineOrchestrator.setAgentAddonDefaults": {
23718
+ "pipelineOrchestrator.setAgentCapabilities": {
23609
23719
  capName: "pipeline-orchestrator",
23610
23720
  capScope: "system",
23611
23721
  addonId: null,
23612
23722
  access: "create"
23613
23723
  },
23614
- "pipelineOrchestrator.setAgentCapabilities": {
23724
+ "pipelineOrchestrator.setAgentDetectWeight": {
23615
23725
  capName: "pipeline-orchestrator",
23616
23726
  capScope: "system",
23617
23727
  addonId: null,
23618
23728
  access: "create"
23619
23729
  },
23620
- "pipelineOrchestrator.setAgentDetectWeight": {
23730
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23621
23731
  capName: "pipeline-orchestrator",
23622
23732
  capScope: "system",
23623
23733
  addonId: null,
@@ -23659,6 +23769,12 @@ Object.freeze({
23659
23769
  addonId: null,
23660
23770
  access: "create"
23661
23771
  },
23772
+ "pipelineOrchestrator.setPipelineDevicePin": {
23773
+ capName: "pipeline-orchestrator",
23774
+ capScope: "system",
23775
+ addonId: null,
23776
+ access: "create"
23777
+ },
23662
23778
  "pipelineOrchestrator.unassignAudio": {
23663
23779
  capName: "pipeline-orchestrator",
23664
23780
  capScope: "system",
@@ -25211,32 +25327,6 @@ Object.freeze({
25211
25327
  "network-access": "ingress",
25212
25328
  "smtp-provider": "email"
25213
25329
  });
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
25330
  //#endregion
25241
25331
  //#region ../../node_modules/readable-stream/lib/ours/primordials.js
25242
25332
  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). */
@@ -11574,7 +11612,14 @@ var RunnerCameraConfigSchema = object({
11574
11612
  * camera's detect node differs from its source-owner (P2d, gated by the
11575
11613
  * `remoteSourcingNodes` rollout setting).
11576
11614
  */
11577
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11615
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11616
+ /**
11617
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11618
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11619
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11620
+ * this only selects WHICH device pool of that node runs the session.
11621
+ */
11622
+ deviceKey: string().optional()
11578
11623
  });
11579
11624
  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
11625
  /**
@@ -11595,6 +11640,19 @@ var RunnerLocalLoadSchema = object({
11595
11640
  avgInferenceTimeMs: number$1(),
11596
11641
  /** Total queue depth across motion + detection queues. */
11597
11642
  queueDepthTotal: number$1(),
11643
+ /**
11644
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11645
+ * this runner currently has attached cameras on, so the orchestrator's second
11646
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11647
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11648
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11649
+ */
11650
+ devices: array(object({
11651
+ deviceKey: string(),
11652
+ backend: string(),
11653
+ attachedCameras: number$1(),
11654
+ queueDepthTotal: number$1()
11655
+ })).default([]),
11598
11656
  /** Hardware capability flags reported by this node. */
11599
11657
  hardware: object({
11600
11658
  hasGpu: boolean(),
@@ -13070,6 +13128,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13070
13128
  kind: "mutation",
13071
13129
  auth: "admin"
13072
13130
  });
13131
+ 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;
13132
+ new Set(Object.values(DeviceType));
13073
13133
  /**
13074
13134
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13075
13135
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -16764,13 +16824,11 @@ var PipelineTemplateSchema = object({
16764
16824
  createdAt: string(),
16765
16825
  updatedAt: string()
16766
16826
  });
16767
- var AgentAddonConfigSchema = object({
16768
- enabled: boolean(),
16827
+ var DeviceStepConfigSchema = object({
16769
16828
  modelId: string().optional(),
16770
- settings: record(string(), unknown()).readonly()
16829
+ settings: record(string(), unknown()).optional()
16771
16830
  });
16772
16831
  var AgentPipelineSettingsSchema = object({
16773
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16774
16832
  maxCameras: number$1().int().nonnegative().nullable().default(null),
16775
16833
  /** Per-node detection weight (relative share for the quota balancer). */
16776
16834
  detectWeight: number$1().positive().optional(),
@@ -16794,7 +16852,22 @@ var AgentPipelineSettingsSchema = object({
16794
16852
  * it already uses to reach the hub). Set this only when the auto-detected
16795
16853
  * address is wrong (multi-homed host, NAT, custom interface).
16796
16854
  */
16797
- reachableHost: string().optional()
16855
+ reachableHost: string().optional(),
16856
+ /**
16857
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16858
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16859
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16860
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16861
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16862
+ * the default model/settings for every camera landing on that accelerator;
16863
+ * a stepId absent ⇒ the step uses that device's format default.
16864
+ */
16865
+ inferenceDevices: record(string(), object({
16866
+ enabled: boolean(),
16867
+ weight: number$1().positive().optional(),
16868
+ maxSessions: number$1().int().positive().optional(),
16869
+ steps: record(string(), DeviceStepConfigSchema).optional()
16870
+ })).optional()
16798
16871
  });
16799
16872
  var CameraPipelineForAgentSchema = object({
16800
16873
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16804,14 +16877,13 @@ var CameraPipelineForAgentSchema = object({
16804
16877
  }).nullable()
16805
16878
  });
16806
16879
  var CameraStepOverridePatchSchema = object({
16807
- enabled: boolean().optional(),
16808
16880
  modelId: string().optional(),
16809
16881
  settings: record(string(), unknown()).readonly().optional()
16810
16882
  });
16811
16883
  var CameraPipelineSettingsSchema = object({
16812
16884
  pinnedAgentNodeId: string().optional(),
16813
16885
  stepToggles: record(string(), boolean()).optional(),
16814
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16886
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16815
16887
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16816
16888
  });
16817
16889
  /**
@@ -17025,6 +17097,44 @@ var CameraStatusSchema = object({
17025
17097
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
17026
17098
  fetchedAt: number$1()
17027
17099
  });
17100
+ var NodeInferenceDeviceSchema = object({
17101
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17102
+ key: string(),
17103
+ backend: string(),
17104
+ device: string(),
17105
+ format: _enum(MODEL_FORMATS),
17106
+ /** Whether the node's live probe reports the device as usable right now. */
17107
+ available: boolean(),
17108
+ /**
17109
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17110
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17111
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17112
+ * not a balanced target). An explicit stored value always wins; a stored-only
17113
+ * (unavailable) key keeps its stored value.
17114
+ */
17115
+ enabled: boolean(),
17116
+ /** Relative balancer weight for the enabled device (default 1). */
17117
+ weight: number$1(),
17118
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17119
+ maxSessions: number$1().nullable(),
17120
+ /** Object-detection model the executor defaults to for this deviceKey. */
17121
+ defaultModelId: string(),
17122
+ /**
17123
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17124
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17125
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17126
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17127
+ * available per format; this is the stored selection that becomes the
17128
+ * default for EVERY camera landing on this accelerator.
17129
+ */
17130
+ steps: record(string(), DeviceStepConfigSchema).optional()
17131
+ });
17132
+ var NodeInferenceDevicesSchema = object({
17133
+ nodeId: string(),
17134
+ /** False when the node's platform-probe was unreachable (no live device set). */
17135
+ reachable: boolean(),
17136
+ devices: array(NodeInferenceDeviceSchema).readonly()
17137
+ });
17028
17138
  method(object({
17029
17139
  deviceId: number$1(),
17030
17140
  agentNodeId: string()
@@ -17034,7 +17144,13 @@ method(object({
17034
17144
  }), method(object({ deviceId: number$1() }), object({ success: literal(true) }), {
17035
17145
  kind: "mutation",
17036
17146
  auth: "admin"
17037
- }), method(_void(), object({ migrated: number$1() }), {
17147
+ }), method(object({
17148
+ deviceId: number$1(),
17149
+ deviceKey: string()
17150
+ }), object({ success: literal(true) }), {
17151
+ kind: "mutation",
17152
+ auth: "admin"
17153
+ }), method(object({ deviceId: number$1() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number$1() }), {
17038
17154
  kind: "mutation",
17039
17155
  auth: "admin"
17040
17156
  }), 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 +17184,7 @@ method(object({
17068
17184
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17069
17185
  nodeId: string(),
17070
17186
  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({
17187
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17078
17188
  success: boolean(),
17079
17189
  removed: boolean()
17080
17190
  }), {
@@ -17106,7 +17216,18 @@ method(object({
17106
17216
  }), object({ success: literal(true) }), {
17107
17217
  kind: "mutation",
17108
17218
  auth: "admin"
17109
- }), method(object({ agentNodeId: string() }), object({
17219
+ }), method(object({
17220
+ agentNodeId: string(),
17221
+ inferenceDevices: record(string(), object({
17222
+ enabled: boolean(),
17223
+ weight: number$1().positive().optional(),
17224
+ maxSessions: number$1().int().positive().optional(),
17225
+ steps: record(string(), DeviceStepConfigSchema).optional()
17226
+ }))
17227
+ }), object({ success: literal(true) }), {
17228
+ kind: "mutation",
17229
+ auth: "admin"
17230
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17110
17231
  success: literal(true),
17111
17232
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17112
17233
  effectiveModelId: string().nullable(),
@@ -17122,9 +17243,10 @@ method(object({
17122
17243
  }), object({ success: literal(true) }), {
17123
17244
  kind: "mutation",
17124
17245
  auth: "admin"
17125
- }), method(object({ deviceId: number$1() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17246
+ }), method(object({ deviceId: number$1() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17126
17247
  deviceId: number$1(),
17127
17248
  agentNodeId: string(),
17249
+ deviceKey: string(),
17128
17250
  addonId: string(),
17129
17251
  patch: CameraStepOverridePatchSchema.nullable()
17130
17252
  }), object({ success: literal(true) }), {
@@ -17161,14 +17283,13 @@ method(object({
17161
17283
  });
17162
17284
  /**
17163
17285
  * server-management — per-NODE singleton capability for a node's ROOT
17164
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17165
- * agents).
17286
+ * package lifecycle (runtime-updatable node packages).
17166
17287
  *
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).
17288
+ * Every node role runs the SAME root package (`@camstack/server`), which
17289
+ * carries the whole software stack in its npm dep tree, so ONE version
17290
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17291
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17292
+ * no auto-rollback).
17172
17293
  *
17173
17294
  * Providers:
17174
17295
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17276,7 +17397,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17276
17397
  /** Explicit target version; omitted = latest from the registry. */
17277
17398
  version: string().optional() }), ServerUpdateActionResultSchema, {
17278
17399
  kind: "mutation",
17279
- auth: "admin"
17400
+ auth: "admin",
17401
+ timeoutMs: 16 * 6e4
17280
17402
  }), method(_void(), ServerUpdateActionResultSchema, {
17281
17403
  kind: "mutation",
17282
17404
  auth: "admin"
@@ -18320,22 +18442,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18320
18442
  var RestartAddonResultSchema = unknown();
18321
18443
  var InstallPackageResultSchema = unknown();
18322
18444
  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
18445
  var BulkUpdateItemStatusSchema = _enum([
18340
18446
  "queued",
18341
18447
  "updating",
@@ -18463,13 +18569,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18463
18569
  }), object({ success: literal(true) }), {
18464
18570
  kind: "mutation",
18465
18571
  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
18572
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18474
18573
  kind: "mutation",
18475
18574
  auth: "admin"
@@ -19335,10 +19434,10 @@ var TopologyCategorySchema = object({
19335
19434
  addons: array(TopologyCategoryAddonSchema).readonly()
19336
19435
  });
19337
19436
  /**
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.
19437
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19438
+ * root package for every node role) as reported by its `registerNode`
19439
+ * manifest — version visibility for the Server management surface. Nullable:
19440
+ * offline rows and nodes that never reported one.
19342
19441
  */
19343
19442
  var TopologyRootPackageSchema = object({
19344
19443
  name: string(),
@@ -19726,17 +19825,28 @@ var PlatformScoreSchema = object({
19726
19825
  format: _enum([
19727
19826
  "onnx",
19728
19827
  "coreml",
19729
- "openvino"
19828
+ "openvino",
19829
+ "tflite"
19730
19830
  ]),
19731
19831
  score: number$1(),
19732
19832
  reason: string(),
19733
19833
  available: boolean()
19734
19834
  });
19835
+ var InferenceDeviceDescriptorSchema = object({
19836
+ key: string(),
19837
+ backend: string(),
19838
+ device: string(),
19839
+ format: ModelFormatSchema,
19840
+ runtime: literal("python"),
19841
+ score: number$1(),
19842
+ available: boolean()
19843
+ });
19735
19844
  var PlatformCapabilitiesSchema = object({
19736
19845
  hardware: HardwareInfoSchema,
19737
19846
  scores: array(PlatformScoreSchema).readonly(),
19738
19847
  bestScore: PlatformScoreSchema,
19739
- pythonPath: string().nullable()
19848
+ pythonPath: string().nullable(),
19849
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19740
19850
  });
19741
19851
  var ModelRequirementSchema = object({
19742
19852
  modelId: string(),
@@ -20615,12 +20725,6 @@ Object.freeze({
20615
20725
  addonId: null,
20616
20726
  access: "delete"
20617
20727
  },
20618
- "addons.updateFrameworkPackage": {
20619
- capName: "addons",
20620
- capScope: "system",
20621
- addonId: null,
20622
- access: "create"
20623
- },
20624
20728
  "addons.updatePackage": {
20625
20729
  capName: "addons",
20626
20730
  capScope: "system",
@@ -23393,12 +23497,6 @@ Object.freeze({
23393
23497
  addonId: null,
23394
23498
  access: "view"
23395
23499
  },
23396
- "pipelineExecutor.reprobeEngine": {
23397
- capName: "pipeline-executor",
23398
- capScope: "system",
23399
- addonId: null,
23400
- access: "create"
23401
- },
23402
23500
  "pipelineExecutor.runAudioTest": {
23403
23501
  capName: "pipeline-executor",
23404
23502
  capScope: "system",
@@ -23549,6 +23647,12 @@ Object.freeze({
23549
23647
  addonId: null,
23550
23648
  access: "view"
23551
23649
  },
23650
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23651
+ capName: "pipeline-orchestrator",
23652
+ capScope: "system",
23653
+ addonId: null,
23654
+ access: "view"
23655
+ },
23552
23656
  "pipelineOrchestrator.getPipelineAssignment": {
23553
23657
  capName: "pipeline-orchestrator",
23554
23658
  capScope: "system",
@@ -23561,6 +23665,12 @@ Object.freeze({
23561
23665
  addonId: null,
23562
23666
  access: "view"
23563
23667
  },
23668
+ "pipelineOrchestrator.getPipelineDevicePin": {
23669
+ capName: "pipeline-orchestrator",
23670
+ capScope: "system",
23671
+ addonId: null,
23672
+ access: "view"
23673
+ },
23564
23674
  "pipelineOrchestrator.listAgentSettings": {
23565
23675
  capName: "pipeline-orchestrator",
23566
23676
  capScope: "system",
@@ -23603,19 +23713,19 @@ Object.freeze({
23603
23713
  addonId: null,
23604
23714
  access: "create"
23605
23715
  },
23606
- "pipelineOrchestrator.setAgentAddonDefaults": {
23716
+ "pipelineOrchestrator.setAgentCapabilities": {
23607
23717
  capName: "pipeline-orchestrator",
23608
23718
  capScope: "system",
23609
23719
  addonId: null,
23610
23720
  access: "create"
23611
23721
  },
23612
- "pipelineOrchestrator.setAgentCapabilities": {
23722
+ "pipelineOrchestrator.setAgentDetectWeight": {
23613
23723
  capName: "pipeline-orchestrator",
23614
23724
  capScope: "system",
23615
23725
  addonId: null,
23616
23726
  access: "create"
23617
23727
  },
23618
- "pipelineOrchestrator.setAgentDetectWeight": {
23728
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23619
23729
  capName: "pipeline-orchestrator",
23620
23730
  capScope: "system",
23621
23731
  addonId: null,
@@ -23657,6 +23767,12 @@ Object.freeze({
23657
23767
  addonId: null,
23658
23768
  access: "create"
23659
23769
  },
23770
+ "pipelineOrchestrator.setPipelineDevicePin": {
23771
+ capName: "pipeline-orchestrator",
23772
+ capScope: "system",
23773
+ addonId: null,
23774
+ access: "create"
23775
+ },
23660
23776
  "pipelineOrchestrator.unassignAudio": {
23661
23777
  capName: "pipeline-orchestrator",
23662
23778
  capScope: "system",
@@ -25209,32 +25325,6 @@ Object.freeze({
25209
25325
  "network-access": "ingress",
25210
25326
  "smtp-provider": "email"
25211
25327
  });
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
25328
  //#endregion
25239
25329
  //#region ../../node_modules/readable-stream/lib/ours/primordials.js
25240
25330
  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.0",
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",