@camstack/addon-smtp-nodemailer 1.1.27 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7105,6 +7105,17 @@ var ModelCatalogEntrySchema = object({
7105
7105
  "imagenet",
7106
7106
  "none"
7107
7107
  ]).optional(),
7108
+ /**
7109
+ * The model already applies softmax IN-GRAPH — its raw output is a
7110
+ * probability distribution, not logits. When set, the `softmax`
7111
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7112
+ * probability vector collapses it toward uniform (top-1 score craters far
7113
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7114
+ * the output is raw logits and the postprocessor applies softmax (the normal
7115
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7116
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7117
+ */
7118
+ outputProbabilities: boolean().optional(),
7108
7119
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7109
7120
  /**
7110
7121
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11118,10 +11129,7 @@ var ConfigUISchemaNullableBridge = custom();
11118
11129
  var InferenceCapabilitiesBridge = custom();
11119
11130
  var ModelAvailabilityListBridge = custom();
11120
11131
  var PipelineRunResultBridge = custom();
11121
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11122
- kind: "mutation",
11123
- auth: "admin"
11124
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11132
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11125
11133
  modelId: string(),
11126
11134
  settings: record(string(), unknown()).readonly()
11127
11135
  }))), method(object({ steps: record(string(), object({
@@ -11181,13 +11189,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11181
11189
  * (inputClasses ≠ null) are skipped and served per-track via
11182
11190
  * pipelineRunner.runDetailSubtree (two-plane design).
11183
11191
  */
11184
- plane: _enum(["full", "frame"]).optional()
11192
+ plane: _enum(["full", "frame"]).optional(),
11193
+ /**
11194
+ * Inference-device selector (Phase 2 multi-device). Format
11195
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11196
+ * Omitted ⇒ the runner's default device (current single-engine
11197
+ * behaviour). Selects WHICH device pool of the node runs the call.
11198
+ */
11199
+ deviceKey: string().optional()
11185
11200
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11186
11201
  engine: PipelineEngineChoiceSchema.optional(),
11187
11202
  steps: array(PipelineStepInputSchema).min(1),
11188
11203
  frames: array(FrameInputSchema).min(1).max(255),
11189
11204
  deviceId: number().optional(),
11190
- sessionId: string().optional()
11205
+ sessionId: string().optional(),
11206
+ /**
11207
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11208
+ * the batch to the Python pool's bench preprocess cache
11209
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11210
+ * preprocessed ONCE and every later inference is a pure-inference cache
11211
+ * hit — the sustained-throughput run measures inference, not
11212
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11213
+ * full preprocess every call, correct). Fresh per sustained run;
11214
+ * released via `uncacheFrame`.
11215
+ */
11216
+ frameId: number().int().nonnegative().optional(),
11217
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11218
+ deviceKey: string().optional()
11191
11219
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11192
11220
  data: _instanceof(Uint8Array),
11193
11221
  width: number().int().positive(),
@@ -11219,8 +11247,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11219
11247
  * - `runtime` — main camera-serving engine (no idle TTL).
11220
11248
  * - `warm-override` — benchmark/test override held in the warm
11221
11249
  * cache; auto-disposed after the idle TTL.
11250
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11251
+ * multi-device, keyed by `deviceKey`) resolved
11252
+ * via `resolveDeviceFactory`. Runs alongside the
11253
+ * `runtime` engine on a DIFFERENT accelerator
11254
+ * (NPU / iGPU / Coral) — this is how the
11255
+ * Engines tab shows all pools running at once.
11222
11256
  */
11223
- kind: _enum(["runtime", "warm-override"]),
11257
+ kind: _enum([
11258
+ "runtime",
11259
+ "warm-override",
11260
+ "device-pool"
11261
+ ]),
11224
11262
  /** Native pid of the underlying Python pool (null when no pool). */
11225
11263
  poolPid: number().nullable(),
11226
11264
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11322,7 +11360,21 @@ var NativeCropResultSchema = object({
11322
11360
  /** Packed rgb (24-bit) pixels of the crop. */
11323
11361
  bytes: _instanceof(Uint8Array),
11324
11362
  width: number().int().positive(),
11325
- height: number().int().positive()
11363
+ height: number().int().positive(),
11364
+ /**
11365
+ * Which source served this crop, so a quality-sensitive consumer (the native
11366
+ * `keyFrame`) can reject a degraded fallback:
11367
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11368
+ * quality path).
11369
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11370
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11371
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11372
+ *
11373
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11374
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11375
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11376
+ */
11377
+ tier: _enum(["native", "ram-fullframe"]).optional()
11326
11378
  });
11327
11379
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11328
11380
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11562,7 +11614,14 @@ var RunnerCameraConfigSchema = object({
11562
11614
  * camera's detect node differs from its source-owner (P2d, gated by the
11563
11615
  * `remoteSourcingNodes` rollout setting).
11564
11616
  */
11565
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11617
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11618
+ /**
11619
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11620
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11621
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11622
+ * this only selects WHICH device pool of that node runs the session.
11623
+ */
11624
+ deviceKey: string().optional()
11566
11625
  });
11567
11626
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11568
11627
  /**
@@ -11583,6 +11642,19 @@ var RunnerLocalLoadSchema = object({
11583
11642
  avgInferenceTimeMs: number(),
11584
11643
  /** Total queue depth across motion + detection queues. */
11585
11644
  queueDepthTotal: number(),
11645
+ /**
11646
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11647
+ * this runner currently has attached cameras on, so the orchestrator's second
11648
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11649
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11650
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11651
+ */
11652
+ devices: array(object({
11653
+ deviceKey: string(),
11654
+ backend: string(),
11655
+ attachedCameras: number(),
11656
+ queueDepthTotal: number()
11657
+ })).default([]),
11586
11658
  /** Hardware capability flags reported by this node. */
11587
11659
  hardware: object({
11588
11660
  hasGpu: boolean(),
@@ -13058,6 +13130,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13058
13130
  kind: "mutation",
13059
13131
  auth: "admin"
13060
13132
  });
13133
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
13134
+ new Set(Object.values(DeviceType));
13061
13135
  /**
13062
13136
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13063
13137
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14631,7 +14705,8 @@ var LinkedDeviceSchema = object({
14631
14705
  deviceId: number(),
14632
14706
  name: string(),
14633
14707
  location: string().nullable(),
14634
- features: array(string())
14708
+ features: array(string()),
14709
+ producesTrackedEvents: boolean().optional()
14635
14710
  });
14636
14711
  var SavedDeviceRowSchema = object({
14637
14712
  /** 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"
@@ -18296,22 +18435,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18296
18435
  var RestartAddonResultSchema = unknown();
18297
18436
  var InstallPackageResultSchema = unknown();
18298
18437
  var ReloadPackagesResultSchema = unknown();
18299
- /**
18300
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18301
- * server restarts so the admin UI can react to the `restartingAt`
18302
- * timestamp (shows reconnect overlay). The transition from
18303
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18304
- * `system.restart-completed` event after the new process boots.
18305
- *
18306
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18307
- */
18308
- var UpdateFrameworkPackageResultSchema = object({
18309
- packageName: string(),
18310
- fromVersion: string(),
18311
- toVersion: string(),
18312
- /** Ms-epoch the server scheduled its self-restart. */
18313
- restartingAt: number()
18314
- });
18315
18438
  var BulkUpdateItemStatusSchema = _enum([
18316
18439
  "queued",
18317
18440
  "updating",
@@ -18439,13 +18562,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18439
18562
  }), object({ success: literal(true) }), {
18440
18563
  kind: "mutation",
18441
18564
  auth: "admin"
18442
- }), method(object({
18443
- packageName: string().min(1),
18444
- version: string().optional(),
18445
- deferRestart: boolean().optional()
18446
- }), UpdateFrameworkPackageResultSchema, {
18447
- kind: "mutation",
18448
- auth: "admin"
18449
18565
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18450
18566
  kind: "mutation",
18451
18567
  auth: "admin"
@@ -19311,10 +19427,10 @@ var TopologyCategorySchema = object({
19311
19427
  addons: array(TopologyCategoryAddonSchema).readonly()
19312
19428
  });
19313
19429
  /**
19314
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19315
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19316
- * version visibility for the Server management surface. Nullable: offline
19317
- * rows and pre-phase-2 nodes report none.
19430
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19431
+ * root package for every node role) as reported by its `registerNode`
19432
+ * manifest — version visibility for the Server management surface. Nullable:
19433
+ * offline rows and nodes that never reported one.
19318
19434
  */
19319
19435
  var TopologyRootPackageSchema = object({
19320
19436
  name: string(),
@@ -19702,17 +19818,28 @@ var PlatformScoreSchema = object({
19702
19818
  format: _enum([
19703
19819
  "onnx",
19704
19820
  "coreml",
19705
- "openvino"
19821
+ "openvino",
19822
+ "tflite"
19706
19823
  ]),
19707
19824
  score: number(),
19708
19825
  reason: string(),
19709
19826
  available: boolean()
19710
19827
  });
19828
+ var InferenceDeviceDescriptorSchema = object({
19829
+ key: string(),
19830
+ backend: string(),
19831
+ device: string(),
19832
+ format: ModelFormatSchema,
19833
+ runtime: literal("python"),
19834
+ score: number(),
19835
+ available: boolean()
19836
+ });
19711
19837
  var PlatformCapabilitiesSchema = object({
19712
19838
  hardware: HardwareInfoSchema,
19713
19839
  scores: array(PlatformScoreSchema).readonly(),
19714
19840
  bestScore: PlatformScoreSchema,
19715
- pythonPath: string().nullable()
19841
+ pythonPath: string().nullable(),
19842
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19716
19843
  });
19717
19844
  var ModelRequirementSchema = object({
19718
19845
  modelId: string(),
@@ -20591,12 +20718,6 @@ Object.freeze({
20591
20718
  addonId: null,
20592
20719
  access: "delete"
20593
20720
  },
20594
- "addons.updateFrameworkPackage": {
20595
- capName: "addons",
20596
- capScope: "system",
20597
- addonId: null,
20598
- access: "create"
20599
- },
20600
20721
  "addons.updatePackage": {
20601
20722
  capName: "addons",
20602
20723
  capScope: "system",
@@ -23369,12 +23490,6 @@ Object.freeze({
23369
23490
  addonId: null,
23370
23491
  access: "view"
23371
23492
  },
23372
- "pipelineExecutor.reprobeEngine": {
23373
- capName: "pipeline-executor",
23374
- capScope: "system",
23375
- addonId: null,
23376
- access: "create"
23377
- },
23378
23493
  "pipelineExecutor.runAudioTest": {
23379
23494
  capName: "pipeline-executor",
23380
23495
  capScope: "system",
@@ -23525,6 +23640,12 @@ Object.freeze({
23525
23640
  addonId: null,
23526
23641
  access: "view"
23527
23642
  },
23643
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23644
+ capName: "pipeline-orchestrator",
23645
+ capScope: "system",
23646
+ addonId: null,
23647
+ access: "view"
23648
+ },
23528
23649
  "pipelineOrchestrator.getPipelineAssignment": {
23529
23650
  capName: "pipeline-orchestrator",
23530
23651
  capScope: "system",
@@ -23537,6 +23658,12 @@ Object.freeze({
23537
23658
  addonId: null,
23538
23659
  access: "view"
23539
23660
  },
23661
+ "pipelineOrchestrator.getPipelineDevicePin": {
23662
+ capName: "pipeline-orchestrator",
23663
+ capScope: "system",
23664
+ addonId: null,
23665
+ access: "view"
23666
+ },
23540
23667
  "pipelineOrchestrator.listAgentSettings": {
23541
23668
  capName: "pipeline-orchestrator",
23542
23669
  capScope: "system",
@@ -23579,19 +23706,19 @@ Object.freeze({
23579
23706
  addonId: null,
23580
23707
  access: "create"
23581
23708
  },
23582
- "pipelineOrchestrator.setAgentAddonDefaults": {
23709
+ "pipelineOrchestrator.setAgentCapabilities": {
23583
23710
  capName: "pipeline-orchestrator",
23584
23711
  capScope: "system",
23585
23712
  addonId: null,
23586
23713
  access: "create"
23587
23714
  },
23588
- "pipelineOrchestrator.setAgentCapabilities": {
23715
+ "pipelineOrchestrator.setAgentDetectWeight": {
23589
23716
  capName: "pipeline-orchestrator",
23590
23717
  capScope: "system",
23591
23718
  addonId: null,
23592
23719
  access: "create"
23593
23720
  },
23594
- "pipelineOrchestrator.setAgentDetectWeight": {
23721
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23595
23722
  capName: "pipeline-orchestrator",
23596
23723
  capScope: "system",
23597
23724
  addonId: null,
@@ -23633,6 +23760,12 @@ Object.freeze({
23633
23760
  addonId: null,
23634
23761
  access: "create"
23635
23762
  },
23763
+ "pipelineOrchestrator.setPipelineDevicePin": {
23764
+ capName: "pipeline-orchestrator",
23765
+ capScope: "system",
23766
+ addonId: null,
23767
+ access: "create"
23768
+ },
23636
23769
  "pipelineOrchestrator.unassignAudio": {
23637
23770
  capName: "pipeline-orchestrator",
23638
23771
  capScope: "system",
@@ -25185,32 +25318,6 @@ Object.freeze({
25185
25318
  "network-access": "ingress",
25186
25319
  "smtp-provider": "email"
25187
25320
  });
25188
- var frameworkSwapPackageSchema = object({
25189
- name: string(),
25190
- stagedPath: string(),
25191
- backupPath: string(),
25192
- toVersion: string(),
25193
- fromVersion: string().nullable()
25194
- });
25195
- object({
25196
- jobId: string(),
25197
- taskId: string(),
25198
- packages: array(frameworkSwapPackageSchema),
25199
- requestedAtMs: number(),
25200
- schemaVersion: literal(1)
25201
- });
25202
- object({
25203
- jobId: string(),
25204
- taskId: string(),
25205
- backups: array(object({
25206
- name: string(),
25207
- backupPath: string(),
25208
- livePath: string()
25209
- })),
25210
- appliedAtMs: number(),
25211
- bootAttempts: number(),
25212
- schemaVersion: literal(1)
25213
- });
25214
25321
  //#endregion
25215
25322
  //#region ../../node_modules/nodemailer/lib/punycode/index.js
25216
25323
  var require_punycode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -7103,6 +7103,17 @@ var ModelCatalogEntrySchema = object({
7103
7103
  "imagenet",
7104
7104
  "none"
7105
7105
  ]).optional(),
7106
+ /**
7107
+ * The model already applies softmax IN-GRAPH — its raw output is a
7108
+ * probability distribution, not logits. When set, the `softmax`
7109
+ * postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
7110
+ * probability vector collapses it toward uniform (top-1 score craters far
7111
+ * below its true value, making every confidence gate meaningless). Absent ⇒
7112
+ * the output is raw logits and the postprocessor applies softmax (the normal
7113
+ * case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
7114
+ * TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
7115
+ */
7116
+ outputProbabilities: boolean().optional(),
7106
7117
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7107
7118
  /**
7108
7119
  * Per-MODEL postprocessor override. Absent ⇒ the step's own
@@ -11116,10 +11127,7 @@ var ConfigUISchemaNullableBridge = custom();
11116
11127
  var InferenceCapabilitiesBridge = custom();
11117
11128
  var ModelAvailabilityListBridge = custom();
11118
11129
  var PipelineRunResultBridge = custom();
11119
- method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(_void(), PipelineEngineChoiceSchema, {
11120
- kind: "mutation",
11121
- auth: "admin"
11122
- }), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11130
+ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
11123
11131
  modelId: string(),
11124
11132
  settings: record(string(), unknown()).readonly()
11125
11133
  }))), method(object({ steps: record(string(), object({
@@ -11179,13 +11187,33 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11179
11187
  * (inputClasses ≠ null) are skipped and served per-track via
11180
11188
  * pipelineRunner.runDetailSubtree (two-plane design).
11181
11189
  */
11182
- plane: _enum(["full", "frame"]).optional()
11190
+ plane: _enum(["full", "frame"]).optional(),
11191
+ /**
11192
+ * Inference-device selector (Phase 2 multi-device). Format
11193
+ * `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
11194
+ * Omitted ⇒ the runner's default device (current single-engine
11195
+ * behaviour). Selects WHICH device pool of the node runs the call.
11196
+ */
11197
+ deviceKey: string().optional()
11183
11198
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
11184
11199
  engine: PipelineEngineChoiceSchema.optional(),
11185
11200
  steps: array(PipelineStepInputSchema).min(1),
11186
11201
  frames: array(FrameInputSchema).min(1).max(255),
11187
11202
  deviceId: number().optional(),
11188
- sessionId: string().optional()
11203
+ sessionId: string().optional(),
11204
+ /**
11205
+ * Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
11206
+ * the batch to the Python pool's bench preprocess cache
11207
+ * (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
11208
+ * preprocessed ONCE and every later inference is a pure-inference cache
11209
+ * hit — the sustained-throughput run measures inference, not
11210
+ * decode+preprocess+infer. Omitted/0 for live frames (all different →
11211
+ * full preprocess every call, correct). Fresh per sustained run;
11212
+ * released via `uncacheFrame`.
11213
+ */
11214
+ frameId: number().int().nonnegative().optional(),
11215
+ /** Inference-device selector (Phase 2 multi-device); see runPipeline. */
11216
+ deviceKey: string().optional()
11189
11217
  }), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
11190
11218
  data: _instanceof(Uint8Array),
11191
11219
  width: number().int().positive(),
@@ -11217,8 +11245,18 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
11217
11245
  * - `runtime` — main camera-serving engine (no idle TTL).
11218
11246
  * - `warm-override` — benchmark/test override held in the warm
11219
11247
  * cache; auto-disposed after the idle TTL.
11248
+ * - `device-pool` — a concurrent per-device pool (Phase 2
11249
+ * multi-device, keyed by `deviceKey`) resolved
11250
+ * via `resolveDeviceFactory`. Runs alongside the
11251
+ * `runtime` engine on a DIFFERENT accelerator
11252
+ * (NPU / iGPU / Coral) — this is how the
11253
+ * Engines tab shows all pools running at once.
11220
11254
  */
11221
- kind: _enum(["runtime", "warm-override"]),
11255
+ kind: _enum([
11256
+ "runtime",
11257
+ "warm-override",
11258
+ "device-pool"
11259
+ ]),
11222
11260
  /** Native pid of the underlying Python pool (null when no pool). */
11223
11261
  poolPid: number().nullable(),
11224
11262
  /** ms since this factory was last used (null when not warm-tracked). */
@@ -11320,7 +11358,21 @@ var NativeCropResultSchema = object({
11320
11358
  /** Packed rgb (24-bit) pixels of the crop. */
11321
11359
  bytes: _instanceof(Uint8Array),
11322
11360
  width: number().int().positive(),
11323
- height: number().int().positive()
11361
+ height: number().int().positive(),
11362
+ /**
11363
+ * Which source served this crop, so a quality-sensitive consumer (the native
11364
+ * `keyFrame`) can reject a degraded fallback:
11365
+ * - `native` — cut from the decode worker's retained NATIVE surface (the
11366
+ * quality path).
11367
+ * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
11368
+ * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
11369
+ * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
11370
+ *
11371
+ * OPTIONAL: a pre-tier runner (version skew) omits it — an ABSENT `tier` MUST be
11372
+ * treated as `native` (accepted) by every consumer so mixed-version clusters
11373
+ * keep the pre-tier behaviour. An ROI miss returns `null` (no tier at all).
11374
+ */
11375
+ tier: _enum(["native", "ram-fullframe"]).optional()
11324
11376
  });
11325
11377
  /** Parent detection context passed to `runDetailSubtree` — the crop's
11326
11378
  * originating detection, in FRAME-space coordinates. Reuses
@@ -11560,7 +11612,14 @@ var RunnerCameraConfigSchema = object({
11560
11612
  * camera's detect node differs from its source-owner (P2d, gated by the
11561
11613
  * `remoteSourcingNodes` rollout setting).
11562
11614
  */
11563
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11615
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11616
+ /**
11617
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11618
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11619
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11620
+ * this only selects WHICH device pool of that node runs the session.
11621
+ */
11622
+ deviceKey: string().optional()
11564
11623
  });
11565
11624
  motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
11566
11625
  /**
@@ -11581,6 +11640,19 @@ var RunnerLocalLoadSchema = object({
11581
11640
  avgInferenceTimeMs: number(),
11582
11641
  /** Total queue depth across motion + detection queues. */
11583
11642
  queueDepthTotal: number(),
11643
+ /**
11644
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11645
+ * this runner currently has attached cameras on, so the orchestrator's second
11646
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11647
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11648
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11649
+ */
11650
+ devices: array(object({
11651
+ deviceKey: string(),
11652
+ backend: string(),
11653
+ attachedCameras: number(),
11654
+ queueDepthTotal: number()
11655
+ })).default([]),
11584
11656
  /** Hardware capability flags reported by this node. */
11585
11657
  hardware: object({
11586
11658
  hasGpu: boolean(),
@@ -13056,6 +13128,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13056
13128
  kind: "mutation",
13057
13129
  auth: "admin"
13058
13130
  });
13131
+ DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
13132
+ new Set(Object.values(DeviceType));
13059
13133
  /**
13060
13134
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13061
13135
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -14629,7 +14703,8 @@ var LinkedDeviceSchema = object({
14629
14703
  deviceId: number(),
14630
14704
  name: string(),
14631
14705
  location: string().nullable(),
14632
- features: array(string())
14706
+ features: array(string()),
14707
+ producesTrackedEvents: boolean().optional()
14633
14708
  });
14634
14709
  var SavedDeviceRowSchema = object({
14635
14710
  /** Numeric id reserved at allocateDeviceId time. */
@@ -16259,6 +16334,7 @@ var TrackSchema = object({
16259
16334
  deviceId: number(),
16260
16335
  className: string(),
16261
16336
  label: string().optional(),
16337
+ producingDeviceName: string().optional(),
16262
16338
  /** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
16263
16339
  source: TrackSourceSchema.optional(),
16264
16340
  firstSeen: number(),
@@ -16396,7 +16472,8 @@ var MediaFileKindEnum = _enum([
16396
16472
  "fullFrameBoxed",
16397
16473
  "faceCrop",
16398
16474
  "plateCrop",
16399
- "keyFrame"
16475
+ "keyFrame",
16476
+ "keyFrameSmall"
16400
16477
  ]);
16401
16478
  var MediaFileSchema = object({
16402
16479
  key: string(),
@@ -16725,13 +16802,11 @@ var PipelineTemplateSchema = object({
16725
16802
  createdAt: string(),
16726
16803
  updatedAt: string()
16727
16804
  });
16728
- var AgentAddonConfigSchema = object({
16729
- enabled: boolean(),
16805
+ var DeviceStepConfigSchema = object({
16730
16806
  modelId: string().optional(),
16731
- settings: record(string(), unknown()).readonly()
16807
+ settings: record(string(), unknown()).optional()
16732
16808
  });
16733
16809
  var AgentPipelineSettingsSchema = object({
16734
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16735
16810
  maxCameras: number().int().nonnegative().nullable().default(null),
16736
16811
  /** Per-node detection weight (relative share for the quota balancer). */
16737
16812
  detectWeight: number().positive().optional(),
@@ -16755,7 +16830,22 @@ var AgentPipelineSettingsSchema = object({
16755
16830
  * it already uses to reach the hub). Set this only when the auto-detected
16756
16831
  * address is wrong (multi-homed host, NAT, custom interface).
16757
16832
  */
16758
- reachableHost: string().optional()
16833
+ reachableHost: string().optional(),
16834
+ /**
16835
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16836
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16837
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16838
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16839
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16840
+ * the default model/settings for every camera landing on that accelerator;
16841
+ * a stepId absent ⇒ the step uses that device's format default.
16842
+ */
16843
+ inferenceDevices: record(string(), object({
16844
+ enabled: boolean(),
16845
+ weight: number().positive().optional(),
16846
+ maxSessions: number().int().positive().optional(),
16847
+ steps: record(string(), DeviceStepConfigSchema).optional()
16848
+ })).optional()
16759
16849
  });
16760
16850
  var CameraPipelineForAgentSchema = object({
16761
16851
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16765,14 +16855,13 @@ var CameraPipelineForAgentSchema = object({
16765
16855
  }).nullable()
16766
16856
  });
16767
16857
  var CameraStepOverridePatchSchema = object({
16768
- enabled: boolean().optional(),
16769
16858
  modelId: string().optional(),
16770
16859
  settings: record(string(), unknown()).readonly().optional()
16771
16860
  });
16772
16861
  var CameraPipelineSettingsSchema = object({
16773
16862
  pinnedAgentNodeId: string().optional(),
16774
16863
  stepToggles: record(string(), boolean()).optional(),
16775
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16864
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16776
16865
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16777
16866
  });
16778
16867
  /**
@@ -16986,6 +17075,44 @@ var CameraStatusSchema = object({
16986
17075
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
16987
17076
  fetchedAt: number()
16988
17077
  });
17078
+ var NodeInferenceDeviceSchema = object({
17079
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17080
+ key: string(),
17081
+ backend: string(),
17082
+ device: string(),
17083
+ format: _enum(MODEL_FORMATS),
17084
+ /** Whether the node's live probe reports the device as usable right now. */
17085
+ available: boolean(),
17086
+ /**
17087
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17088
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17089
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17090
+ * not a balanced target). An explicit stored value always wins; a stored-only
17091
+ * (unavailable) key keeps its stored value.
17092
+ */
17093
+ enabled: boolean(),
17094
+ /** Relative balancer weight for the enabled device (default 1). */
17095
+ weight: number(),
17096
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17097
+ maxSessions: number().nullable(),
17098
+ /** Object-detection model the executor defaults to for this deviceKey. */
17099
+ defaultModelId: string(),
17100
+ /**
17101
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17102
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17103
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17104
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17105
+ * available per format; this is the stored selection that becomes the
17106
+ * default for EVERY camera landing on this accelerator.
17107
+ */
17108
+ steps: record(string(), DeviceStepConfigSchema).optional()
17109
+ });
17110
+ var NodeInferenceDevicesSchema = object({
17111
+ nodeId: string(),
17112
+ /** False when the node's platform-probe was unreachable (no live device set). */
17113
+ reachable: boolean(),
17114
+ devices: array(NodeInferenceDeviceSchema).readonly()
17115
+ });
16989
17116
  method(object({
16990
17117
  deviceId: number(),
16991
17118
  agentNodeId: string()
@@ -16995,7 +17122,13 @@ method(object({
16995
17122
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
16996
17123
  kind: "mutation",
16997
17124
  auth: "admin"
16998
- }), method(_void(), object({ migrated: number() }), {
17125
+ }), method(object({
17126
+ deviceId: number(),
17127
+ deviceKey: string()
17128
+ }), object({ success: literal(true) }), {
17129
+ kind: "mutation",
17130
+ auth: "admin"
17131
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
16999
17132
  kind: "mutation",
17000
17133
  auth: "admin"
17001
17134
  }), 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({
@@ -17029,13 +17162,7 @@ method(object({
17029
17162
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17030
17163
  nodeId: string(),
17031
17164
  settings: AgentPipelineSettingsSchema
17032
- })).readonly()), method(object({
17033
- agentNodeId: string(),
17034
- defaults: record(string(), AgentAddonConfigSchema)
17035
- }), object({ success: literal(true) }), {
17036
- kind: "mutation",
17037
- auth: "admin"
17038
- }), method(object({ agentNodeId: string() }), object({
17165
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17039
17166
  success: boolean(),
17040
17167
  removed: boolean()
17041
17168
  }), {
@@ -17067,7 +17194,18 @@ method(object({
17067
17194
  }), object({ success: literal(true) }), {
17068
17195
  kind: "mutation",
17069
17196
  auth: "admin"
17070
- }), method(object({ agentNodeId: string() }), object({
17197
+ }), method(object({
17198
+ agentNodeId: string(),
17199
+ inferenceDevices: record(string(), object({
17200
+ enabled: boolean(),
17201
+ weight: number().positive().optional(),
17202
+ maxSessions: number().int().positive().optional(),
17203
+ steps: record(string(), DeviceStepConfigSchema).optional()
17204
+ }))
17205
+ }), object({ success: literal(true) }), {
17206
+ kind: "mutation",
17207
+ auth: "admin"
17208
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17071
17209
  success: literal(true),
17072
17210
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17073
17211
  effectiveModelId: string().nullable(),
@@ -17083,9 +17221,10 @@ method(object({
17083
17221
  }), object({ success: literal(true) }), {
17084
17222
  kind: "mutation",
17085
17223
  auth: "admin"
17086
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17224
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17087
17225
  deviceId: number(),
17088
17226
  agentNodeId: string(),
17227
+ deviceKey: string(),
17089
17228
  addonId: string(),
17090
17229
  patch: CameraStepOverridePatchSchema.nullable()
17091
17230
  }), object({ success: literal(true) }), {
@@ -17122,14 +17261,13 @@ method(object({
17122
17261
  });
17123
17262
  /**
17124
17263
  * server-management — per-NODE singleton capability for a node's ROOT
17125
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17126
- * agents).
17264
+ * package lifecycle (runtime-updatable node packages).
17127
17265
  *
17128
- * Each node's root package (`@camstack/server` on the hub, `@camstack/agent`
17129
- * on agents) carries the whole software stack in its npm dep tree, so ONE
17130
- * version describes the node. Updates install into
17131
- * `<dataDir>/server-root/versions/<v>/` and apply on restart via the baked
17132
- * starter (probation boot + auto-rollback to N-1).
17266
+ * Every node role runs the SAME root package (`@camstack/server`), which
17267
+ * carries the whole software stack in its npm dep tree, so ONE version
17268
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17269
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17270
+ * no auto-rollback).
17133
17271
  *
17134
17272
  * Providers:
17135
17273
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17237,7 +17375,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17237
17375
  /** Explicit target version; omitted = latest from the registry. */
17238
17376
  version: string().optional() }), ServerUpdateActionResultSchema, {
17239
17377
  kind: "mutation",
17240
- auth: "admin"
17378
+ auth: "admin",
17379
+ timeoutMs: 16 * 6e4
17241
17380
  }), method(_void(), ServerUpdateActionResultSchema, {
17242
17381
  kind: "mutation",
17243
17382
  auth: "admin"
@@ -18294,22 +18433,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18294
18433
  var RestartAddonResultSchema = unknown();
18295
18434
  var InstallPackageResultSchema = unknown();
18296
18435
  var ReloadPackagesResultSchema = unknown();
18297
- /**
18298
- * Result of `updateFrameworkPackage`. The cap method returns BEFORE the
18299
- * server restarts so the admin UI can react to the `restartingAt`
18300
- * timestamp (shows reconnect overlay). The transition from
18301
- * `fromVersion` to `toVersion` will be confirmed by a subsequent
18302
- * `system.restart-completed` event after the new process boots.
18303
- *
18304
- * Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
18305
- */
18306
- var UpdateFrameworkPackageResultSchema = object({
18307
- packageName: string(),
18308
- fromVersion: string(),
18309
- toVersion: string(),
18310
- /** Ms-epoch the server scheduled its self-restart. */
18311
- restartingAt: number()
18312
- });
18313
18436
  var BulkUpdateItemStatusSchema = _enum([
18314
18437
  "queued",
18315
18438
  "updating",
@@ -18437,13 +18560,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18437
18560
  }), object({ success: literal(true) }), {
18438
18561
  kind: "mutation",
18439
18562
  auth: "admin"
18440
- }), method(object({
18441
- packageName: string().min(1),
18442
- version: string().optional(),
18443
- deferRestart: boolean().optional()
18444
- }), UpdateFrameworkPackageResultSchema, {
18445
- kind: "mutation",
18446
- auth: "admin"
18447
18563
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18448
18564
  kind: "mutation",
18449
18565
  auth: "admin"
@@ -19309,10 +19425,10 @@ var TopologyCategorySchema = object({
19309
19425
  addons: array(TopologyCategoryAddonSchema).readonly()
19310
19426
  });
19311
19427
  /**
19312
- * The node's runtime-updatable ROOT package (`@camstack/server` on the hub,
19313
- * `@camstack/agent` on agents) as reported by its `registerNode` manifest —
19314
- * version visibility for the Server management surface. Nullable: offline
19315
- * rows and pre-phase-2 nodes report none.
19428
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19429
+ * root package for every node role) as reported by its `registerNode`
19430
+ * manifest — version visibility for the Server management surface. Nullable:
19431
+ * offline rows and nodes that never reported one.
19316
19432
  */
19317
19433
  var TopologyRootPackageSchema = object({
19318
19434
  name: string(),
@@ -19700,17 +19816,28 @@ var PlatformScoreSchema = object({
19700
19816
  format: _enum([
19701
19817
  "onnx",
19702
19818
  "coreml",
19703
- "openvino"
19819
+ "openvino",
19820
+ "tflite"
19704
19821
  ]),
19705
19822
  score: number(),
19706
19823
  reason: string(),
19707
19824
  available: boolean()
19708
19825
  });
19826
+ var InferenceDeviceDescriptorSchema = object({
19827
+ key: string(),
19828
+ backend: string(),
19829
+ device: string(),
19830
+ format: ModelFormatSchema,
19831
+ runtime: literal("python"),
19832
+ score: number(),
19833
+ available: boolean()
19834
+ });
19709
19835
  var PlatformCapabilitiesSchema = object({
19710
19836
  hardware: HardwareInfoSchema,
19711
19837
  scores: array(PlatformScoreSchema).readonly(),
19712
19838
  bestScore: PlatformScoreSchema,
19713
- pythonPath: string().nullable()
19839
+ pythonPath: string().nullable(),
19840
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19714
19841
  });
19715
19842
  var ModelRequirementSchema = object({
19716
19843
  modelId: string(),
@@ -20589,12 +20716,6 @@ Object.freeze({
20589
20716
  addonId: null,
20590
20717
  access: "delete"
20591
20718
  },
20592
- "addons.updateFrameworkPackage": {
20593
- capName: "addons",
20594
- capScope: "system",
20595
- addonId: null,
20596
- access: "create"
20597
- },
20598
20719
  "addons.updatePackage": {
20599
20720
  capName: "addons",
20600
20721
  capScope: "system",
@@ -23367,12 +23488,6 @@ Object.freeze({
23367
23488
  addonId: null,
23368
23489
  access: "view"
23369
23490
  },
23370
- "pipelineExecutor.reprobeEngine": {
23371
- capName: "pipeline-executor",
23372
- capScope: "system",
23373
- addonId: null,
23374
- access: "create"
23375
- },
23376
23491
  "pipelineExecutor.runAudioTest": {
23377
23492
  capName: "pipeline-executor",
23378
23493
  capScope: "system",
@@ -23523,6 +23638,12 @@ Object.freeze({
23523
23638
  addonId: null,
23524
23639
  access: "view"
23525
23640
  },
23641
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23642
+ capName: "pipeline-orchestrator",
23643
+ capScope: "system",
23644
+ addonId: null,
23645
+ access: "view"
23646
+ },
23526
23647
  "pipelineOrchestrator.getPipelineAssignment": {
23527
23648
  capName: "pipeline-orchestrator",
23528
23649
  capScope: "system",
@@ -23535,6 +23656,12 @@ Object.freeze({
23535
23656
  addonId: null,
23536
23657
  access: "view"
23537
23658
  },
23659
+ "pipelineOrchestrator.getPipelineDevicePin": {
23660
+ capName: "pipeline-orchestrator",
23661
+ capScope: "system",
23662
+ addonId: null,
23663
+ access: "view"
23664
+ },
23538
23665
  "pipelineOrchestrator.listAgentSettings": {
23539
23666
  capName: "pipeline-orchestrator",
23540
23667
  capScope: "system",
@@ -23577,19 +23704,19 @@ Object.freeze({
23577
23704
  addonId: null,
23578
23705
  access: "create"
23579
23706
  },
23580
- "pipelineOrchestrator.setAgentAddonDefaults": {
23707
+ "pipelineOrchestrator.setAgentCapabilities": {
23581
23708
  capName: "pipeline-orchestrator",
23582
23709
  capScope: "system",
23583
23710
  addonId: null,
23584
23711
  access: "create"
23585
23712
  },
23586
- "pipelineOrchestrator.setAgentCapabilities": {
23713
+ "pipelineOrchestrator.setAgentDetectWeight": {
23587
23714
  capName: "pipeline-orchestrator",
23588
23715
  capScope: "system",
23589
23716
  addonId: null,
23590
23717
  access: "create"
23591
23718
  },
23592
- "pipelineOrchestrator.setAgentDetectWeight": {
23719
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23593
23720
  capName: "pipeline-orchestrator",
23594
23721
  capScope: "system",
23595
23722
  addonId: null,
@@ -23631,6 +23758,12 @@ Object.freeze({
23631
23758
  addonId: null,
23632
23759
  access: "create"
23633
23760
  },
23761
+ "pipelineOrchestrator.setPipelineDevicePin": {
23762
+ capName: "pipeline-orchestrator",
23763
+ capScope: "system",
23764
+ addonId: null,
23765
+ access: "create"
23766
+ },
23634
23767
  "pipelineOrchestrator.unassignAudio": {
23635
23768
  capName: "pipeline-orchestrator",
23636
23769
  capScope: "system",
@@ -25183,32 +25316,6 @@ Object.freeze({
25183
25316
  "network-access": "ingress",
25184
25317
  "smtp-provider": "email"
25185
25318
  });
25186
- var frameworkSwapPackageSchema = object({
25187
- name: string(),
25188
- stagedPath: string(),
25189
- backupPath: string(),
25190
- toVersion: string(),
25191
- fromVersion: string().nullable()
25192
- });
25193
- object({
25194
- jobId: string(),
25195
- taskId: string(),
25196
- packages: array(frameworkSwapPackageSchema),
25197
- requestedAtMs: number(),
25198
- schemaVersion: literal(1)
25199
- });
25200
- object({
25201
- jobId: string(),
25202
- taskId: string(),
25203
- backups: array(object({
25204
- name: string(),
25205
- backupPath: string(),
25206
- livePath: string()
25207
- })),
25208
- appliedAtMs: number(),
25209
- bootAttempts: number(),
25210
- schemaVersion: literal(1)
25211
- });
25212
25319
  //#endregion
25213
25320
  //#region ../../node_modules/nodemailer/lib/punycode/index.js
25214
25321
  var require_punycode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-smtp-nodemailer",
3
- "version": "1.1.27",
3
+ "version": "1.2.1",
4
4
  "description": "SMTP email provider addon for CamStack — wraps `nodemailer` and registers a `smtp-provider` cap collection entry. Used by magic-link login + notifier addons.",
5
5
  "keywords": [
6
6
  "camstack",