camstack 1.1.31 → 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.
@@ -14522,7 +14522,7 @@ function date4(params) {
14522
14522
  // ../../node_modules/zod/v4/classic/external.js
14523
14523
  config(en_default());
14524
14524
 
14525
- // ../types/dist/sleep-D8ZkNoYz.mjs
14525
+ // ../types/dist/sleep-BQ60XlE9.mjs
14526
14526
  var WELL_KNOWN_TABS = [
14527
14527
  {
14528
14528
  id: "overview",
@@ -15389,6 +15389,17 @@ var ModelCatalogEntrySchema = external_exports.object({
15389
15389
  "imagenet",
15390
15390
  "none"
15391
15391
  ]).optional(),
15392
+ /**
15393
+ * The model already applies softmax IN-GRAPH — its raw output is a
15394
+ * probability distribution, not logits. When set, the `softmax`
15395
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
15396
+ * probability vector collapses it toward uniform (top-1 score craters far
15397
+ * below its true value, making every confidence gate meaningless). Absent ⇒
15398
+ * the output is raw logits and the postprocessor applies softmax (the normal
15399
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
15400
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
15401
+ */
15402
+ outputProbabilities: external_exports.boolean().optional(),
15392
15403
  preprocessMode: external_exports.enum(["letterbox", "resize"]).optional(),
15393
15404
  /**
15394
15405
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -19694,20 +19705,6 @@ var pipelineExecutorCapability = {
19694
19705
  getSelectedEngine: method(external_exports.void(), PipelineEngineChoiceSchema),
19695
19706
  getDefaultSteps: method(PipelineEngineChoiceSchema, external_exports.array(PipelineDefaultStepSchema)),
19696
19707
  /**
19697
- * Re-run the platform probe for the inference engine and write the
19698
- * detected runtime / backend / device back into the addon's own
19699
- * global settings store. Returns the engine that was picked so the
19700
- * UI can confirm without a second round-trip. Triggers the standard
19701
- * `requiresRestart` auto-restart flow because all three fields are
19702
- * marked restart-required. Replaces the legacy per-agent
19703
- * `pipeline-orchestrator.reprobeAgentHwAccel` surface for the
19704
- * engine dimension — each addon now owns its own probe.
19705
- */
19706
- reprobeEngine: method(external_exports.void(), PipelineEngineChoiceSchema, {
19707
- kind: "mutation",
19708
- auth: "admin"
19709
- }),
19710
- /**
19711
19708
  * Per-node detection-engine provisioning snapshot. Returns the live
19712
19709
  * state of the lazy runtime-provisioning machine on `nodeId`
19713
19710
  * (idle / installing / verifying / ready / failed). The UI pairs this
@@ -19845,7 +19842,14 @@ var pipelineExecutorCapability = {
19845
19842
  * (inputClasses ≠ null) are skipped and served per-track via
19846
19843
  * pipelineRunner.runDetailSubtree (two-plane design).
19847
19844
  */
19848
- plane: external_exports.enum(["full", "frame"]).optional()
19845
+ plane: external_exports.enum(["full", "frame"]).optional(),
19846
+ /**
19847
+ * Inference-device selector (Phase 2 multi-device). Format
19848
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
19849
+ * Omitted ⇒ the runner's default device (current single-engine
19850
+ * behaviour). Selects WHICH device pool of the node runs the call.
19851
+ */
19852
+ deviceKey: external_exports.string().optional()
19849
19853
  }), PipelineRunResultBridge, { kind: "mutation" }),
19850
19854
  /**
19851
19855
  * Batched run — N raw frames packed into one cap call. The provider
@@ -19863,7 +19867,20 @@ var pipelineExecutorCapability = {
19863
19867
  steps: external_exports.array(PipelineStepInputSchema).min(1),
19864
19868
  frames: external_exports.array(FrameInputSchema).min(1).max(255),
19865
19869
  deviceId: external_exports.number().optional(),
19866
- sessionId: external_exports.string().optional()
19870
+ sessionId: external_exports.string().optional(),
19871
+ /**
19872
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
19873
+ * the batch to the Python pool's bench preprocess cache
19874
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
19875
+ * preprocessed ONCE and every later inference is a pure-inference cache
19876
+ * hit — the sustained-throughput run measures inference, not
19877
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
19878
+ * full preprocess every call, correct). Fresh per sustained run;
19879
+ * released via `uncacheFrame`.
19880
+ */
19881
+ frameId: external_exports.number().int().nonnegative().optional(),
19882
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
19883
+ deviceKey: external_exports.string().optional()
19867
19884
  }), external_exports.object({ results: external_exports.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
19868
19885
  /**
19869
19886
  * Cache a raw frame inside the Python inference pool's memory.
@@ -19920,8 +19937,18 @@ var pipelineExecutorCapability = {
19920
19937
  * - `runtime` — main camera-serving engine (no idle TTL).
19921
19938
  * - `warm-override` — benchmark/test override held in the warm
19922
19939
  * cache; auto-disposed after the idle TTL.
19940
+ * - `device-pool` — a concurrent per-device pool (Phase 2
19941
+ * multi-device, keyed by `deviceKey`) resolved
19942
+ * via `resolveDeviceFactory`. Runs alongside the
19943
+ * `runtime` engine on a DIFFERENT accelerator
19944
+ * (NPU / iGPU / Coral) — this is how the
19945
+ * Engines tab shows all pools running at once.
19923
19946
  */
19924
- kind: external_exports.enum(["runtime", "warm-override"]),
19947
+ kind: external_exports.enum([
19948
+ "runtime",
19949
+ "warm-override",
19950
+ "device-pool"
19951
+ ]),
19925
19952
  /** Native pid of the underlying Python pool (null when no pool). */
19926
19953
  poolPid: external_exports.number().nullable(),
19927
19954
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -20194,7 +20221,14 @@ var RunnerCameraConfigSchema = external_exports.object({
20194
20221
  * camera's detect node differs from its source-owner (P2d, gated by the
20195
20222
  * `remoteSourcingNodes` rollout setting).
20196
20223
  */
20197
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
20224
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
20225
+ /**
20226
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
20227
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
20228
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
20229
+ * this only selects WHICH device pool of that node runs the session.
20230
+ */
20231
+ deviceKey: external_exports.string().optional()
20198
20232
  });
20199
20233
  var RunnerCameraDeviceUIFields = [
20200
20234
  {
@@ -20319,6 +20353,19 @@ var RunnerLocalLoadSchema = external_exports.object({
20319
20353
  avgInferenceTimeMs: external_exports.number(),
20320
20354
  /** Total queue depth across motion + detection queues. */
20321
20355
  queueDepthTotal: external_exports.number(),
20356
+ /**
20357
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
20358
+ * this runner currently has attached cameras on, so the orchestrator's second
20359
+ * `balance()` pass (over a node's devices) weights on real per-pool session
20360
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
20361
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
20362
+ */
20363
+ devices: external_exports.array(external_exports.object({
20364
+ deviceKey: external_exports.string(),
20365
+ backend: external_exports.string(),
20366
+ attachedCameras: external_exports.number(),
20367
+ queueDepthTotal: external_exports.number()
20368
+ })).default([]),
20322
20369
  /** Hardware capability flags reported by this node. */
20323
20370
  hardware: external_exports.object({
20324
20371
  hasGpu: external_exports.boolean(),
@@ -22501,6 +22548,40 @@ var deviceProviderCapability = {
22501
22548
  })
22502
22549
  }
22503
22550
  };
22551
+ var DEVICE_TYPE_CONTROL_KIND = {
22552
+ [DeviceType.Cover]: "cover",
22553
+ [DeviceType.Valve]: "valve",
22554
+ [DeviceType.Humidifier]: "humidifier",
22555
+ [DeviceType.WaterHeater]: "water-heater",
22556
+ [DeviceType.Camera]: "dummy",
22557
+ [DeviceType.Hub]: "dummy",
22558
+ [DeviceType.Switch]: "switch",
22559
+ [DeviceType.Siren]: "switch",
22560
+ [DeviceType.Light]: "light",
22561
+ [DeviceType.Fan]: "fan",
22562
+ [DeviceType.Sensor]: "sensor",
22563
+ [DeviceType.Thermostat]: "thermostat",
22564
+ [DeviceType.Climate]: "climate",
22565
+ [DeviceType.Button]: "button",
22566
+ [DeviceType.EventEmitter]: "dummy",
22567
+ [DeviceType.Update]: "update",
22568
+ [DeviceType.Generic]: "dummy",
22569
+ [DeviceType.Notifier]: "dummy",
22570
+ [DeviceType.Script]: "dummy",
22571
+ [DeviceType.Automation]: "dummy",
22572
+ [DeviceType.Lock]: "lock",
22573
+ [DeviceType.MediaPlayer]: "media-player",
22574
+ [DeviceType.AlarmPanel]: "alarm",
22575
+ [DeviceType.Control]: "control",
22576
+ [DeviceType.Presence]: "sensor",
22577
+ [DeviceType.Weather]: "weather",
22578
+ [DeviceType.Vacuum]: "vacuum",
22579
+ [DeviceType.LawnMower]: "lawn-mower",
22580
+ [DeviceType.Container]: "dummy",
22581
+ [DeviceType.Image]: "image",
22582
+ [DeviceType.PetFeeder]: "pet-feeder"
22583
+ };
22584
+ var DEVICE_TYPE_VALUES = new Set(Object.values(DeviceType));
22504
22585
  var AddonPageDeclarationSchema$1 = external_exports.object({
22505
22586
  id: external_exports.string(),
22506
22587
  label: external_exports.string(),
@@ -26570,13 +26651,11 @@ var PipelineTemplateSchema = external_exports.object({
26570
26651
  createdAt: external_exports.string(),
26571
26652
  updatedAt: external_exports.string()
26572
26653
  });
26573
- var AgentAddonConfigSchema = external_exports.object({
26574
- enabled: external_exports.boolean(),
26654
+ var DeviceStepConfigSchema = external_exports.object({
26575
26655
  modelId: external_exports.string().optional(),
26576
- settings: external_exports.record(external_exports.string(), external_exports.unknown()).readonly()
26656
+ settings: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
26577
26657
  });
26578
26658
  var AgentPipelineSettingsSchema = external_exports.object({
26579
- addonDefaults: external_exports.record(external_exports.string(), AgentAddonConfigSchema).readonly(),
26580
26659
  maxCameras: external_exports.number().int().nonnegative().nullable().default(null),
26581
26660
  /** Per-node detection weight (relative share for the quota balancer). */
26582
26661
  detectWeight: external_exports.number().positive().optional(),
@@ -26600,7 +26679,22 @@ var AgentPipelineSettingsSchema = external_exports.object({
26600
26679
  * it already uses to reach the hub). Set this only when the auto-detected
26601
26680
  * address is wrong (multi-homed host, NAT, custom interface).
26602
26681
  */
26603
- reachableHost: external_exports.string().optional()
26682
+ reachableHost: external_exports.string().optional(),
26683
+ /**
26684
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
26685
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
26686
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
26687
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
26688
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
26689
+ * the default model/settings for every camera landing on that accelerator;
26690
+ * a stepId absent ⇒ the step uses that device's format default.
26691
+ */
26692
+ inferenceDevices: external_exports.record(external_exports.string(), external_exports.object({
26693
+ enabled: external_exports.boolean(),
26694
+ weight: external_exports.number().positive().optional(),
26695
+ maxSessions: external_exports.number().int().positive().optional(),
26696
+ steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
26697
+ })).optional()
26604
26698
  });
26605
26699
  var CameraPipelineForAgentSchema = external_exports.object({
26606
26700
  steps: external_exports.array(PipelineStepInputSchema).readonly(),
@@ -26610,14 +26704,13 @@ var CameraPipelineForAgentSchema = external_exports.object({
26610
26704
  }).nullable()
26611
26705
  });
26612
26706
  var CameraStepOverridePatchSchema = external_exports.object({
26613
- enabled: external_exports.boolean().optional(),
26614
26707
  modelId: external_exports.string().optional(),
26615
26708
  settings: external_exports.record(external_exports.string(), external_exports.unknown()).readonly().optional()
26616
26709
  });
26617
26710
  var CameraPipelineSettingsSchema = external_exports.object({
26618
26711
  pinnedAgentNodeId: external_exports.string().optional(),
26619
26712
  stepToggles: external_exports.record(external_exports.string(), external_exports.boolean()).optional(),
26620
- stepOverridesByAgent: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema)).optional(),
26713
+ stepOverridesByDevice: external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema))).optional(),
26621
26714
  pipelineByAgent: external_exports.record(external_exports.string(), CameraPipelineForAgentSchema).optional()
26622
26715
  });
26623
26716
  var PipelineAssignmentSchema = external_exports.object({
@@ -26783,6 +26876,44 @@ var CameraStatusSchema = external_exports.object({
26783
26876
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
26784
26877
  fetchedAt: external_exports.number()
26785
26878
  });
26879
+ var NodeInferenceDeviceSchema = external_exports.object({
26880
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
26881
+ key: external_exports.string(),
26882
+ backend: external_exports.string(),
26883
+ device: external_exports.string(),
26884
+ format: external_exports.enum(MODEL_FORMATS),
26885
+ /** Whether the node's live probe reports the device as usable right now. */
26886
+ available: external_exports.boolean(),
26887
+ /**
26888
+ * Whether this device participates in dispatch. AUTO default (spec C2):
26889
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
26890
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
26891
+ * not a balanced target). An explicit stored value always wins; a stored-only
26892
+ * (unavailable) key keeps its stored value.
26893
+ */
26894
+ enabled: external_exports.boolean(),
26895
+ /** Relative balancer weight for the enabled device (default 1). */
26896
+ weight: external_exports.number(),
26897
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
26898
+ maxSessions: external_exports.number().nullable(),
26899
+ /** Object-detection model the executor defaults to for this deviceKey. */
26900
+ defaultModelId: external_exports.string(),
26901
+ /**
26902
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
26903
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
26904
+ * Absent/empty ⇒ no base (every step uses its device format default). The
26905
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
26906
+ * available per format; this is the stored selection that becomes the
26907
+ * default for EVERY camera landing on this accelerator.
26908
+ */
26909
+ steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
26910
+ });
26911
+ var NodeInferenceDevicesSchema = external_exports.object({
26912
+ nodeId: external_exports.string(),
26913
+ /** False when the node's platform-probe was unreachable (no live device set). */
26914
+ reachable: external_exports.boolean(),
26915
+ devices: external_exports.array(NodeInferenceDeviceSchema).readonly()
26916
+ });
26786
26917
  var pipelineOrchestratorCapability = {
26787
26918
  name: "pipeline-orchestrator",
26788
26919
  scope: "system",
@@ -26820,6 +26951,34 @@ var pipelineOrchestratorCapability = {
26820
26951
  auth: "admin"
26821
26952
  }),
26822
26953
  /**
26954
+ * Pin a camera's detection to a specific INFERENCE DEVICE (accelerator)
26955
+ * within its node — a SOFT L1 device affinity honoured by the per-session
26956
+ * device `balance()` pass (sibling of the node-level `pipelineNodeId` pin;
26957
+ * persisted as `pipelineDeviceKey` in the device store, read by
26958
+ * `readPipelineDevicePin`). `deviceKey` is a concrete key
26959
+ * (`openvino:npu` / `edgetpu:usb` / `cpu`), or the `'auto'` sentinel /
26960
+ * empty string to CLEAR the pin and let the balancer pick the device.
26961
+ *
26962
+ * Applies promptly: the device is chosen per-session at dispatch, so any
26963
+ * running detection session is closed and re-dispatched onto the new pin
26964
+ * (the camera stays on the SAME node — a device pin never moves the camera).
26965
+ * Cameras with no active session pick it up on their next dispatch.
26966
+ */
26967
+ setPipelineDevicePin: method(external_exports.object({
26968
+ deviceId: external_exports.number(),
26969
+ deviceKey: external_exports.string()
26970
+ }), external_exports.object({ success: external_exports.literal(true) }), {
26971
+ kind: "mutation",
26972
+ auth: "admin"
26973
+ }),
26974
+ /**
26975
+ * Read a camera's persisted inference-device pin (`pipelineDeviceKey`).
26976
+ * Returns the concrete device key, or `null` when unpinned (auto). Lets the
26977
+ * UI show the current pin alongside the node pin (parity with the node-pin
26978
+ * value carried on the assignment record).
26979
+ */
26980
+ getPipelineDevicePin: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.object({ deviceKey: external_exports.string().nullable() })),
26981
+ /**
26823
26982
  * Trigger a full rebalance pass. Iterates over all assigned cameras,
26824
26983
  * recomputes the optimal agent for each one based on current load +
26825
26984
  * hardware affinity, and migrates cameras whose current agent is no
@@ -26904,14 +27063,6 @@ var pipelineOrchestratorCapability = {
26904
27063
  nodeId: external_exports.string(),
26905
27064
  settings: AgentPipelineSettingsSchema
26906
27065
  })).readonly()),
26907
- /** Bulk-replace ALL addon configs on one agent. Used by the agent-level PipelineEditor which emits the full map per edit. Merges on top of existing entries — omitted addonIds are left alone. */
26908
- setAgentAddonDefaults: method(external_exports.object({
26909
- agentNodeId: external_exports.string(),
26910
- defaults: external_exports.record(external_exports.string(), AgentAddonConfigSchema)
26911
- }), external_exports.object({ success: external_exports.literal(true) }), {
26912
- kind: "mutation",
26913
- auth: "admin"
26914
- }),
26915
27066
  /**
26916
27067
  * Drop a single agent's persisted settings. Used by the cluster
26917
27068
  * "Offline agents" panel to evict stale entries left behind when an
@@ -26998,6 +27149,46 @@ var pipelineOrchestratorCapability = {
26998
27149
  auth: "admin"
26999
27150
  }),
27000
27151
  /**
27152
+ * Set one node's multi-device inference opt-in (Phase 4 multi-device) — the
27153
+ * per-node `deviceKey → { enabled, weight }` map that decides which
27154
+ * accelerators the dispatcher may balance detection sessions across.
27155
+ * The map REPLACES the node's stored `inferenceDevices` wholesale (pass the
27156
+ * complete desired set; an empty map clears the opt-in → the node reverts to
27157
+ * its single DEFAULT accelerator). `weight` is optional and defaults to 1.
27158
+ * `models` is the optional per-device model override (`stepId → modelId`,
27159
+ * C7.2/C7.4) — a stepId absent ⇒ the step uses that device's default model.
27160
+ * Creates the node's settings entry if absent. Changes take effect on the
27161
+ * next dispatch/rebalance cycle — the dispatcher reads the enabled set via
27162
+ * `PipelineSettingsStore.buildNodeInferenceDevices` when placing sessions
27163
+ * and the per-(node,device) base provisioning via
27164
+ * `buildNodeInferenceDeviceSteps`.
27165
+ */
27166
+ setAgentInferenceDevices: method(external_exports.object({
27167
+ agentNodeId: external_exports.string(),
27168
+ inferenceDevices: external_exports.record(external_exports.string(), external_exports.object({
27169
+ enabled: external_exports.boolean(),
27170
+ weight: external_exports.number().positive().optional(),
27171
+ maxSessions: external_exports.number().int().positive().optional(),
27172
+ steps: external_exports.record(external_exports.string(), DeviceStepConfigSchema).optional()
27173
+ }))
27174
+ }), external_exports.object({ success: external_exports.literal(true) }), {
27175
+ kind: "mutation",
27176
+ auth: "admin"
27177
+ }),
27178
+ /**
27179
+ * DEVICE-AWARE merged view of ONE node's inference accelerators. Joins each
27180
+ * physical device the node HAS — probed live via a node-pinned
27181
+ * `platformProbe.getCapabilities` (the platform-probe singleton is targeted
27182
+ * by the `nodeId` cap INPUT, since a `nodePin` context is ignored by a
27183
+ * singleton mount) — with its stored opt-in (`enabled`/`weight`) and the
27184
+ * object-detection `defaultModelId` the executor would run for that
27185
+ * deviceKey. Disabled-but-configured keys still appear. An unreachable node
27186
+ * returns `reachable:false` + best-effort stored-only devices (never
27187
+ * throws). Read surface for the cluster/agent multi-device UI — hence a
27188
+ * default (read-level) auth, matching the other `getAgent*` reads.
27189
+ */
27190
+ getNodeInferenceDevices: method(external_exports.object({ nodeId: external_exports.string() }), NodeInferenceDevicesSchema),
27191
+ /**
27001
27192
  * Reset one node's pipeline to its hardware-aware defaults — the HONEST
27002
27193
  * reset (replaces the executor's legacy `resetToDefault`, which cleared a
27003
27194
  * dead persisted step-tree seed nothing in the live path read):
@@ -27036,15 +27227,18 @@ var pipelineOrchestratorCapability = {
27036
27227
  kind: "mutation",
27037
27228
  auth: "admin"
27038
27229
  }),
27039
- /** Read every L2.5 override map for a device. Null when device has no overrides. */
27040
- getCameraStepOverrides: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema)).nullable()),
27230
+ /** Read every per-(node,device) override map for a device. Null when device has no overrides. */
27231
+ getCameraStepOverrides: method(external_exports.object({ deviceId: external_exports.number() }), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), external_exports.record(external_exports.string(), CameraStepOverridePatchSchema))).nullable()),
27041
27232
  /**
27042
- * Write or clear the L2.5 per-agent override for one addonId on a device.
27043
- * `patch: null` clears the entry entirely for that (agent, addon) pair.
27233
+ * Write or clear the per-(camera,node,device) override for one addonId.
27234
+ * `patch: null` clears the entry entirely for that (node, deviceKey, addon)
27235
+ * triple (empty parents are pruned). Model/settings only — enablement is
27236
+ * the per-camera `stepToggles` authority.
27044
27237
  */
27045
27238
  setCameraStepOverride: method(external_exports.object({
27046
27239
  deviceId: external_exports.number(),
27047
27240
  agentNodeId: external_exports.string(),
27241
+ deviceKey: external_exports.string(),
27048
27242
  addonId: external_exports.string(),
27049
27243
  patch: CameraStepOverridePatchSchema.nullable()
27050
27244
  }), external_exports.object({ success: external_exports.literal(true) }), {
@@ -27197,7 +27391,8 @@ var serverManagementCapability = {
27197
27391
  version: external_exports.string().optional()
27198
27392
  }), ServerUpdateActionResultSchema, {
27199
27393
  kind: "mutation",
27200
- auth: "admin"
27394
+ auth: "admin",
27395
+ timeoutMs: 16 * 6e4
27201
27396
  }),
27202
27397
  rollbackServerUpdate: method(external_exports.void(), ServerUpdateActionResultSchema, {
27203
27398
  kind: "mutation",
@@ -28389,13 +28584,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
28389
28584
  var RestartAddonResultSchema = external_exports.unknown();
28390
28585
  var InstallPackageResultSchema = external_exports.unknown();
28391
28586
  var ReloadPackagesResultSchema = external_exports.unknown();
28392
- var UpdateFrameworkPackageResultSchema = external_exports.object({
28393
- packageName: external_exports.string(),
28394
- fromVersion: external_exports.string(),
28395
- toVersion: external_exports.string(),
28396
- /** Ms-epoch the server scheduled its self-restart. */
28397
- restartingAt: external_exports.number()
28398
- });
28399
28587
  var BulkUpdateItemStatusSchema = external_exports.enum([
28400
28588
  "queued",
28401
28589
  "updating",
@@ -28623,28 +28811,6 @@ var addonsCapability = {
28623
28811
  kind: "mutation",
28624
28812
  auth: "admin"
28625
28813
  }),
28626
- /**
28627
- * Live-update one of the framework packages marked
28628
- * `camstack.system: true` (`@camstack/types|kernel|core|sdk|ui-library`).
28629
- * Runs `npm install --prefix <appRoot> <name>@<version> --no-save`,
28630
- * writes a `.restart-pending` marker, emits `system.restarting`
28631
- * and schedules a graceful process exit. The supervisor (Docker /
28632
- * Electron / systemd) brings the hub back up; on first boot after
28633
- * the restart the marker fires `system.restart-completed`.
28634
- *
28635
- * `version` defaults to `'latest'`. The allow-list of valid
28636
- * `packageName` values is enforced server-side.
28637
- *
28638
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
28639
- */
28640
- updateFrameworkPackage: method(external_exports.object({
28641
- packageName: external_exports.string().min(1),
28642
- version: external_exports.string().optional(),
28643
- deferRestart: external_exports.boolean().optional()
28644
- }), UpdateFrameworkPackageResultSchema, {
28645
- kind: "mutation",
28646
- auth: "admin"
28647
- }),
28648
28814
  getVersions: method(external_exports.object({ name: external_exports.string() }), external_exports.array(PackageVersionInfoSchema).readonly()),
28649
28815
  restartAddon: method(external_exports.object({ addonId: external_exports.string() }), RestartAddonResultSchema, {
28650
28816
  kind: "mutation",
@@ -30140,17 +30306,28 @@ var PlatformScoreSchema = external_exports.object({
30140
30306
  format: external_exports.enum([
30141
30307
  "onnx",
30142
30308
  "coreml",
30143
- "openvino"
30309
+ "openvino",
30310
+ "tflite"
30144
30311
  ]),
30145
30312
  score: external_exports.number(),
30146
30313
  reason: external_exports.string(),
30147
30314
  available: external_exports.boolean()
30148
30315
  });
30316
+ var InferenceDeviceDescriptorSchema = external_exports.object({
30317
+ key: external_exports.string(),
30318
+ backend: external_exports.string(),
30319
+ device: external_exports.string(),
30320
+ format: ModelFormatSchema,
30321
+ runtime: external_exports.literal("python"),
30322
+ score: external_exports.number(),
30323
+ available: external_exports.boolean()
30324
+ });
30149
30325
  var PlatformCapabilitiesSchema = external_exports.object({
30150
30326
  hardware: HardwareInfoSchema,
30151
30327
  scores: external_exports.array(PlatformScoreSchema).readonly(),
30152
30328
  bestScore: PlatformScoreSchema,
30153
- pythonPath: external_exports.string().nullable()
30329
+ pythonPath: external_exports.string().nullable(),
30330
+ devices: external_exports.array(InferenceDeviceDescriptorSchema).readonly()
30154
30331
  });
30155
30332
  var ModelRequirementSchema = external_exports.object({
30156
30333
  modelId: external_exports.string(),
@@ -31122,12 +31299,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
31122
31299
  addonId: null,
31123
31300
  access: "delete"
31124
31301
  },
31125
- "addons.updateFrameworkPackage": {
31126
- capName: "addons",
31127
- capScope: "system",
31128
- addonId: null,
31129
- access: "create"
31130
- },
31131
31302
  "addons.updatePackage": {
31132
31303
  capName: "addons",
31133
31304
  capScope: "system",
@@ -33900,12 +34071,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
33900
34071
  addonId: null,
33901
34072
  access: "view"
33902
34073
  },
33903
- "pipelineExecutor.reprobeEngine": {
33904
- capName: "pipeline-executor",
33905
- capScope: "system",
33906
- addonId: null,
33907
- access: "create"
33908
- },
33909
34074
  "pipelineExecutor.runAudioTest": {
33910
34075
  capName: "pipeline-executor",
33911
34076
  capScope: "system",
@@ -34056,6 +34221,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34056
34221
  addonId: null,
34057
34222
  access: "view"
34058
34223
  },
34224
+ "pipelineOrchestrator.getNodeInferenceDevices": {
34225
+ capName: "pipeline-orchestrator",
34226
+ capScope: "system",
34227
+ addonId: null,
34228
+ access: "view"
34229
+ },
34059
34230
  "pipelineOrchestrator.getPipelineAssignment": {
34060
34231
  capName: "pipeline-orchestrator",
34061
34232
  capScope: "system",
@@ -34068,6 +34239,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34068
34239
  addonId: null,
34069
34240
  access: "view"
34070
34241
  },
34242
+ "pipelineOrchestrator.getPipelineDevicePin": {
34243
+ capName: "pipeline-orchestrator",
34244
+ capScope: "system",
34245
+ addonId: null,
34246
+ access: "view"
34247
+ },
34071
34248
  "pipelineOrchestrator.listAgentSettings": {
34072
34249
  capName: "pipeline-orchestrator",
34073
34250
  capScope: "system",
@@ -34110,19 +34287,19 @@ var METHOD_ACCESS_MAP = Object.freeze({
34110
34287
  addonId: null,
34111
34288
  access: "create"
34112
34289
  },
34113
- "pipelineOrchestrator.setAgentAddonDefaults": {
34290
+ "pipelineOrchestrator.setAgentCapabilities": {
34114
34291
  capName: "pipeline-orchestrator",
34115
34292
  capScope: "system",
34116
34293
  addonId: null,
34117
34294
  access: "create"
34118
34295
  },
34119
- "pipelineOrchestrator.setAgentCapabilities": {
34296
+ "pipelineOrchestrator.setAgentDetectWeight": {
34120
34297
  capName: "pipeline-orchestrator",
34121
34298
  capScope: "system",
34122
34299
  addonId: null,
34123
34300
  access: "create"
34124
34301
  },
34125
- "pipelineOrchestrator.setAgentDetectWeight": {
34302
+ "pipelineOrchestrator.setAgentInferenceDevices": {
34126
34303
  capName: "pipeline-orchestrator",
34127
34304
  capScope: "system",
34128
34305
  addonId: null,
@@ -34164,6 +34341,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
34164
34341
  addonId: null,
34165
34342
  access: "create"
34166
34343
  },
34344
+ "pipelineOrchestrator.setPipelineDevicePin": {
34345
+ capName: "pipeline-orchestrator",
34346
+ capScope: "system",
34347
+ addonId: null,
34348
+ access: "create"
34349
+ },
34167
34350
  "pipelineOrchestrator.unassignAudio": {
34168
34351
  capName: "pipeline-orchestrator",
34169
34352
  capScope: "system",
@@ -35716,32 +35899,6 @@ var CAP_PROVIDER_KIND_MAP = Object.freeze({
35716
35899
  "network-access": "ingress",
35717
35900
  "smtp-provider": "email"
35718
35901
  });
35719
- var frameworkSwapPackageSchema = external_exports.object({
35720
- name: external_exports.string(),
35721
- stagedPath: external_exports.string(),
35722
- backupPath: external_exports.string(),
35723
- toVersion: external_exports.string(),
35724
- fromVersion: external_exports.string().nullable()
35725
- });
35726
- var pendingFrameworkSwapSchema = external_exports.object({
35727
- jobId: external_exports.string(),
35728
- taskId: external_exports.string(),
35729
- packages: external_exports.array(frameworkSwapPackageSchema),
35730
- requestedAtMs: external_exports.number(),
35731
- schemaVersion: external_exports.literal(1)
35732
- });
35733
- var frameworkSwapConfirmSchema = external_exports.object({
35734
- jobId: external_exports.string(),
35735
- taskId: external_exports.string(),
35736
- backups: external_exports.array(external_exports.object({
35737
- name: external_exports.string(),
35738
- backupPath: external_exports.string(),
35739
- livePath: external_exports.string()
35740
- })),
35741
- appliedAtMs: external_exports.number(),
35742
- bootAttempts: external_exports.number(),
35743
- schemaVersion: external_exports.literal(1)
35744
- });
35745
35902
 
35746
35903
  // src/commands/discover.ts
35747
35904
  var DEFAULT_MULTICAST_GROUP = "239.0.0.0";
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-ZFONIXEK.js";
4
+ } from "./chunk-LQUCPQ55.js";
5
5
  import "./chunk-K3NQKI34.js";
6
6
 
7
7
  // src/cli.ts
@@ -1079,7 +1079,7 @@ function isUnknown(_value) {
1079
1079
  return true;
1080
1080
  }
1081
1081
  async function resolveServerInteractive(presetNamespace) {
1082
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-ZBSZJQ2R.js");
1082
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-GAE4KR5T.js");
1083
1083
  if (presetNamespace) {
1084
1084
  const spinner4 = clack.spinner();
1085
1085
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-ZFONIXEK.js";
8
+ } from "./chunk-LQUCPQ55.js";
9
9
  import "./chunk-K3NQKI34.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.1.31",
3
+ "version": "1.2.0",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",