@camstack/addon-cloudflare 1.1.29 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7067,6 +7067,17 @@ var ModelCatalogEntrySchema = object({
7067
7067
  "imagenet",
7068
7068
  "none"
7069
7069
  ]).optional(),
7070
+ /**
7071
+ * The model already applies softmax IN-GRAPH — its raw output is a
7072
+ * probability distribution, not logits. When set, the `softmax`
7073
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7074
+ * probability vector collapses it toward uniform (top-1 score craters far
7075
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7076
+ * the output is raw logits and the postprocessor applies softmax (the normal
7077
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7078
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7079
+ */
7080
+ outputProbabilities: boolean().optional(),
7070
7081
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7071
7082
  /**
7072
7083
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11080,10 +11091,7 @@ var ConfigUISchemaNullableBridge = custom();
11080
11091
  var InferenceCapabilitiesBridge = custom();
11081
11092
  var ModelAvailabilityListBridge = custom();
11082
11093
  var PipelineRunResultBridge = custom();
11083
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11084
- kind: "mutation",
11085
- auth: "admin"
11086
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11094
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11087
11095
  modelId: string(),
11088
11096
  settings: record(string(), unknown()).readonly()
11089
11097
  }))), method(object({ steps: record(string(), object({
@@ -11143,13 +11151,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11143
11151
  * (inputClasses ≠ null) are skipped and served per-track via
11144
11152
  * pipelineRunner.runDetailSubtree (two-plane design).
11145
11153
  */
11146
- plane: _enum(["full", "frame"]).optional()
11154
+ plane: _enum(["full", "frame"]).optional(),
11155
+ /**
11156
+ * Inference-device selector (Phase 2 multi-device). Format
11157
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11158
+ * Omitted ⇒ the runner's default device (current single-engine
11159
+ * behaviour). Selects WHICH device pool of the node runs the call.
11160
+ */
11161
+ deviceKey: string().optional()
11147
11162
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11148
11163
  engine: PipelineEngineChoiceSchema.optional(),
11149
11164
  steps: array(PipelineStepInputSchema).min(1),
11150
11165
  frames: array(FrameInputSchema).min(1).max(255),
11151
11166
  deviceId: number().optional(),
11152
- sessionId: string().optional()
11167
+ sessionId: string().optional(),
11168
+ /**
11169
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11170
+ * the batch to the Python pool's bench preprocess cache
11171
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11172
+ * preprocessed ONCE and every later inference is a pure-inference cache
11173
+ * hit — the sustained-throughput run measures inference, not
11174
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11175
+ * full preprocess every call, correct). Fresh per sustained run;
11176
+ * released via `uncacheFrame`.
11177
+ */
11178
+ frameId: number().int().nonnegative().optional(),
11179
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11180
+ deviceKey: string().optional()
11153
11181
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11154
11182
  data: _instanceof(Uint8Array),
11155
11183
  width: number().int().positive(),
@@ -11181,8 +11209,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11181
11209
  * - `runtime` — main camera-serving engine (no idle TTL).
11182
11210
  * - `warm-override` — benchmark/test override held in the warm
11183
11211
  * cache; auto-disposed after the idle TTL.
11212
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11213
+ * multi-device, keyed by `deviceKey`) resolved
11214
+ * via `resolveDeviceFactory`. Runs alongside the
11215
+ * `runtime` engine on a DIFFERENT accelerator
11216
+ * (NPU / iGPU / Coral) — this is how the
11217
+ * Engines tab shows all pools running at once.
11184
11218
  */
11185
- kind: _enum(["runtime", "warm-override"]),
11219
+ kind: _enum([
11220
+ "runtime",
11221
+ "warm-override",
11222
+ "device-pool"
11223
+ ]),
11186
11224
  /** Native pid of the underlying Python pool (null when no pool). */
11187
11225
  poolPid: number().nullable(),
11188
11226
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11284,7 +11322,21 @@ var NativeCropResultSchema = object({
11284
11322
  /** Packed rgb (24-bit) pixels of the crop. */
11285
11323
  bytes: _instanceof(Uint8Array),
11286
11324
  width: number().int().positive(),
11287
- height: number().int().positive()
11325
+ height: number().int().positive(),
11326
+ /**
11327
+ * Which source served this crop, so a quality-sensitive consumer (the native
11328
+ * `keyFrame`) can reject a degraded fallback:
11329
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11330
+ * quality path).
11331
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11332
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11333
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11334
+ *
11335
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11336
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11337
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11338
+ */
11339
+ tier: _enum(["native", "ram-fullframe"]).optional()
11288
11340
  });
11289
11341
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11290
11342
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11524,7 +11576,14 @@ var RunnerCameraConfigSchema = object({
11524
11576
  * camera's detect node differs from its source-owner (P2d, gated by the
11525
11577
  * `remoteSourcingNodes` rollout setting).
11526
11578
  */
11527
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11579
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11580
+ /**
11581
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11582
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11583
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11584
+ * this only selects WHICH device pool of that node runs the session.
11585
+ */
11586
+ deviceKey: string().optional()
11528
11587
  });
11529
11588
  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;
11530
11589
  /**
@@ -11545,6 +11604,19 @@ var RunnerLocalLoadSchema = object({
11545
11604
  avgInferenceTimeMs: number(),
11546
11605
  /** Total queue depth across motion + detection queues. */
11547
11606
  queueDepthTotal: number(),
11607
+ /**
11608
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11609
+ * this runner currently has attached cameras on, so the orchestrator's second
11610
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11611
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11612
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11613
+ */
11614
+ devices: array(object({
11615
+ deviceKey: string(),
11616
+ backend: string(),
11617
+ attachedCameras: number(),
11618
+ queueDepthTotal: number()
11619
+ })).default([]),
11548
11620
  /** Hardware capability flags reported by this node. */
11549
11621
  hardware: object({
11550
11622
  hasGpu: boolean(),
@@ -13020,6 +13092,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13020
13092
  kind: "mutation",
13021
13093
  auth: "admin"
13022
13094
  });
13095
+ 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;
13096
+ new Set(Object.values(DeviceType));
13023
13097
  /**
13024
13098
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13025
13099
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14614,7 +14688,8 @@ var LinkedDeviceSchema = object({
14614
14688
  deviceId: number(),
14615
14689
  name: string(),
14616
14690
  location: string().nullable(),
14617
- features: array(string())
14691
+ features: array(string()),
14692
+ producesTrackedEvents: boolean().optional()
14618
14693
  });
14619
14694
  var SavedDeviceRowSchema = object({
14620
14695
  /** Numeric id reserved at allocateDeviceId time. */
@@ -16261,6 +16336,7 @@ var TrackSchema = object({
16261
16336
  deviceId: number(),
16262
16337
  className: string(),
16263
16338
  label: string().optional(),
16339
+ producingDeviceName: string().optional(),
16264
16340
  /** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
16265
16341
  source: TrackSourceSchema.optional(),
16266
16342
  firstSeen: number(),
@@ -16398,7 +16474,8 @@ var MediaFileKindEnum = _enum([
16398
16474
  "fullFrameBoxed",
16399
16475
  "faceCrop",
16400
16476
  "plateCrop",
16401
- "keyFrame"
16477
+ "keyFrame",
16478
+ "keyFrameSmall"
16402
16479
  ]);
16403
16480
  var MediaFileSchema = object({
16404
16481
  key: string(),
@@ -16727,13 +16804,11 @@ var PipelineTemplateSchema = object({
16727
16804
  createdAt: string(),
16728
16805
  updatedAt: string()
16729
16806
  });
16730
- var AgentAddonConfigSchema = object({
16731
- enabled: boolean(),
16807
+ var DeviceStepConfigSchema = object({
16732
16808
  modelId: string().optional(),
16733
- settings: record(string(), unknown()).readonly()
16809
+ settings: record(string(), unknown()).optional()
16734
16810
  });
16735
16811
  var AgentPipelineSettingsSchema = object({
16736
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16737
16812
  maxCameras: number().int().nonnegative().nullable().default(null),
16738
16813
  /** Per-node detection weight (relative share for the quota balancer). */
16739
16814
  detectWeight: number().positive().optional(),
@@ -16757,7 +16832,22 @@ var AgentPipelineSettingsSchema = object({
16757
16832
  * it already uses to reach the hub). Set this only when the auto-detected
16758
16833
  * address is wrong (multi-homed host, NAT, custom interface).
16759
16834
  */
16760
- reachableHost: string().optional()
16835
+ reachableHost: string().optional(),
16836
+ /**
16837
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16838
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16839
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16840
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16841
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16842
+ * the default model/settings for every camera landing on that accelerator;
16843
+ * a stepId absent ⇒ the step uses that device's format default.
16844
+ */
16845
+ inferenceDevices: record(string(), object({
16846
+ enabled: boolean(),
16847
+ weight: number().positive().optional(),
16848
+ maxSessions: number().int().positive().optional(),
16849
+ steps: record(string(), DeviceStepConfigSchema).optional()
16850
+ })).optional()
16761
16851
  });
16762
16852
  var CameraPipelineForAgentSchema = object({
16763
16853
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16767,14 +16857,13 @@ var CameraPipelineForAgentSchema = object({
16767
16857
  }).nullable()
16768
16858
  });
16769
16859
  var CameraStepOverridePatchSchema = object({
16770
- enabled: boolean().optional(),
16771
16860
  modelId: string().optional(),
16772
16861
  settings: record(string(), unknown()).readonly().optional()
16773
16862
  });
16774
16863
  var CameraPipelineSettingsSchema = object({
16775
16864
  pinnedAgentNodeId: string().optional(),
16776
16865
  stepToggles: record(string(), boolean()).optional(),
16777
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16866
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16778
16867
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16779
16868
  });
16780
16869
  /**
@@ -16988,6 +17077,44 @@ var CameraStatusSchema = object({
16988
17077
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
16989
17078
  fetchedAt: number()
16990
17079
  });
17080
+ var NodeInferenceDeviceSchema = object({
17081
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17082
+ key: string(),
17083
+ backend: string(),
17084
+ device: string(),
17085
+ format: _enum(MODEL_FORMATS),
17086
+ /** Whether the node's live probe reports the device as usable right now. */
17087
+ available: boolean(),
17088
+ /**
17089
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17090
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17091
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17092
+ * not a balanced target). An explicit stored value always wins; a stored-only
17093
+ * (unavailable) key keeps its stored value.
17094
+ */
17095
+ enabled: boolean(),
17096
+ /** Relative balancer weight for the enabled device (default 1). */
17097
+ weight: number(),
17098
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17099
+ maxSessions: number().nullable(),
17100
+ /** Object-detection model the executor defaults to for this deviceKey. */
17101
+ defaultModelId: string(),
17102
+ /**
17103
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17104
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17105
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17106
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17107
+ * available per format; this is the stored selection that becomes the
17108
+ * default for EVERY camera landing on this accelerator.
17109
+ */
17110
+ steps: record(string(), DeviceStepConfigSchema).optional()
17111
+ });
17112
+ var NodeInferenceDevicesSchema = object({
17113
+ nodeId: string(),
17114
+ /** False when the node's platform-probe was unreachable (no live device set). */
17115
+ reachable: boolean(),
17116
+ devices: array(NodeInferenceDeviceSchema).readonly()
17117
+ });
16991
17118
  method(object({
16992
17119
  deviceId: number(),
16993
17120
  agentNodeId: string()
@@ -16997,7 +17124,13 @@ method(object({
16997
17124
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
16998
17125
  kind: "mutation",
16999
17126
  auth: "admin"
17000
- }), method(_void(), object({ migrated: number() }), {
17127
+ }), method(object({
17128
+ deviceId: number(),
17129
+ deviceKey: string()
17130
+ }), object({ success: literal(true) }), {
17131
+ kind: "mutation",
17132
+ auth: "admin"
17133
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
17001
17134
  kind: "mutation",
17002
17135
  auth: "admin"
17003
17136
  }), 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({
@@ -17031,13 +17164,7 @@ method(object({
17031
17164
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17032
17165
  nodeId: string(),
17033
17166
  settings: AgentPipelineSettingsSchema
17034
- })).readonly()), method(object({
17035
- agentNodeId: string(),
17036
- defaults: record(string(), AgentAddonConfigSchema)
17037
- }), object({ success: literal(true) }), {
17038
- kind: "mutation",
17039
- auth: "admin"
17040
- }), method(object({ agentNodeId: string() }), object({
17167
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17041
17168
  success: boolean(),
17042
17169
  removed: boolean()
17043
17170
  }), {
@@ -17069,7 +17196,18 @@ method(object({
17069
17196
  }), object({ success: literal(true) }), {
17070
17197
  kind: "mutation",
17071
17198
  auth: "admin"
17072
- }), method(object({ agentNodeId: string() }), object({
17199
+ }), method(object({
17200
+ agentNodeId: string(),
17201
+ inferenceDevices: record(string(), object({
17202
+ enabled: boolean(),
17203
+ weight: number().positive().optional(),
17204
+ maxSessions: number().int().positive().optional(),
17205
+ steps: record(string(), DeviceStepConfigSchema).optional()
17206
+ }))
17207
+ }), object({ success: literal(true) }), {
17208
+ kind: "mutation",
17209
+ auth: "admin"
17210
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17073
17211
  success: literal(true),
17074
17212
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17075
17213
  effectiveModelId: string().nullable(),
@@ -17085,9 +17223,10 @@ method(object({
17085
17223
  }), object({ success: literal(true) }), {
17086
17224
  kind: "mutation",
17087
17225
  auth: "admin"
17088
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17226
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17089
17227
  deviceId: number(),
17090
17228
  agentNodeId: string(),
17229
+ deviceKey: string(),
17091
17230
  addonId: string(),
17092
17231
  patch: CameraStepOverridePatchSchema.nullable()
17093
17232
  }), object({ success: literal(true) }), {
@@ -17124,14 +17263,13 @@ method(object({
17124
17263
  });
17125
17264
  /**
17126
17265
  * server-management — per-NODE singleton capability for a node's ROOT
17127
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17128
- * agents).
17266
+ * package lifecycle (runtime-updatable node packages).
17129
17267
  *
17130
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
17131
- * on agents) carries the whole software stack in its npm dep tree, so ONE
17132
- * version describes the node. Updates install into
17133
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
17134
- * starter (probation boot + auto-rollback to N-1).
17268
+ * Every node role runs the SAME root package (`@camstack/server`), which
17269
+ * carries the whole software stack in its npm dep tree, so ONE version
17270
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17271
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17272
+ * no auto-rollback).
17135
17273
  *
17136
17274
  * Providers:
17137
17275
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17239,7 +17377,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17239
17377
  /** Explicit target version; omitted = latest from the registry. */
17240
17378
  version: string().optional() }), ServerUpdateActionResultSchema, {
17241
17379
  kind: "mutation",
17242
- auth: "admin"
17380
+ auth: "admin",
17381
+ timeoutMs: 16 * 6e4
17243
17382
  }), method(_void(), ServerUpdateActionResultSchema, {
17244
17383
  kind: "mutation",
17245
17384
  auth: "admin"
@@ -18306,22 +18445,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18306
18445
  var RestartAddonResultSchema = unknown();
18307
18446
  var InstallPackageResultSchema = unknown();
18308
18447
  var ReloadPackagesResultSchema = unknown();
18309
- /**
18310
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18311
- * server restarts so the admin UI can react to the `restartingAt`
18312
- * timestamp (shows reconnect overlay). The transition from
18313
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18314
- * `system.restart-completed` event after the new process boots.
18315
- *
18316
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18317
- */
18318
- var UpdateFrameworkPackageResultSchema = object({
18319
- packageName: string(),
18320
- fromVersion: string(),
18321
- toVersion: string(),
18322
- /** Ms-epoch the server scheduled its self-restart. */
18323
- restartingAt: number()
18324
- });
18325
18448
  var BulkUpdateItemStatusSchema = _enum([
18326
18449
  "queued",
18327
18450
  "updating",
@@ -18449,13 +18572,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18449
18572
  }), object({ success: literal(true) }), {
18450
18573
  kind: "mutation",
18451
18574
  auth: "admin"
18452
- }), method(object({
18453
- packageName: string().min(1),
18454
- version: string().optional(),
18455
- deferRestart: boolean().optional()
18456
- }), UpdateFrameworkPackageResultSchema, {
18457
- kind: "mutation",
18458
- auth: "admin"
18459
18575
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18460
18576
  kind: "mutation",
18461
18577
  auth: "admin"
@@ -19321,10 +19437,10 @@ var TopologyCategorySchema = object({
19321
19437
  addons: array(TopologyCategoryAddonSchema).readonly()
19322
19438
  });
19323
19439
  /**
19324
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19325
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19326
- * version visibility for the Server management surface. Nullable: offline
19327
- * rows and pre-phase-2 nodes report none.
19440
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19441
+ * root package for every node role) as reported by its `registerNode`
19442
+ * manifest — version visibility for the Server management surface. Nullable:
19443
+ * offline rows and nodes that never reported one.
19328
19444
  */
19329
19445
  var TopologyRootPackageSchema = object({
19330
19446
  name: string(),
@@ -19712,17 +19828,28 @@ var PlatformScoreSchema = object({
19712
19828
  format: _enum([
19713
19829
  "onnx",
19714
19830
  "coreml",
19715
- "openvino"
19831
+ "openvino",
19832
+ "tflite"
19716
19833
  ]),
19717
19834
  score: number(),
19718
19835
  reason: string(),
19719
19836
  available: boolean()
19720
19837
  });
19838
+ var InferenceDeviceDescriptorSchema = object({
19839
+ key: string(),
19840
+ backend: string(),
19841
+ device: string(),
19842
+ format: ModelFormatSchema,
19843
+ runtime: literal("python"),
19844
+ score: number(),
19845
+ available: boolean()
19846
+ });
19721
19847
  var PlatformCapabilitiesSchema = object({
19722
19848
  hardware: HardwareInfoSchema,
19723
19849
  scores: array(PlatformScoreSchema).readonly(),
19724
19850
  bestScore: PlatformScoreSchema,
19725
- pythonPath: string().nullable()
19851
+ pythonPath: string().nullable(),
19852
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19726
19853
  });
19727
19854
  var ModelRequirementSchema = object({
19728
19855
  modelId: string(),
@@ -20601,12 +20728,6 @@ Object.freeze({
20601
20728
  addonId: null,
20602
20729
  access: "delete"
20603
20730
  },
20604
- "addons.updateFrameworkPackage": {
20605
- capName: "addons",
20606
- capScope: "system",
20607
- addonId: null,
20608
- access: "create"
20609
- },
20610
20731
  "addons.updatePackage": {
20611
20732
  capName: "addons",
20612
20733
  capScope: "system",
@@ -23379,12 +23500,6 @@ Object.freeze({
23379
23500
  addonId: null,
23380
23501
  access: "view"
23381
23502
  },
23382
- "pipelineExecutor.reprobeEngine": {
23383
- capName: "pipeline-executor",
23384
- capScope: "system",
23385
- addonId: null,
23386
- access: "create"
23387
- },
23388
23503
  "pipelineExecutor.runAudioTest": {
23389
23504
  capName: "pipeline-executor",
23390
23505
  capScope: "system",
@@ -23535,6 +23650,12 @@ Object.freeze({
23535
23650
  addonId: null,
23536
23651
  access: "view"
23537
23652
  },
23653
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23654
+ capName: "pipeline-orchestrator",
23655
+ capScope: "system",
23656
+ addonId: null,
23657
+ access: "view"
23658
+ },
23538
23659
  "pipelineOrchestrator.getPipelineAssignment": {
23539
23660
  capName: "pipeline-orchestrator",
23540
23661
  capScope: "system",
@@ -23547,6 +23668,12 @@ Object.freeze({
23547
23668
  addonId: null,
23548
23669
  access: "view"
23549
23670
  },
23671
+ "pipelineOrchestrator.getPipelineDevicePin": {
23672
+ capName: "pipeline-orchestrator",
23673
+ capScope: "system",
23674
+ addonId: null,
23675
+ access: "view"
23676
+ },
23550
23677
  "pipelineOrchestrator.listAgentSettings": {
23551
23678
  capName: "pipeline-orchestrator",
23552
23679
  capScope: "system",
@@ -23589,19 +23716,19 @@ Object.freeze({
23589
23716
  addonId: null,
23590
23717
  access: "create"
23591
23718
  },
23592
- "pipelineOrchestrator.setAgentAddonDefaults": {
23719
+ "pipelineOrchestrator.setAgentCapabilities": {
23593
23720
  capName: "pipeline-orchestrator",
23594
23721
  capScope: "system",
23595
23722
  addonId: null,
23596
23723
  access: "create"
23597
23724
  },
23598
- "pipelineOrchestrator.setAgentCapabilities": {
23725
+ "pipelineOrchestrator.setAgentDetectWeight": {
23599
23726
  capName: "pipeline-orchestrator",
23600
23727
  capScope: "system",
23601
23728
  addonId: null,
23602
23729
  access: "create"
23603
23730
  },
23604
- "pipelineOrchestrator.setAgentDetectWeight": {
23731
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23605
23732
  capName: "pipeline-orchestrator",
23606
23733
  capScope: "system",
23607
23734
  addonId: null,
@@ -23643,6 +23770,12 @@ Object.freeze({
23643
23770
  addonId: null,
23644
23771
  access: "create"
23645
23772
  },
23773
+ "pipelineOrchestrator.setPipelineDevicePin": {
23774
+ capName: "pipeline-orchestrator",
23775
+ capScope: "system",
23776
+ addonId: null,
23777
+ access: "create"
23778
+ },
23646
23779
  "pipelineOrchestrator.unassignAudio": {
23647
23780
  capName: "pipeline-orchestrator",
23648
23781
  capScope: "system",
@@ -25195,31 +25328,5 @@ Object.freeze({
25195
25328
  "network-access": "ingress",
25196
25329
  "smtp-provider": "email"
25197
25330
  });
25198
- var frameworkSwapPackageSchema = object({
25199
- name: string(),
25200
- stagedPath: string(),
25201
- backupPath: string(),
25202
- toVersion: string(),
25203
- fromVersion: string().nullable()
25204
- });
25205
- object({
25206
- jobId: string(),
25207
- taskId: string(),
25208
- packages: array(frameworkSwapPackageSchema),
25209
- requestedAtMs: number(),
25210
- schemaVersion: literal(1)
25211
- });
25212
- object({
25213
- jobId: string(),
25214
- taskId: string(),
25215
- backups: array(object({
25216
- name: string(),
25217
- backupPath: string(),
25218
- livePath: string()
25219
- })),
25220
- appliedAtMs: number(),
25221
- bootAttempts: number(),
25222
- schemaVersion: literal(1)
25223
- });
25224
25331
  //#endregion
25225
25332
  export { BaseAddon as a, boolean as c, number as d, object as f, turnProviderCapability as i, discriminatedUnion as l, EventCategory as m, defineCustomActions as n, _enum as o, string as p, networkAccessCapability as r, array as s, customAction as t, literal as u };
@@ -7067,6 +7067,17 @@ var ModelCatalogEntrySchema = object({
7067
7067
  "imagenet",
7068
7068
  "none"
7069
7069
  ]).optional(),
7070
+ /**
7071
+ * The model already applies softmax IN-GRAPH — its raw output is a
7072
+ * probability distribution, not logits. When set, the `softmax`
7073
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7074
+ * probability vector collapses it toward uniform (top-1 score craters far
7075
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7076
+ * the output is raw logits and the postprocessor applies softmax (the normal
7077
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7078
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7079
+ */
7080
+ outputProbabilities: boolean().optional(),
7070
7081
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7071
7082
  /**
7072
7083
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11080,10 +11091,7 @@ var ConfigUISchemaNullableBridge = custom();
11080
11091
  var InferenceCapabilitiesBridge = custom();
11081
11092
  var ModelAvailabilityListBridge = custom();
11082
11093
  var PipelineRunResultBridge = custom();
11083
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11084
- kind: "mutation",
11085
- auth: "admin"
11086
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11094
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11087
11095
  modelId: string(),
11088
11096
  settings: record(string(), unknown()).readonly()
11089
11097
  }))), method(object({ steps: record(string(), object({
@@ -11143,13 +11151,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11143
11151
  * (inputClasses ≠ null) are skipped and served per-track via
11144
11152
  * pipelineRunner.runDetailSubtree (two-plane design).
11145
11153
  */
11146
- plane: _enum(["full", "frame"]).optional()
11154
+ plane: _enum(["full", "frame"]).optional(),
11155
+ /**
11156
+ * Inference-device selector (Phase 2 multi-device). Format
11157
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11158
+ * Omitted ⇒ the runner's default device (current single-engine
11159
+ * behaviour). Selects WHICH device pool of the node runs the call.
11160
+ */
11161
+ deviceKey: string().optional()
11147
11162
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11148
11163
  engine: PipelineEngineChoiceSchema.optional(),
11149
11164
  steps: array(PipelineStepInputSchema).min(1),
11150
11165
  frames: array(FrameInputSchema).min(1).max(255),
11151
11166
  deviceId: number().optional(),
11152
- sessionId: string().optional()
11167
+ sessionId: string().optional(),
11168
+ /**
11169
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11170
+ * the batch to the Python pool's bench preprocess cache
11171
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11172
+ * preprocessed ONCE and every later inference is a pure-inference cache
11173
+ * hit — the sustained-throughput run measures inference, not
11174
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11175
+ * full preprocess every call, correct). Fresh per sustained run;
11176
+ * released via `uncacheFrame`.
11177
+ */
11178
+ frameId: number().int().nonnegative().optional(),
11179
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11180
+ deviceKey: string().optional()
11153
11181
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11154
11182
  data: _instanceof(Uint8Array),
11155
11183
  width: number().int().positive(),
@@ -11181,8 +11209,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11181
11209
  * - `runtime` — main camera-serving engine (no idle TTL).
11182
11210
  * - `warm-override` — benchmark/test override held in the warm
11183
11211
  * cache; auto-disposed after the idle TTL.
11212
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11213
+ * multi-device, keyed by `deviceKey`) resolved
11214
+ * via `resolveDeviceFactory`. Runs alongside the
11215
+ * `runtime` engine on a DIFFERENT accelerator
11216
+ * (NPU / iGPU / Coral) — this is how the
11217
+ * Engines tab shows all pools running at once.
11184
11218
  */
11185
- kind: _enum(["runtime", "warm-override"]),
11219
+ kind: _enum([
11220
+ "runtime",
11221
+ "warm-override",
11222
+ "device-pool"
11223
+ ]),
11186
11224
  /** Native pid of the underlying Python pool (null when no pool). */
11187
11225
  poolPid: number().nullable(),
11188
11226
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11284,7 +11322,21 @@ var NativeCropResultSchema = object({
11284
11322
  /** Packed rgb (24-bit) pixels of the crop. */
11285
11323
  bytes: _instanceof(Uint8Array),
11286
11324
  width: number().int().positive(),
11287
- height: number().int().positive()
11325
+ height: number().int().positive(),
11326
+ /**
11327
+ * Which source served this crop, so a quality-sensitive consumer (the native
11328
+ * `keyFrame`) can reject a degraded fallback:
11329
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11330
+ * quality path).
11331
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11332
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11333
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11334
+ *
11335
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11336
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11337
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11338
+ */
11339
+ tier: _enum(["native", "ram-fullframe"]).optional()
11288
11340
  });
11289
11341
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11290
11342
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11524,7 +11576,14 @@ var RunnerCameraConfigSchema = object({
11524
11576
  * camera's detect node differs from its source-owner (P2d, gated by the
11525
11577
  * `remoteSourcingNodes` rollout setting).
11526
11578
  */
11527
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11579
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11580
+ /**
11581
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11582
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11583
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11584
+ * this only selects WHICH device pool of that node runs the session.
11585
+ */
11586
+ deviceKey: string().optional()
11528
11587
  });
11529
11588
  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;
11530
11589
  /**
@@ -11545,6 +11604,19 @@ var RunnerLocalLoadSchema = object({
11545
11604
  avgInferenceTimeMs: number(),
11546
11605
  /** Total queue depth across motion + detection queues. */
11547
11606
  queueDepthTotal: number(),
11607
+ /**
11608
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11609
+ * this runner currently has attached cameras on, so the orchestrator's second
11610
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11611
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11612
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11613
+ */
11614
+ devices: array(object({
11615
+ deviceKey: string(),
11616
+ backend: string(),
11617
+ attachedCameras: number(),
11618
+ queueDepthTotal: number()
11619
+ })).default([]),
11548
11620
  /** Hardware capability flags reported by this node. */
11549
11621
  hardware: object({
11550
11622
  hasGpu: boolean(),
@@ -13020,6 +13092,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13020
13092
  kind: "mutation",
13021
13093
  auth: "admin"
13022
13094
  });
13095
+ 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;
13096
+ new Set(Object.values(DeviceType));
13023
13097
  /**
13024
13098
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13025
13099
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14614,7 +14688,8 @@ var LinkedDeviceSchema = object({
14614
14688
  deviceId: number(),
14615
14689
  name: string(),
14616
14690
  location: string().nullable(),
14617
- features: array(string())
14691
+ features: array(string()),
14692
+ producesTrackedEvents: boolean().optional()
14618
14693
  });
14619
14694
  var SavedDeviceRowSchema = object({
14620
14695
  /** Numeric id reserved at allocateDeviceId time. */
@@ -16261,6 +16336,7 @@ var TrackSchema = object({
16261
16336
  deviceId: number(),
16262
16337
  className: string(),
16263
16338
  label: string().optional(),
16339
+ producingDeviceName: string().optional(),
16264
16340
  /** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
16265
16341
  source: TrackSourceSchema.optional(),
16266
16342
  firstSeen: number(),
@@ -16398,7 +16474,8 @@ var MediaFileKindEnum = _enum([
16398
16474
  "fullFrameBoxed",
16399
16475
  "faceCrop",
16400
16476
  "plateCrop",
16401
- "keyFrame"
16477
+ "keyFrame",
16478
+ "keyFrameSmall"
16402
16479
  ]);
16403
16480
  var MediaFileSchema = object({
16404
16481
  key: string(),
@@ -16727,13 +16804,11 @@ var PipelineTemplateSchema = object({
16727
16804
  createdAt: string(),
16728
16805
  updatedAt: string()
16729
16806
  });
16730
- var AgentAddonConfigSchema = object({
16731
- enabled: boolean(),
16807
+ var DeviceStepConfigSchema = object({
16732
16808
  modelId: string().optional(),
16733
- settings: record(string(), unknown()).readonly()
16809
+ settings: record(string(), unknown()).optional()
16734
16810
  });
16735
16811
  var AgentPipelineSettingsSchema = object({
16736
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16737
16812
  maxCameras: number().int().nonnegative().nullable().default(null),
16738
16813
  /** Per-node detection weight (relative share for the quota balancer). */
16739
16814
  detectWeight: number().positive().optional(),
@@ -16757,7 +16832,22 @@ var AgentPipelineSettingsSchema = object({
16757
16832
  * it already uses to reach the hub). Set this only when the auto-detected
16758
16833
  * address is wrong (multi-homed host, NAT, custom interface).
16759
16834
  */
16760
- reachableHost: string().optional()
16835
+ reachableHost: string().optional(),
16836
+ /**
16837
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16838
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16839
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16840
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16841
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16842
+ * the default model/settings for every camera landing on that accelerator;
16843
+ * a stepId absent ⇒ the step uses that device's format default.
16844
+ */
16845
+ inferenceDevices: record(string(), object({
16846
+ enabled: boolean(),
16847
+ weight: number().positive().optional(),
16848
+ maxSessions: number().int().positive().optional(),
16849
+ steps: record(string(), DeviceStepConfigSchema).optional()
16850
+ })).optional()
16761
16851
  });
16762
16852
  var CameraPipelineForAgentSchema = object({
16763
16853
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16767,14 +16857,13 @@ var CameraPipelineForAgentSchema = object({
16767
16857
  }).nullable()
16768
16858
  });
16769
16859
  var CameraStepOverridePatchSchema = object({
16770
- enabled: boolean().optional(),
16771
16860
  modelId: string().optional(),
16772
16861
  settings: record(string(), unknown()).readonly().optional()
16773
16862
  });
16774
16863
  var CameraPipelineSettingsSchema = object({
16775
16864
  pinnedAgentNodeId: string().optional(),
16776
16865
  stepToggles: record(string(), boolean()).optional(),
16777
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16866
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16778
16867
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16779
16868
  });
16780
16869
  /**
@@ -16988,6 +17077,44 @@ var CameraStatusSchema = object({
16988
17077
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
16989
17078
  fetchedAt: number()
16990
17079
  });
17080
+ var NodeInferenceDeviceSchema = object({
17081
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17082
+ key: string(),
17083
+ backend: string(),
17084
+ device: string(),
17085
+ format: _enum(MODEL_FORMATS),
17086
+ /** Whether the node's live probe reports the device as usable right now. */
17087
+ available: boolean(),
17088
+ /**
17089
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17090
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17091
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17092
+ * not a balanced target). An explicit stored value always wins; a stored-only
17093
+ * (unavailable) key keeps its stored value.
17094
+ */
17095
+ enabled: boolean(),
17096
+ /** Relative balancer weight for the enabled device (default 1). */
17097
+ weight: number(),
17098
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17099
+ maxSessions: number().nullable(),
17100
+ /** Object-detection model the executor defaults to for this deviceKey. */
17101
+ defaultModelId: string(),
17102
+ /**
17103
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17104
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17105
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17106
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17107
+ * available per format; this is the stored selection that becomes the
17108
+ * default for EVERY camera landing on this accelerator.
17109
+ */
17110
+ steps: record(string(), DeviceStepConfigSchema).optional()
17111
+ });
17112
+ var NodeInferenceDevicesSchema = object({
17113
+ nodeId: string(),
17114
+ /** False when the node's platform-probe was unreachable (no live device set). */
17115
+ reachable: boolean(),
17116
+ devices: array(NodeInferenceDeviceSchema).readonly()
17117
+ });
16991
17118
  method(object({
16992
17119
  deviceId: number(),
16993
17120
  agentNodeId: string()
@@ -16997,7 +17124,13 @@ method(object({
16997
17124
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
16998
17125
  kind: "mutation",
16999
17126
  auth: "admin"
17000
- }), method(_void(), object({ migrated: number() }), {
17127
+ }), method(object({
17128
+ deviceId: number(),
17129
+ deviceKey: string()
17130
+ }), object({ success: literal(true) }), {
17131
+ kind: "mutation",
17132
+ auth: "admin"
17133
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
17001
17134
  kind: "mutation",
17002
17135
  auth: "admin"
17003
17136
  }), 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({
@@ -17031,13 +17164,7 @@ method(object({
17031
17164
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17032
17165
  nodeId: string(),
17033
17166
  settings: AgentPipelineSettingsSchema
17034
- })).readonly()), method(object({
17035
- agentNodeId: string(),
17036
- defaults: record(string(), AgentAddonConfigSchema)
17037
- }), object({ success: literal(true) }), {
17038
- kind: "mutation",
17039
- auth: "admin"
17040
- }), method(object({ agentNodeId: string() }), object({
17167
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17041
17168
  success: boolean(),
17042
17169
  removed: boolean()
17043
17170
  }), {
@@ -17069,7 +17196,18 @@ method(object({
17069
17196
  }), object({ success: literal(true) }), {
17070
17197
  kind: "mutation",
17071
17198
  auth: "admin"
17072
- }), method(object({ agentNodeId: string() }), object({
17199
+ }), method(object({
17200
+ agentNodeId: string(),
17201
+ inferenceDevices: record(string(), object({
17202
+ enabled: boolean(),
17203
+ weight: number().positive().optional(),
17204
+ maxSessions: number().int().positive().optional(),
17205
+ steps: record(string(), DeviceStepConfigSchema).optional()
17206
+ }))
17207
+ }), object({ success: literal(true) }), {
17208
+ kind: "mutation",
17209
+ auth: "admin"
17210
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17073
17211
  success: literal(true),
17074
17212
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17075
17213
  effectiveModelId: string().nullable(),
@@ -17085,9 +17223,10 @@ method(object({
17085
17223
  }), object({ success: literal(true) }), {
17086
17224
  kind: "mutation",
17087
17225
  auth: "admin"
17088
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17226
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17089
17227
  deviceId: number(),
17090
17228
  agentNodeId: string(),
17229
+ deviceKey: string(),
17091
17230
  addonId: string(),
17092
17231
  patch: CameraStepOverridePatchSchema.nullable()
17093
17232
  }), object({ success: literal(true) }), {
@@ -17124,14 +17263,13 @@ method(object({
17124
17263
  });
17125
17264
  /**
17126
17265
  * server-management — per-NODE singleton capability for a node's ROOT
17127
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17128
- * agents).
17266
+ * package lifecycle (runtime-updatable node packages).
17129
17267
  *
17130
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
17131
- * on agents) carries the whole software stack in its npm dep tree, so ONE
17132
- * version describes the node. Updates install into
17133
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
17134
- * starter (probation boot + auto-rollback to N-1).
17268
+ * Every node role runs the SAME root package (`@camstack/server`), which
17269
+ * carries the whole software stack in its npm dep tree, so ONE version
17270
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17271
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17272
+ * no auto-rollback).
17135
17273
  *
17136
17274
  * Providers:
17137
17275
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17239,7 +17377,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17239
17377
  /** Explicit target version; omitted = latest from the registry. */
17240
17378
  version: string().optional() }), ServerUpdateActionResultSchema, {
17241
17379
  kind: "mutation",
17242
- auth: "admin"
17380
+ auth: "admin",
17381
+ timeoutMs: 16 * 6e4
17243
17382
  }), method(_void(), ServerUpdateActionResultSchema, {
17244
17383
  kind: "mutation",
17245
17384
  auth: "admin"
@@ -18306,22 +18445,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18306
18445
  var RestartAddonResultSchema = unknown();
18307
18446
  var InstallPackageResultSchema = unknown();
18308
18447
  var ReloadPackagesResultSchema = unknown();
18309
- /**
18310
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18311
- * server restarts so the admin UI can react to the `restartingAt`
18312
- * timestamp (shows reconnect overlay). The transition from
18313
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18314
- * `system.restart-completed` event after the new process boots.
18315
- *
18316
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18317
- */
18318
- var UpdateFrameworkPackageResultSchema = object({
18319
- packageName: string(),
18320
- fromVersion: string(),
18321
- toVersion: string(),
18322
- /** Ms-epoch the server scheduled its self-restart. */
18323
- restartingAt: number()
18324
- });
18325
18448
  var BulkUpdateItemStatusSchema = _enum([
18326
18449
  "queued",
18327
18450
  "updating",
@@ -18449,13 +18572,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18449
18572
  }), object({ success: literal(true) }), {
18450
18573
  kind: "mutation",
18451
18574
  auth: "admin"
18452
- }), method(object({
18453
- packageName: string().min(1),
18454
- version: string().optional(),
18455
- deferRestart: boolean().optional()
18456
- }), UpdateFrameworkPackageResultSchema, {
18457
- kind: "mutation",
18458
- auth: "admin"
18459
18575
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18460
18576
  kind: "mutation",
18461
18577
  auth: "admin"
@@ -19321,10 +19437,10 @@ var TopologyCategorySchema = object({
19321
19437
  addons: array(TopologyCategoryAddonSchema).readonly()
19322
19438
  });
19323
19439
  /**
19324
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19325
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19326
- * version visibility for the Server management surface. Nullable: offline
19327
- * rows and pre-phase-2 nodes report none.
19440
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19441
+ * root package for every node role) as reported by its `registerNode`
19442
+ * manifest — version visibility for the Server management surface. Nullable:
19443
+ * offline rows and nodes that never reported one.
19328
19444
  */
19329
19445
  var TopologyRootPackageSchema = object({
19330
19446
  name: string(),
@@ -19712,17 +19828,28 @@ var PlatformScoreSchema = object({
19712
19828
  format: _enum([
19713
19829
  "onnx",
19714
19830
  "coreml",
19715
- "openvino"
19831
+ "openvino",
19832
+ "tflite"
19716
19833
  ]),
19717
19834
  score: number(),
19718
19835
  reason: string(),
19719
19836
  available: boolean()
19720
19837
  });
19838
+ var InferenceDeviceDescriptorSchema = object({
19839
+ key: string(),
19840
+ backend: string(),
19841
+ device: string(),
19842
+ format: ModelFormatSchema,
19843
+ runtime: literal("python"),
19844
+ score: number(),
19845
+ available: boolean()
19846
+ });
19721
19847
  var PlatformCapabilitiesSchema = object({
19722
19848
  hardware: HardwareInfoSchema,
19723
19849
  scores: array(PlatformScoreSchema).readonly(),
19724
19850
  bestScore: PlatformScoreSchema,
19725
- pythonPath: string().nullable()
19851
+ pythonPath: string().nullable(),
19852
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19726
19853
  });
19727
19854
  var ModelRequirementSchema = object({
19728
19855
  modelId: string(),
@@ -20601,12 +20728,6 @@ Object.freeze({
20601
20728
  addonId: null,
20602
20729
  access: "delete"
20603
20730
  },
20604
- "addons.updateFrameworkPackage": {
20605
- capName: "addons",
20606
- capScope: "system",
20607
- addonId: null,
20608
- access: "create"
20609
- },
20610
20731
  "addons.updatePackage": {
20611
20732
  capName: "addons",
20612
20733
  capScope: "system",
@@ -23379,12 +23500,6 @@ Object.freeze({
23379
23500
  addonId: null,
23380
23501
  access: "view"
23381
23502
  },
23382
- "pipelineExecutor.reprobeEngine": {
23383
- capName: "pipeline-executor",
23384
- capScope: "system",
23385
- addonId: null,
23386
- access: "create"
23387
- },
23388
23503
  "pipelineExecutor.runAudioTest": {
23389
23504
  capName: "pipeline-executor",
23390
23505
  capScope: "system",
@@ -23535,6 +23650,12 @@ Object.freeze({
23535
23650
  addonId: null,
23536
23651
  access: "view"
23537
23652
  },
23653
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23654
+ capName: "pipeline-orchestrator",
23655
+ capScope: "system",
23656
+ addonId: null,
23657
+ access: "view"
23658
+ },
23538
23659
  "pipelineOrchestrator.getPipelineAssignment": {
23539
23660
  capName: "pipeline-orchestrator",
23540
23661
  capScope: "system",
@@ -23547,6 +23668,12 @@ Object.freeze({
23547
23668
  addonId: null,
23548
23669
  access: "view"
23549
23670
  },
23671
+ "pipelineOrchestrator.getPipelineDevicePin": {
23672
+ capName: "pipeline-orchestrator",
23673
+ capScope: "system",
23674
+ addonId: null,
23675
+ access: "view"
23676
+ },
23550
23677
  "pipelineOrchestrator.listAgentSettings": {
23551
23678
  capName: "pipeline-orchestrator",
23552
23679
  capScope: "system",
@@ -23589,19 +23716,19 @@ Object.freeze({
23589
23716
  addonId: null,
23590
23717
  access: "create"
23591
23718
  },
23592
- "pipelineOrchestrator.setAgentAddonDefaults": {
23719
+ "pipelineOrchestrator.setAgentCapabilities": {
23593
23720
  capName: "pipeline-orchestrator",
23594
23721
  capScope: "system",
23595
23722
  addonId: null,
23596
23723
  access: "create"
23597
23724
  },
23598
- "pipelineOrchestrator.setAgentCapabilities": {
23725
+ "pipelineOrchestrator.setAgentDetectWeight": {
23599
23726
  capName: "pipeline-orchestrator",
23600
23727
  capScope: "system",
23601
23728
  addonId: null,
23602
23729
  access: "create"
23603
23730
  },
23604
- "pipelineOrchestrator.setAgentDetectWeight": {
23731
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23605
23732
  capName: "pipeline-orchestrator",
23606
23733
  capScope: "system",
23607
23734
  addonId: null,
@@ -23643,6 +23770,12 @@ Object.freeze({
23643
23770
  addonId: null,
23644
23771
  access: "create"
23645
23772
  },
23773
+ "pipelineOrchestrator.setPipelineDevicePin": {
23774
+ capName: "pipeline-orchestrator",
23775
+ capScope: "system",
23776
+ addonId: null,
23777
+ access: "create"
23778
+ },
23646
23779
  "pipelineOrchestrator.unassignAudio": {
23647
23780
  capName: "pipeline-orchestrator",
23648
23781
  capScope: "system",
@@ -25195,32 +25328,6 @@ Object.freeze({
25195
25328
  "network-access": "ingress",
25196
25329
  "smtp-provider": "email"
25197
25330
  });
25198
- var frameworkSwapPackageSchema = object({
25199
- name: string(),
25200
- stagedPath: string(),
25201
- backupPath: string(),
25202
- toVersion: string(),
25203
- fromVersion: string().nullable()
25204
- });
25205
- object({
25206
- jobId: string(),
25207
- taskId: string(),
25208
- packages: array(frameworkSwapPackageSchema),
25209
- requestedAtMs: number(),
25210
- schemaVersion: literal(1)
25211
- });
25212
- object({
25213
- jobId: string(),
25214
- taskId: string(),
25215
- backups: array(object({
25216
- name: string(),
25217
- backupPath: string(),
25218
- livePath: string()
25219
- })),
25220
- appliedAtMs: number(),
25221
- bootAttempts: number(),
25222
- schemaVersion: literal(1)
25223
- });
25224
25331
  //#endregion
25225
25332
  Object.defineProperty(exports, "BaseAddon", {
25226
25333
  enumerable: true,
@@ -21,7 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
- const require_dist = require("../dist-uEQ179pR.js");
24
+ const require_dist = require("../dist-Dj-pqK75.js");
25
25
  let node_path = require("node:path");
26
26
  node_path = __toESM(node_path);
27
27
  let node_crypto = require("node:crypto");
@@ -1,4 +1,4 @@
1
- import { a as BaseAddon, c as boolean, d as number, f as object, m as EventCategory, n as defineCustomActions, o as _enum, p as string, r as networkAccessCapability, s as array, t as customAction, u as literal } from "../dist-CNbtRwT8.mjs";
1
+ import { a as BaseAddon, c as boolean, d as number, f as object, m as EventCategory, n as defineCustomActions, o as _enum, p as string, r as networkAccessCapability, s as array, t as customAction, u as literal } from "../dist-DcLZyoLm.mjs";
2
2
  import * as path from "node:path";
3
3
  import { randomUUID } from "node:crypto";
4
4
  import { spawn } from "node:child_process";
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_dist = require("../dist-uEQ179pR.js");
2
+ const require_dist = require("../dist-Dj-pqK75.js");
3
3
  //#region src/turn/cloudflare-turn.ts
4
4
  /**
5
5
  * Cloudflare returns ICE servers in several flavours depending on which
@@ -1,4 +1,4 @@
1
- import { a as BaseAddon, c as boolean, d as number, f as object, i as turnProviderCapability, l as discriminatedUnion, n as defineCustomActions, p as string, t as customAction, u as literal } from "../dist-CNbtRwT8.mjs";
1
+ import { a as BaseAddon, c as boolean, d as number, f as object, i as turnProviderCapability, l as discriminatedUnion, n as defineCustomActions, p as string, t as customAction, u as literal } from "../dist-DcLZyoLm.mjs";
2
2
  //#region src/turn/cloudflare-turn.ts
3
3
  /**
4
4
  * Cloudflare returns ICE servers in several flavours depending on which
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-cloudflare",
3
- "version": "1.1.29",
3
+ "version": "1.2.1",
4
4
  "description": "Cloudflare bundle — Tunnel (network-access) + TURN relay (turn-provider). Multi-entry npm package shipping 2 addons under a single bundle.",
5
5
  "keywords": [
6
6
  "camstack",