@camstack/addon-provider-wyze 0.1.25 → 0.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.
Files changed (3) hide show
  1. package/dist/addon.js +193 -103
  2. package/dist/addon.mjs +193 -103
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -7115,6 +7115,17 @@ var ModelCatalogEntrySchema = object({
7115
7115
  "imagenet",
7116
7116
  "none"
7117
7117
  ]).optional(),
7118
+ /**
7119
+ * The model already applies softmax IN-GRAPH — its raw output is a
7120
+ * probability distribution, not logits. When set, the `softmax`
7121
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7122
+ * probability vector collapses it toward uniform (top-1 score craters far
7123
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7124
+ * the output is raw logits and the postprocessor applies softmax (the normal
7125
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7126
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7127
+ */
7128
+ outputProbabilities: boolean().optional(),
7118
7129
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7119
7130
  /**
7120
7131
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -12405,10 +12416,7 @@ var ConfigUISchemaNullableBridge = custom();
12405
12416
  var InferenceCapabilitiesBridge = custom();
12406
12417
  var ModelAvailabilityListBridge = custom();
12407
12418
  var PipelineRunResultBridge = custom();
12408
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
12409
- kind: "mutation",
12410
- auth: "admin"
12411
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
12419
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
12412
12420
  modelId: string(),
12413
12421
  settings: record(string(), unknown()).readonly()
12414
12422
  }))), method(object({ steps: record(string(), object({
@@ -12468,13 +12476,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12468
12476
  * (inputClasses ≠ null) are skipped and served per-track via
12469
12477
  * pipelineRunner.runDetailSubtree (two-plane design).
12470
12478
  */
12471
- plane: _enum(["full", "frame"]).optional()
12479
+ plane: _enum(["full", "frame"]).optional(),
12480
+ /**
12481
+ * Inference-device selector (Phase 2 multi-device). Format
12482
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
12483
+ * Omitted ⇒ the runner's default device (current single-engine
12484
+ * behaviour). Selects WHICH device pool of the node runs the call.
12485
+ */
12486
+ deviceKey: string().optional()
12472
12487
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
12473
12488
  engine: PipelineEngineChoiceSchema.optional(),
12474
12489
  steps: array(PipelineStepInputSchema).min(1),
12475
12490
  frames: array(FrameInputSchema).min(1).max(255),
12476
12491
  deviceId: number().optional(),
12477
- sessionId: string().optional()
12492
+ sessionId: string().optional(),
12493
+ /**
12494
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
12495
+ * the batch to the Python pool's bench preprocess cache
12496
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
12497
+ * preprocessed ONCE and every later inference is a pure-inference cache
12498
+ * hit — the sustained-throughput run measures inference, not
12499
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
12500
+ * full preprocess every call, correct). Fresh per sustained run;
12501
+ * released via `uncacheFrame`.
12502
+ */
12503
+ frameId: number().int().nonnegative().optional(),
12504
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
12505
+ deviceKey: string().optional()
12478
12506
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
12479
12507
  data: _instanceof(Uint8Array),
12480
12508
  width: number().int().positive(),
@@ -12506,8 +12534,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12506
12534
  * - `runtime` — main camera-serving engine (no idle TTL).
12507
12535
  * - `warm-override` — benchmark/test override held in the warm
12508
12536
  * cache; auto-disposed after the idle TTL.
12537
+ * - `device-pool` — a concurrent per-device pool (Phase 2
12538
+ * multi-device, keyed by `deviceKey`) resolved
12539
+ * via `resolveDeviceFactory`. Runs alongside the
12540
+ * `runtime` engine on a DIFFERENT accelerator
12541
+ * (NPU / iGPU / Coral) — this is how the
12542
+ * Engines tab shows all pools running at once.
12509
12543
  */
12510
- kind: _enum(["runtime", "warm-override"]),
12544
+ kind: _enum([
12545
+ "runtime",
12546
+ "warm-override",
12547
+ "device-pool"
12548
+ ]),
12511
12549
  /** Native pid of the underlying Python pool (null when no pool). */
12512
12550
  poolPid: number().nullable(),
12513
12551
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -12882,7 +12920,14 @@ var RunnerCameraConfigSchema = object({
12882
12920
  * camera's detect node differs from its source-owner (P2d, gated by the
12883
12921
  * `remoteSourcingNodes` rollout setting).
12884
12922
  */
12885
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
12923
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
12924
+ /**
12925
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
12926
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
12927
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
12928
+ * this only selects WHICH device pool of that node runs the session.
12929
+ */
12930
+ deviceKey: string().optional()
12886
12931
  });
12887
12932
  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;
12888
12933
  /**
@@ -12903,6 +12948,19 @@ var RunnerLocalLoadSchema = object({
12903
12948
  avgInferenceTimeMs: number(),
12904
12949
  /** Total queue depth across motion + detection queues. */
12905
12950
  queueDepthTotal: number(),
12951
+ /**
12952
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
12953
+ * this runner currently has attached cameras on, so the orchestrator's second
12954
+ * `balance()` pass (over a node's devices) weights on real per-pool session
12955
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
12956
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
12957
+ */
12958
+ devices: array(object({
12959
+ deviceKey: string(),
12960
+ backend: string(),
12961
+ attachedCameras: number(),
12962
+ queueDepthTotal: number()
12963
+ })).default([]),
12906
12964
  /** Hardware capability flags reported by this node. */
12907
12965
  hardware: object({
12908
12966
  hasGpu: boolean(),
@@ -16051,6 +16109,8 @@ var BaseDeviceProvider = class extends BaseAddon {
16051
16109
  return toDeviceSummary(device, this.addonId);
16052
16110
  }
16053
16111
  };
16112
+ 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;
16113
+ new Set(Object.values(DeviceType));
16054
16114
  /**
16055
16115
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
16056
16116
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -19737,13 +19797,11 @@ var PipelineTemplateSchema = object({
19737
19797
  createdAt: string(),
19738
19798
  updatedAt: string()
19739
19799
  });
19740
- var AgentAddonConfigSchema = object({
19741
- enabled: boolean(),
19800
+ var DeviceStepConfigSchema = object({
19742
19801
  modelId: string().optional(),
19743
- settings: record(string(), unknown()).readonly()
19802
+ settings: record(string(), unknown()).optional()
19744
19803
  });
19745
19804
  var AgentPipelineSettingsSchema = object({
19746
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
19747
19805
  maxCameras: number().int().nonnegative().nullable().default(null),
19748
19806
  /** Per-node detection weight (relative share for the quota balancer). */
19749
19807
  detectWeight: number().positive().optional(),
@@ -19767,7 +19825,22 @@ var AgentPipelineSettingsSchema = object({
19767
19825
  * it already uses to reach the hub). Set this only when the auto-detected
19768
19826
  * address is wrong (multi-homed host, NAT, custom interface).
19769
19827
  */
19770
- reachableHost: string().optional()
19828
+ reachableHost: string().optional(),
19829
+ /**
19830
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
19831
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
19832
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
19833
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
19834
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
19835
+ * the default model/settings for every camera landing on that accelerator;
19836
+ * a stepId absent ⇒ the step uses that device's format default.
19837
+ */
19838
+ inferenceDevices: record(string(), object({
19839
+ enabled: boolean(),
19840
+ weight: number().positive().optional(),
19841
+ maxSessions: number().int().positive().optional(),
19842
+ steps: record(string(), DeviceStepConfigSchema).optional()
19843
+ })).optional()
19771
19844
  });
19772
19845
  var CameraPipelineForAgentSchema = object({
19773
19846
  steps: array(PipelineStepInputSchema).readonly(),
@@ -19777,14 +19850,13 @@ var CameraPipelineForAgentSchema = object({
19777
19850
  }).nullable()
19778
19851
  });
19779
19852
  var CameraStepOverridePatchSchema = object({
19780
- enabled: boolean().optional(),
19781
19853
  modelId: string().optional(),
19782
19854
  settings: record(string(), unknown()).readonly().optional()
19783
19855
  });
19784
19856
  var CameraPipelineSettingsSchema = object({
19785
19857
  pinnedAgentNodeId: string().optional(),
19786
19858
  stepToggles: record(string(), boolean()).optional(),
19787
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
19859
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
19788
19860
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
19789
19861
  });
19790
19862
  /**
@@ -19998,6 +20070,44 @@ var CameraStatusSchema = object({
19998
20070
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
19999
20071
  fetchedAt: number()
20000
20072
  });
20073
+ var NodeInferenceDeviceSchema = object({
20074
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
20075
+ key: string(),
20076
+ backend: string(),
20077
+ device: string(),
20078
+ format: _enum(MODEL_FORMATS),
20079
+ /** Whether the node's live probe reports the device as usable right now. */
20080
+ available: boolean(),
20081
+ /**
20082
+ * Whether this device participates in dispatch. AUTO default (spec C2):
20083
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
20084
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
20085
+ * not a balanced target). An explicit stored value always wins; a stored-only
20086
+ * (unavailable) key keeps its stored value.
20087
+ */
20088
+ enabled: boolean(),
20089
+ /** Relative balancer weight for the enabled device (default 1). */
20090
+ weight: number(),
20091
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
20092
+ maxSessions: number().nullable(),
20093
+ /** Object-detection model the executor defaults to for this deviceKey. */
20094
+ defaultModelId: string(),
20095
+ /**
20096
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
20097
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
20098
+ * Absent/empty ⇒ no base (every step uses its device format default). The
20099
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
20100
+ * available per format; this is the stored selection that becomes the
20101
+ * default for EVERY camera landing on this accelerator.
20102
+ */
20103
+ steps: record(string(), DeviceStepConfigSchema).optional()
20104
+ });
20105
+ var NodeInferenceDevicesSchema = object({
20106
+ nodeId: string(),
20107
+ /** False when the node's platform-probe was unreachable (no live device set). */
20108
+ reachable: boolean(),
20109
+ devices: array(NodeInferenceDeviceSchema).readonly()
20110
+ });
20001
20111
  method(object({
20002
20112
  deviceId: number(),
20003
20113
  agentNodeId: string()
@@ -20007,7 +20117,13 @@ method(object({
20007
20117
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
20008
20118
  kind: "mutation",
20009
20119
  auth: "admin"
20010
- }), method(_void(), object({ migrated: number() }), {
20120
+ }), method(object({
20121
+ deviceId: number(),
20122
+ deviceKey: string()
20123
+ }), object({ success: literal(true) }), {
20124
+ kind: "mutation",
20125
+ auth: "admin"
20126
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
20011
20127
  kind: "mutation",
20012
20128
  auth: "admin"
20013
20129
  }), method(_void(), array(PipelineAssignmentSchema).readonly()), method(object({ deviceId: number() }), PipelineAssignmentSchema.nullable()), method(_void(), array(AgentLoadSummarySchema).readonly()), method(_void(), GlobalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(object({ nodeId: string() }), CapabilityBindingsSchema), method(object({
@@ -20041,13 +20157,7 @@ method(object({
20041
20157
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
20042
20158
  nodeId: string(),
20043
20159
  settings: AgentPipelineSettingsSchema
20044
- })).readonly()), method(object({
20045
- agentNodeId: string(),
20046
- defaults: record(string(), AgentAddonConfigSchema)
20047
- }), object({ success: literal(true) }), {
20048
- kind: "mutation",
20049
- auth: "admin"
20050
- }), method(object({ agentNodeId: string() }), object({
20160
+ })).readonly()), method(object({ agentNodeId: string() }), object({
20051
20161
  success: boolean(),
20052
20162
  removed: boolean()
20053
20163
  }), {
@@ -20079,7 +20189,18 @@ method(object({
20079
20189
  }), object({ success: literal(true) }), {
20080
20190
  kind: "mutation",
20081
20191
  auth: "admin"
20082
- }), method(object({ agentNodeId: string() }), object({
20192
+ }), method(object({
20193
+ agentNodeId: string(),
20194
+ inferenceDevices: record(string(), object({
20195
+ enabled: boolean(),
20196
+ weight: number().positive().optional(),
20197
+ maxSessions: number().int().positive().optional(),
20198
+ steps: record(string(), DeviceStepConfigSchema).optional()
20199
+ }))
20200
+ }), object({ success: literal(true) }), {
20201
+ kind: "mutation",
20202
+ auth: "admin"
20203
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
20083
20204
  success: literal(true),
20084
20205
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
20085
20206
  effectiveModelId: string().nullable(),
@@ -20095,9 +20216,10 @@ method(object({
20095
20216
  }), object({ success: literal(true) }), {
20096
20217
  kind: "mutation",
20097
20218
  auth: "admin"
20098
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
20219
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
20099
20220
  deviceId: number(),
20100
20221
  agentNodeId: string(),
20222
+ deviceKey: string(),
20101
20223
  addonId: string(),
20102
20224
  patch: CameraStepOverridePatchSchema.nullable()
20103
20225
  }), object({ success: literal(true) }), {
@@ -20134,14 +20256,13 @@ method(object({
20134
20256
  });
20135
20257
  /**
20136
20258
  * server-management — per-NODE singleton capability for a node's ROOT
20137
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
20138
- * agents).
20259
+ * package lifecycle (runtime-updatable node packages).
20139
20260
  *
20140
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
20141
- * on agents) carries the whole software stack in its npm dep tree, so ONE
20142
- * version describes the node. Updates install into
20143
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
20144
- * starter (probation boot + auto-rollback to N-1).
20261
+ * Every node role runs the SAME root package (`@camstack/server`), which
20262
+ * carries the whole software stack in its npm dep tree, so ONE version
20263
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
20264
+ * on restart via the baked starter (single-copy in-place swap — no probation,
20265
+ * no auto-rollback).
20145
20266
  *
20146
20267
  * Providers:
20147
20268
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -20249,7 +20370,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
20249
20370
  /** Explicit target version; omitted = latest from the registry. */
20250
20371
  version: string().optional() }), ServerUpdateActionResultSchema, {
20251
20372
  kind: "mutation",
20252
- auth: "admin"
20373
+ auth: "admin",
20374
+ timeoutMs: 16 * 6e4
20253
20375
  }), method(_void(), ServerUpdateActionResultSchema, {
20254
20376
  kind: "mutation",
20255
20377
  auth: "admin"
@@ -21344,22 +21466,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
21344
21466
  var RestartAddonResultSchema = unknown();
21345
21467
  var InstallPackageResultSchema = unknown();
21346
21468
  var ReloadPackagesResultSchema = unknown();
21347
- /**
21348
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
21349
- * server restarts so the admin UI can react to the `restartingAt`
21350
- * timestamp (shows reconnect overlay). The transition from
21351
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
21352
- * `system.restart-completed` event after the new process boots.
21353
- *
21354
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
21355
- */
21356
- var UpdateFrameworkPackageResultSchema = object({
21357
- packageName: string(),
21358
- fromVersion: string(),
21359
- toVersion: string(),
21360
- /** Ms-epoch the server scheduled its self-restart. */
21361
- restartingAt: number()
21362
- });
21363
21469
  var BulkUpdateItemStatusSchema = _enum([
21364
21470
  "queued",
21365
21471
  "updating",
@@ -21487,13 +21593,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
21487
21593
  }), object({ success: literal(true) }), {
21488
21594
  kind: "mutation",
21489
21595
  auth: "admin"
21490
- }), method(object({
21491
- packageName: string().min(1),
21492
- version: string().optional(),
21493
- deferRestart: boolean().optional()
21494
- }), UpdateFrameworkPackageResultSchema, {
21495
- kind: "mutation",
21496
- auth: "admin"
21497
21596
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
21498
21597
  kind: "mutation",
21499
21598
  auth: "admin"
@@ -22410,10 +22509,10 @@ var TopologyCategorySchema = object({
22410
22509
  addons: array(TopologyCategoryAddonSchema).readonly()
22411
22510
  });
22412
22511
  /**
22413
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
22414
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
22415
- * version visibility for the Server management surface. Nullable: offline
22416
- * rows and pre-phase-2 nodes report none.
22512
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
22513
+ * root package for every node role) as reported by its `registerNode`
22514
+ * manifest — version visibility for the Server management surface. Nullable:
22515
+ * offline rows and nodes that never reported one.
22417
22516
  */
22418
22517
  var TopologyRootPackageSchema = object({
22419
22518
  name: string(),
@@ -22801,17 +22900,28 @@ var PlatformScoreSchema = object({
22801
22900
  format: _enum([
22802
22901
  "onnx",
22803
22902
  "coreml",
22804
- "openvino"
22903
+ "openvino",
22904
+ "tflite"
22805
22905
  ]),
22806
22906
  score: number(),
22807
22907
  reason: string(),
22808
22908
  available: boolean()
22809
22909
  });
22910
+ var InferenceDeviceDescriptorSchema = object({
22911
+ key: string(),
22912
+ backend: string(),
22913
+ device: string(),
22914
+ format: ModelFormatSchema,
22915
+ runtime: literal("python"),
22916
+ score: number(),
22917
+ available: boolean()
22918
+ });
22810
22919
  var PlatformCapabilitiesSchema = object({
22811
22920
  hardware: HardwareInfoSchema,
22812
22921
  scores: array(PlatformScoreSchema).readonly(),
22813
22922
  bestScore: PlatformScoreSchema,
22814
- pythonPath: string().nullable()
22923
+ pythonPath: string().nullable(),
22924
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
22815
22925
  });
22816
22926
  var ModelRequirementSchema = object({
22817
22927
  modelId: string(),
@@ -23703,12 +23813,6 @@ Object.freeze({
23703
23813
  addonId: null,
23704
23814
  access: "delete"
23705
23815
  },
23706
- "addons.updateFrameworkPackage": {
23707
- capName: "addons",
23708
- capScope: "system",
23709
- addonId: null,
23710
- access: "create"
23711
- },
23712
23816
  "addons.updatePackage": {
23713
23817
  capName: "addons",
23714
23818
  capScope: "system",
@@ -26481,12 +26585,6 @@ Object.freeze({
26481
26585
  addonId: null,
26482
26586
  access: "view"
26483
26587
  },
26484
- "pipelineExecutor.reprobeEngine": {
26485
- capName: "pipeline-executor",
26486
- capScope: "system",
26487
- addonId: null,
26488
- access: "create"
26489
- },
26490
26588
  "pipelineExecutor.runAudioTest": {
26491
26589
  capName: "pipeline-executor",
26492
26590
  capScope: "system",
@@ -26637,6 +26735,12 @@ Object.freeze({
26637
26735
  addonId: null,
26638
26736
  access: "view"
26639
26737
  },
26738
+ "pipelineOrchestrator.getNodeInferenceDevices": {
26739
+ capName: "pipeline-orchestrator",
26740
+ capScope: "system",
26741
+ addonId: null,
26742
+ access: "view"
26743
+ },
26640
26744
  "pipelineOrchestrator.getPipelineAssignment": {
26641
26745
  capName: "pipeline-orchestrator",
26642
26746
  capScope: "system",
@@ -26649,6 +26753,12 @@ Object.freeze({
26649
26753
  addonId: null,
26650
26754
  access: "view"
26651
26755
  },
26756
+ "pipelineOrchestrator.getPipelineDevicePin": {
26757
+ capName: "pipeline-orchestrator",
26758
+ capScope: "system",
26759
+ addonId: null,
26760
+ access: "view"
26761
+ },
26652
26762
  "pipelineOrchestrator.listAgentSettings": {
26653
26763
  capName: "pipeline-orchestrator",
26654
26764
  capScope: "system",
@@ -26691,19 +26801,19 @@ Object.freeze({
26691
26801
  addonId: null,
26692
26802
  access: "create"
26693
26803
  },
26694
- "pipelineOrchestrator.setAgentAddonDefaults": {
26804
+ "pipelineOrchestrator.setAgentCapabilities": {
26695
26805
  capName: "pipeline-orchestrator",
26696
26806
  capScope: "system",
26697
26807
  addonId: null,
26698
26808
  access: "create"
26699
26809
  },
26700
- "pipelineOrchestrator.setAgentCapabilities": {
26810
+ "pipelineOrchestrator.setAgentDetectWeight": {
26701
26811
  capName: "pipeline-orchestrator",
26702
26812
  capScope: "system",
26703
26813
  addonId: null,
26704
26814
  access: "create"
26705
26815
  },
26706
- "pipelineOrchestrator.setAgentDetectWeight": {
26816
+ "pipelineOrchestrator.setAgentInferenceDevices": {
26707
26817
  capName: "pipeline-orchestrator",
26708
26818
  capScope: "system",
26709
26819
  addonId: null,
@@ -26745,6 +26855,12 @@ Object.freeze({
26745
26855
  addonId: null,
26746
26856
  access: "create"
26747
26857
  },
26858
+ "pipelineOrchestrator.setPipelineDevicePin": {
26859
+ capName: "pipeline-orchestrator",
26860
+ capScope: "system",
26861
+ addonId: null,
26862
+ access: "create"
26863
+ },
26748
26864
  "pipelineOrchestrator.unassignAudio": {
26749
26865
  capName: "pipeline-orchestrator",
26750
26866
  capScope: "system",
@@ -28297,32 +28413,6 @@ Object.freeze({
28297
28413
  "network-access": "ingress",
28298
28414
  "smtp-provider": "email"
28299
28415
  });
28300
- var frameworkSwapPackageSchema = object({
28301
- name: string(),
28302
- stagedPath: string(),
28303
- backupPath: string(),
28304
- toVersion: string(),
28305
- fromVersion: string().nullable()
28306
- });
28307
- object({
28308
- jobId: string(),
28309
- taskId: string(),
28310
- packages: array(frameworkSwapPackageSchema),
28311
- requestedAtMs: number(),
28312
- schemaVersion: literal(1)
28313
- });
28314
- object({
28315
- jobId: string(),
28316
- taskId: string(),
28317
- backups: array(object({
28318
- name: string(),
28319
- backupPath: string(),
28320
- livePath: string()
28321
- })),
28322
- appliedAtMs: number(),
28323
- bootAttempts: number(),
28324
- schemaVersion: literal(1)
28325
- });
28326
28416
  //#endregion
28327
28417
  //#region ../../node_modules/@apocaliss92/wyze-bridge-js/dist/index.js
28328
28418
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
package/dist/addon.mjs CHANGED
@@ -7094,6 +7094,17 @@ var ModelCatalogEntrySchema = object({
7094
7094
  "imagenet",
7095
7095
  "none"
7096
7096
  ]).optional(),
7097
+ /**
7098
+ * The model already applies softmax IN-GRAPH — its raw output is a
7099
+ * probability distribution, not logits. When set, the `softmax`
7100
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7101
+ * probability vector collapses it toward uniform (top-1 score craters far
7102
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7103
+ * the output is raw logits and the postprocessor applies softmax (the normal
7104
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7105
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7106
+ */
7107
+ outputProbabilities: boolean().optional(),
7097
7108
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7098
7109
  /**
7099
7110
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -12384,10 +12395,7 @@ var ConfigUISchemaNullableBridge = custom();
12384
12395
  var InferenceCapabilitiesBridge = custom();
12385
12396
  var ModelAvailabilityListBridge = custom();
12386
12397
  var PipelineRunResultBridge = custom();
12387
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
12388
- kind: "mutation",
12389
- auth: "admin"
12390
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
12398
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
12391
12399
  modelId: string(),
12392
12400
  settings: record(string(), unknown()).readonly()
12393
12401
  }))), method(object({ steps: record(string(), object({
@@ -12447,13 +12455,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12447
12455
  * (inputClasses ≠ null) are skipped and served per-track via
12448
12456
  * pipelineRunner.runDetailSubtree (two-plane design).
12449
12457
  */
12450
- plane: _enum(["full", "frame"]).optional()
12458
+ plane: _enum(["full", "frame"]).optional(),
12459
+ /**
12460
+ * Inference-device selector (Phase 2 multi-device). Format
12461
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
12462
+ * Omitted ⇒ the runner's default device (current single-engine
12463
+ * behaviour). Selects WHICH device pool of the node runs the call.
12464
+ */
12465
+ deviceKey: string().optional()
12451
12466
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
12452
12467
  engine: PipelineEngineChoiceSchema.optional(),
12453
12468
  steps: array(PipelineStepInputSchema).min(1),
12454
12469
  frames: array(FrameInputSchema).min(1).max(255),
12455
12470
  deviceId: number().optional(),
12456
- sessionId: string().optional()
12471
+ sessionId: string().optional(),
12472
+ /**
12473
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
12474
+ * the batch to the Python pool's bench preprocess cache
12475
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
12476
+ * preprocessed ONCE and every later inference is a pure-inference cache
12477
+ * hit — the sustained-throughput run measures inference, not
12478
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
12479
+ * full preprocess every call, correct). Fresh per sustained run;
12480
+ * released via `uncacheFrame`.
12481
+ */
12482
+ frameId: number().int().nonnegative().optional(),
12483
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
12484
+ deviceKey: string().optional()
12457
12485
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
12458
12486
  data: _instanceof(Uint8Array),
12459
12487
  width: number().int().positive(),
@@ -12485,8 +12513,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
12485
12513
  * - `runtime` — main camera-serving engine (no idle TTL).
12486
12514
  * - `warm-override` — benchmark/test override held in the warm
12487
12515
  * cache; auto-disposed after the idle TTL.
12516
+ * - `device-pool` — a concurrent per-device pool (Phase 2
12517
+ * multi-device, keyed by `deviceKey`) resolved
12518
+ * via `resolveDeviceFactory`. Runs alongside the
12519
+ * `runtime` engine on a DIFFERENT accelerator
12520
+ * (NPU / iGPU / Coral) — this is how the
12521
+ * Engines tab shows all pools running at once.
12488
12522
  */
12489
- kind: _enum(["runtime", "warm-override"]),
12523
+ kind: _enum([
12524
+ "runtime",
12525
+ "warm-override",
12526
+ "device-pool"
12527
+ ]),
12490
12528
  /** Native pid of the underlying Python pool (null when no pool). */
12491
12529
  poolPid: number().nullable(),
12492
12530
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -12861,7 +12899,14 @@ var RunnerCameraConfigSchema = object({
12861
12899
  * camera's detect node differs from its source-owner (P2d, gated by the
12862
12900
  * `remoteSourcingNodes` rollout setting).
12863
12901
  */
12864
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
12902
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
12903
+ /**
12904
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
12905
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
12906
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
12907
+ * this only selects WHICH device pool of that node runs the session.
12908
+ */
12909
+ deviceKey: string().optional()
12865
12910
  });
12866
12911
  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;
12867
12912
  /**
@@ -12882,6 +12927,19 @@ var RunnerLocalLoadSchema = object({
12882
12927
  avgInferenceTimeMs: number(),
12883
12928
  /** Total queue depth across motion + detection queues. */
12884
12929
  queueDepthTotal: number(),
12930
+ /**
12931
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
12932
+ * this runner currently has attached cameras on, so the orchestrator's second
12933
+ * `balance()` pass (over a node's devices) weights on real per-pool session
12934
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
12935
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
12936
+ */
12937
+ devices: array(object({
12938
+ deviceKey: string(),
12939
+ backend: string(),
12940
+ attachedCameras: number(),
12941
+ queueDepthTotal: number()
12942
+ })).default([]),
12885
12943
  /** Hardware capability flags reported by this node. */
12886
12944
  hardware: object({
12887
12945
  hasGpu: boolean(),
@@ -16030,6 +16088,8 @@ var BaseDeviceProvider = class extends BaseAddon {
16030
16088
  return toDeviceSummary(device, this.addonId);
16031
16089
  }
16032
16090
  };
16091
+ 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;
16092
+ new Set(Object.values(DeviceType));
16033
16093
  /**
16034
16094
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
16035
16095
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -19716,13 +19776,11 @@ var PipelineTemplateSchema = object({
19716
19776
  createdAt: string(),
19717
19777
  updatedAt: string()
19718
19778
  });
19719
- var AgentAddonConfigSchema = object({
19720
- enabled: boolean(),
19779
+ var DeviceStepConfigSchema = object({
19721
19780
  modelId: string().optional(),
19722
- settings: record(string(), unknown()).readonly()
19781
+ settings: record(string(), unknown()).optional()
19723
19782
  });
19724
19783
  var AgentPipelineSettingsSchema = object({
19725
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
19726
19784
  maxCameras: number().int().nonnegative().nullable().default(null),
19727
19785
  /** Per-node detection weight (relative share for the quota balancer). */
19728
19786
  detectWeight: number().positive().optional(),
@@ -19746,7 +19804,22 @@ var AgentPipelineSettingsSchema = object({
19746
19804
  * it already uses to reach the hub). Set this only when the auto-detected
19747
19805
  * address is wrong (multi-homed host, NAT, custom interface).
19748
19806
  */
19749
- reachableHost: string().optional()
19807
+ reachableHost: string().optional(),
19808
+ /**
19809
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
19810
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
19811
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
19812
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
19813
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
19814
+ * the default model/settings for every camera landing on that accelerator;
19815
+ * a stepId absent ⇒ the step uses that device's format default.
19816
+ */
19817
+ inferenceDevices: record(string(), object({
19818
+ enabled: boolean(),
19819
+ weight: number().positive().optional(),
19820
+ maxSessions: number().int().positive().optional(),
19821
+ steps: record(string(), DeviceStepConfigSchema).optional()
19822
+ })).optional()
19750
19823
  });
19751
19824
  var CameraPipelineForAgentSchema = object({
19752
19825
  steps: array(PipelineStepInputSchema).readonly(),
@@ -19756,14 +19829,13 @@ var CameraPipelineForAgentSchema = object({
19756
19829
  }).nullable()
19757
19830
  });
19758
19831
  var CameraStepOverridePatchSchema = object({
19759
- enabled: boolean().optional(),
19760
19832
  modelId: string().optional(),
19761
19833
  settings: record(string(), unknown()).readonly().optional()
19762
19834
  });
19763
19835
  var CameraPipelineSettingsSchema = object({
19764
19836
  pinnedAgentNodeId: string().optional(),
19765
19837
  stepToggles: record(string(), boolean()).optional(),
19766
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
19838
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
19767
19839
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
19768
19840
  });
19769
19841
  /**
@@ -19977,6 +20049,44 @@ var CameraStatusSchema = object({
19977
20049
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
19978
20050
  fetchedAt: number()
19979
20051
  });
20052
+ var NodeInferenceDeviceSchema = object({
20053
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
20054
+ key: string(),
20055
+ backend: string(),
20056
+ device: string(),
20057
+ format: _enum(MODEL_FORMATS),
20058
+ /** Whether the node's live probe reports the device as usable right now. */
20059
+ available: boolean(),
20060
+ /**
20061
+ * Whether this device participates in dispatch. AUTO default (spec C2):
20062
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
20063
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
20064
+ * not a balanced target). An explicit stored value always wins; a stored-only
20065
+ * (unavailable) key keeps its stored value.
20066
+ */
20067
+ enabled: boolean(),
20068
+ /** Relative balancer weight for the enabled device (default 1). */
20069
+ weight: number(),
20070
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
20071
+ maxSessions: number().nullable(),
20072
+ /** Object-detection model the executor defaults to for this deviceKey. */
20073
+ defaultModelId: string(),
20074
+ /**
20075
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
20076
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
20077
+ * Absent/empty ⇒ no base (every step uses its device format default). The
20078
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
20079
+ * available per format; this is the stored selection that becomes the
20080
+ * default for EVERY camera landing on this accelerator.
20081
+ */
20082
+ steps: record(string(), DeviceStepConfigSchema).optional()
20083
+ });
20084
+ var NodeInferenceDevicesSchema = object({
20085
+ nodeId: string(),
20086
+ /** False when the node's platform-probe was unreachable (no live device set). */
20087
+ reachable: boolean(),
20088
+ devices: array(NodeInferenceDeviceSchema).readonly()
20089
+ });
19980
20090
  method(object({
19981
20091
  deviceId: number(),
19982
20092
  agentNodeId: string()
@@ -19986,7 +20096,13 @@ method(object({
19986
20096
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
19987
20097
  kind: "mutation",
19988
20098
  auth: "admin"
19989
- }), method(_void(), object({ migrated: number() }), {
20099
+ }), method(object({
20100
+ deviceId: number(),
20101
+ deviceKey: string()
20102
+ }), object({ success: literal(true) }), {
20103
+ kind: "mutation",
20104
+ auth: "admin"
20105
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
19990
20106
  kind: "mutation",
19991
20107
  auth: "admin"
19992
20108
  }), method(_void(), array(PipelineAssignmentSchema).readonly()), method(object({ deviceId: number() }), PipelineAssignmentSchema.nullable()), method(_void(), array(AgentLoadSummarySchema).readonly()), method(_void(), GlobalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(object({ nodeId: string() }), CapabilityBindingsSchema), method(object({
@@ -20020,13 +20136,7 @@ method(object({
20020
20136
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
20021
20137
  nodeId: string(),
20022
20138
  settings: AgentPipelineSettingsSchema
20023
- })).readonly()), method(object({
20024
- agentNodeId: string(),
20025
- defaults: record(string(), AgentAddonConfigSchema)
20026
- }), object({ success: literal(true) }), {
20027
- kind: "mutation",
20028
- auth: "admin"
20029
- }), method(object({ agentNodeId: string() }), object({
20139
+ })).readonly()), method(object({ agentNodeId: string() }), object({
20030
20140
  success: boolean(),
20031
20141
  removed: boolean()
20032
20142
  }), {
@@ -20058,7 +20168,18 @@ method(object({
20058
20168
  }), object({ success: literal(true) }), {
20059
20169
  kind: "mutation",
20060
20170
  auth: "admin"
20061
- }), method(object({ agentNodeId: string() }), object({
20171
+ }), method(object({
20172
+ agentNodeId: string(),
20173
+ inferenceDevices: record(string(), object({
20174
+ enabled: boolean(),
20175
+ weight: number().positive().optional(),
20176
+ maxSessions: number().int().positive().optional(),
20177
+ steps: record(string(), DeviceStepConfigSchema).optional()
20178
+ }))
20179
+ }), object({ success: literal(true) }), {
20180
+ kind: "mutation",
20181
+ auth: "admin"
20182
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
20062
20183
  success: literal(true),
20063
20184
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
20064
20185
  effectiveModelId: string().nullable(),
@@ -20074,9 +20195,10 @@ method(object({
20074
20195
  }), object({ success: literal(true) }), {
20075
20196
  kind: "mutation",
20076
20197
  auth: "admin"
20077
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
20198
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
20078
20199
  deviceId: number(),
20079
20200
  agentNodeId: string(),
20201
+ deviceKey: string(),
20080
20202
  addonId: string(),
20081
20203
  patch: CameraStepOverridePatchSchema.nullable()
20082
20204
  }), object({ success: literal(true) }), {
@@ -20113,14 +20235,13 @@ method(object({
20113
20235
  });
20114
20236
  /**
20115
20237
  * server-management — per-NODE singleton capability for a node's ROOT
20116
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
20117
- * agents).
20238
+ * package lifecycle (runtime-updatable node packages).
20118
20239
  *
20119
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
20120
- * on agents) carries the whole software stack in its npm dep tree, so ONE
20121
- * version describes the node. Updates install into
20122
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
20123
- * starter (probation boot + auto-rollback to N-1).
20240
+ * Every node role runs the SAME root package (`@camstack/server`), which
20241
+ * carries the whole software stack in its npm dep tree, so ONE version
20242
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
20243
+ * on restart via the baked starter (single-copy in-place swap — no probation,
20244
+ * no auto-rollback).
20124
20245
  *
20125
20246
  * Providers:
20126
20247
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -20228,7 +20349,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
20228
20349
  /** Explicit target version; omitted = latest from the registry. */
20229
20350
  version: string().optional() }), ServerUpdateActionResultSchema, {
20230
20351
  kind: "mutation",
20231
- auth: "admin"
20352
+ auth: "admin",
20353
+ timeoutMs: 16 * 6e4
20232
20354
  }), method(_void(), ServerUpdateActionResultSchema, {
20233
20355
  kind: "mutation",
20234
20356
  auth: "admin"
@@ -21323,22 +21445,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
21323
21445
  var RestartAddonResultSchema = unknown();
21324
21446
  var InstallPackageResultSchema = unknown();
21325
21447
  var ReloadPackagesResultSchema = unknown();
21326
- /**
21327
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
21328
- * server restarts so the admin UI can react to the `restartingAt`
21329
- * timestamp (shows reconnect overlay). The transition from
21330
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
21331
- * `system.restart-completed` event after the new process boots.
21332
- *
21333
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
21334
- */
21335
- var UpdateFrameworkPackageResultSchema = object({
21336
- packageName: string(),
21337
- fromVersion: string(),
21338
- toVersion: string(),
21339
- /** Ms-epoch the server scheduled its self-restart. */
21340
- restartingAt: number()
21341
- });
21342
21448
  var BulkUpdateItemStatusSchema = _enum([
21343
21449
  "queued",
21344
21450
  "updating",
@@ -21466,13 +21572,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
21466
21572
  }), object({ success: literal(true) }), {
21467
21573
  kind: "mutation",
21468
21574
  auth: "admin"
21469
- }), method(object({
21470
- packageName: string().min(1),
21471
- version: string().optional(),
21472
- deferRestart: boolean().optional()
21473
- }), UpdateFrameworkPackageResultSchema, {
21474
- kind: "mutation",
21475
- auth: "admin"
21476
21575
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
21477
21576
  kind: "mutation",
21478
21577
  auth: "admin"
@@ -22389,10 +22488,10 @@ var TopologyCategorySchema = object({
22389
22488
  addons: array(TopologyCategoryAddonSchema).readonly()
22390
22489
  });
22391
22490
  /**
22392
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
22393
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
22394
- * version visibility for the Server management surface. Nullable: offline
22395
- * rows and pre-phase-2 nodes report none.
22491
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
22492
+ * root package for every node role) as reported by its `registerNode`
22493
+ * manifest — version visibility for the Server management surface. Nullable:
22494
+ * offline rows and nodes that never reported one.
22396
22495
  */
22397
22496
  var TopologyRootPackageSchema = object({
22398
22497
  name: string(),
@@ -22780,17 +22879,28 @@ var PlatformScoreSchema = object({
22780
22879
  format: _enum([
22781
22880
  "onnx",
22782
22881
  "coreml",
22783
- "openvino"
22882
+ "openvino",
22883
+ "tflite"
22784
22884
  ]),
22785
22885
  score: number(),
22786
22886
  reason: string(),
22787
22887
  available: boolean()
22788
22888
  });
22889
+ var InferenceDeviceDescriptorSchema = object({
22890
+ key: string(),
22891
+ backend: string(),
22892
+ device: string(),
22893
+ format: ModelFormatSchema,
22894
+ runtime: literal("python"),
22895
+ score: number(),
22896
+ available: boolean()
22897
+ });
22789
22898
  var PlatformCapabilitiesSchema = object({
22790
22899
  hardware: HardwareInfoSchema,
22791
22900
  scores: array(PlatformScoreSchema).readonly(),
22792
22901
  bestScore: PlatformScoreSchema,
22793
- pythonPath: string().nullable()
22902
+ pythonPath: string().nullable(),
22903
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
22794
22904
  });
22795
22905
  var ModelRequirementSchema = object({
22796
22906
  modelId: string(),
@@ -23682,12 +23792,6 @@ Object.freeze({
23682
23792
  addonId: null,
23683
23793
  access: "delete"
23684
23794
  },
23685
- "addons.updateFrameworkPackage": {
23686
- capName: "addons",
23687
- capScope: "system",
23688
- addonId: null,
23689
- access: "create"
23690
- },
23691
23795
  "addons.updatePackage": {
23692
23796
  capName: "addons",
23693
23797
  capScope: "system",
@@ -26460,12 +26564,6 @@ Object.freeze({
26460
26564
  addonId: null,
26461
26565
  access: "view"
26462
26566
  },
26463
- "pipelineExecutor.reprobeEngine": {
26464
- capName: "pipeline-executor",
26465
- capScope: "system",
26466
- addonId: null,
26467
- access: "create"
26468
- },
26469
26567
  "pipelineExecutor.runAudioTest": {
26470
26568
  capName: "pipeline-executor",
26471
26569
  capScope: "system",
@@ -26616,6 +26714,12 @@ Object.freeze({
26616
26714
  addonId: null,
26617
26715
  access: "view"
26618
26716
  },
26717
+ "pipelineOrchestrator.getNodeInferenceDevices": {
26718
+ capName: "pipeline-orchestrator",
26719
+ capScope: "system",
26720
+ addonId: null,
26721
+ access: "view"
26722
+ },
26619
26723
  "pipelineOrchestrator.getPipelineAssignment": {
26620
26724
  capName: "pipeline-orchestrator",
26621
26725
  capScope: "system",
@@ -26628,6 +26732,12 @@ Object.freeze({
26628
26732
  addonId: null,
26629
26733
  access: "view"
26630
26734
  },
26735
+ "pipelineOrchestrator.getPipelineDevicePin": {
26736
+ capName: "pipeline-orchestrator",
26737
+ capScope: "system",
26738
+ addonId: null,
26739
+ access: "view"
26740
+ },
26631
26741
  "pipelineOrchestrator.listAgentSettings": {
26632
26742
  capName: "pipeline-orchestrator",
26633
26743
  capScope: "system",
@@ -26670,19 +26780,19 @@ Object.freeze({
26670
26780
  addonId: null,
26671
26781
  access: "create"
26672
26782
  },
26673
- "pipelineOrchestrator.setAgentAddonDefaults": {
26783
+ "pipelineOrchestrator.setAgentCapabilities": {
26674
26784
  capName: "pipeline-orchestrator",
26675
26785
  capScope: "system",
26676
26786
  addonId: null,
26677
26787
  access: "create"
26678
26788
  },
26679
- "pipelineOrchestrator.setAgentCapabilities": {
26789
+ "pipelineOrchestrator.setAgentDetectWeight": {
26680
26790
  capName: "pipeline-orchestrator",
26681
26791
  capScope: "system",
26682
26792
  addonId: null,
26683
26793
  access: "create"
26684
26794
  },
26685
- "pipelineOrchestrator.setAgentDetectWeight": {
26795
+ "pipelineOrchestrator.setAgentInferenceDevices": {
26686
26796
  capName: "pipeline-orchestrator",
26687
26797
  capScope: "system",
26688
26798
  addonId: null,
@@ -26724,6 +26834,12 @@ Object.freeze({
26724
26834
  addonId: null,
26725
26835
  access: "create"
26726
26836
  },
26837
+ "pipelineOrchestrator.setPipelineDevicePin": {
26838
+ capName: "pipeline-orchestrator",
26839
+ capScope: "system",
26840
+ addonId: null,
26841
+ access: "create"
26842
+ },
26727
26843
  "pipelineOrchestrator.unassignAudio": {
26728
26844
  capName: "pipeline-orchestrator",
26729
26845
  capScope: "system",
@@ -28276,32 +28392,6 @@ Object.freeze({
28276
28392
  "network-access": "ingress",
28277
28393
  "smtp-provider": "email"
28278
28394
  });
28279
- var frameworkSwapPackageSchema = object({
28280
- name: string(),
28281
- stagedPath: string(),
28282
- backupPath: string(),
28283
- toVersion: string(),
28284
- fromVersion: string().nullable()
28285
- });
28286
- object({
28287
- jobId: string(),
28288
- taskId: string(),
28289
- packages: array(frameworkSwapPackageSchema),
28290
- requestedAtMs: number(),
28291
- schemaVersion: literal(1)
28292
- });
28293
- object({
28294
- jobId: string(),
28295
- taskId: string(),
28296
- backups: array(object({
28297
- name: string(),
28298
- backupPath: string(),
28299
- livePath: string()
28300
- })),
28301
- appliedAtMs: number(),
28302
- bootAttempts: number(),
28303
- schemaVersion: literal(1)
28304
- });
28305
28395
  //#endregion
28306
28396
  //#region ../../node_modules/@apocaliss92/wyze-bridge-js/dist/index.js
28307
28397
  var __require = /* @__PURE__ */ ((x) => typeof __require$1 !== "undefined" ? __require$1 : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof __require$1 !== "undefined" ? __require$1 : a)[b] }) : x)(function(x) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.1.25",
3
+ "version": "0.2.0",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",