@camstack/addon-smtp-nodemailer 1.1.27 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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). */
@@ -11562,7 +11600,14 @@ var RunnerCameraConfigSchema = object({
11562
11600
  * camera's detect node differs from its source-owner (P2d, gated by the
11563
11601
  * `remoteSourcingNodes` rollout setting).
11564
11602
  */
11565
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11603
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11604
+ /**
11605
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11606
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11607
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11608
+ * this only selects WHICH device pool of that node runs the session.
11609
+ */
11610
+ deviceKey: string().optional()
11566
11611
  });
11567
11612
  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
11613
  /**
@@ -11583,6 +11628,19 @@ var RunnerLocalLoadSchema = object({
11583
11628
  avgInferenceTimeMs: number(),
11584
11629
  /** Total queue depth across motion + detection queues. */
11585
11630
  queueDepthTotal: number(),
11631
+ /**
11632
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11633
+ * this runner currently has attached cameras on, so the orchestrator's second
11634
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11635
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11636
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11637
+ */
11638
+ devices: array(object({
11639
+ deviceKey: string(),
11640
+ backend: string(),
11641
+ attachedCameras: number(),
11642
+ queueDepthTotal: number()
11643
+ })).default([]),
11586
11644
  /** Hardware capability flags reported by this node. */
11587
11645
  hardware: object({
11588
11646
  hasGpu: boolean(),
@@ -13058,6 +13116,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13058
13116
  kind: "mutation",
13059
13117
  auth: "admin"
13060
13118
  });
13119
+ 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;
13120
+ new Set(Object.values(DeviceType));
13061
13121
  /**
13062
13122
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13063
13123
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -16727,13 +16787,11 @@ var PipelineTemplateSchema = object({
16727
16787
  createdAt: string(),
16728
16788
  updatedAt: string()
16729
16789
  });
16730
- var AgentAddonConfigSchema = object({
16731
- enabled: boolean(),
16790
+ var DeviceStepConfigSchema = object({
16732
16791
  modelId: string().optional(),
16733
- settings: record(string(), unknown()).readonly()
16792
+ settings: record(string(), unknown()).optional()
16734
16793
  });
16735
16794
  var AgentPipelineSettingsSchema = object({
16736
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16737
16795
  maxCameras: number().int().nonnegative().nullable().default(null),
16738
16796
  /** Per-node detection weight (relative share for the quota balancer). */
16739
16797
  detectWeight: number().positive().optional(),
@@ -16757,7 +16815,22 @@ var AgentPipelineSettingsSchema = object({
16757
16815
  * it already uses to reach the hub). Set this only when the auto-detected
16758
16816
  * address is wrong (multi-homed host, NAT, custom interface).
16759
16817
  */
16760
- reachableHost: string().optional()
16818
+ reachableHost: string().optional(),
16819
+ /**
16820
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16821
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16822
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16823
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16824
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16825
+ * the default model/settings for every camera landing on that accelerator;
16826
+ * a stepId absent ⇒ the step uses that device's format default.
16827
+ */
16828
+ inferenceDevices: record(string(), object({
16829
+ enabled: boolean(),
16830
+ weight: number().positive().optional(),
16831
+ maxSessions: number().int().positive().optional(),
16832
+ steps: record(string(), DeviceStepConfigSchema).optional()
16833
+ })).optional()
16761
16834
  });
16762
16835
  var CameraPipelineForAgentSchema = object({
16763
16836
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16767,14 +16840,13 @@ var CameraPipelineForAgentSchema = object({
16767
16840
  }).nullable()
16768
16841
  });
16769
16842
  var CameraStepOverridePatchSchema = object({
16770
- enabled: boolean().optional(),
16771
16843
  modelId: string().optional(),
16772
16844
  settings: record(string(), unknown()).readonly().optional()
16773
16845
  });
16774
16846
  var CameraPipelineSettingsSchema = object({
16775
16847
  pinnedAgentNodeId: string().optional(),
16776
16848
  stepToggles: record(string(), boolean()).optional(),
16777
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16849
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16778
16850
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16779
16851
  });
16780
16852
  /**
@@ -16988,6 +17060,44 @@ var CameraStatusSchema = object({
16988
17060
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
16989
17061
  fetchedAt: number()
16990
17062
  });
17063
+ var NodeInferenceDeviceSchema = object({
17064
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17065
+ key: string(),
17066
+ backend: string(),
17067
+ device: string(),
17068
+ format: _enum(MODEL_FORMATS),
17069
+ /** Whether the node's live probe reports the device as usable right now. */
17070
+ available: boolean(),
17071
+ /**
17072
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17073
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17074
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17075
+ * not a balanced target). An explicit stored value always wins; a stored-only
17076
+ * (unavailable) key keeps its stored value.
17077
+ */
17078
+ enabled: boolean(),
17079
+ /** Relative balancer weight for the enabled device (default 1). */
17080
+ weight: number(),
17081
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17082
+ maxSessions: number().nullable(),
17083
+ /** Object-detection model the executor defaults to for this deviceKey. */
17084
+ defaultModelId: string(),
17085
+ /**
17086
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17087
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17088
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17089
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17090
+ * available per format; this is the stored selection that becomes the
17091
+ * default for EVERY camera landing on this accelerator.
17092
+ */
17093
+ steps: record(string(), DeviceStepConfigSchema).optional()
17094
+ });
17095
+ var NodeInferenceDevicesSchema = object({
17096
+ nodeId: string(),
17097
+ /** False when the node's platform-probe was unreachable (no live device set). */
17098
+ reachable: boolean(),
17099
+ devices: array(NodeInferenceDeviceSchema).readonly()
17100
+ });
16991
17101
  method(object({
16992
17102
  deviceId: number(),
16993
17103
  agentNodeId: string()
@@ -16997,7 +17107,13 @@ method(object({
16997
17107
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
16998
17108
  kind: "mutation",
16999
17109
  auth: "admin"
17000
- }), method(_void(), object({ migrated: number() }), {
17110
+ }), method(object({
17111
+ deviceId: number(),
17112
+ deviceKey: string()
17113
+ }), object({ success: literal(true) }), {
17114
+ kind: "mutation",
17115
+ auth: "admin"
17116
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
17001
17117
  kind: "mutation",
17002
17118
  auth: "admin"
17003
17119
  }), 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 +17147,7 @@ method(object({
17031
17147
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17032
17148
  nodeId: string(),
17033
17149
  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({
17150
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17041
17151
  success: boolean(),
17042
17152
  removed: boolean()
17043
17153
  }), {
@@ -17069,7 +17179,18 @@ method(object({
17069
17179
  }), object({ success: literal(true) }), {
17070
17180
  kind: "mutation",
17071
17181
  auth: "admin"
17072
- }), method(object({ agentNodeId: string() }), object({
17182
+ }), method(object({
17183
+ agentNodeId: string(),
17184
+ inferenceDevices: record(string(), object({
17185
+ enabled: boolean(),
17186
+ weight: number().positive().optional(),
17187
+ maxSessions: number().int().positive().optional(),
17188
+ steps: record(string(), DeviceStepConfigSchema).optional()
17189
+ }))
17190
+ }), object({ success: literal(true) }), {
17191
+ kind: "mutation",
17192
+ auth: "admin"
17193
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17073
17194
  success: literal(true),
17074
17195
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17075
17196
  effectiveModelId: string().nullable(),
@@ -17085,9 +17206,10 @@ method(object({
17085
17206
  }), object({ success: literal(true) }), {
17086
17207
  kind: "mutation",
17087
17208
  auth: "admin"
17088
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17209
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17089
17210
  deviceId: number(),
17090
17211
  agentNodeId: string(),
17212
+ deviceKey: string(),
17091
17213
  addonId: string(),
17092
17214
  patch: CameraStepOverridePatchSchema.nullable()
17093
17215
  }), object({ success: literal(true) }), {
@@ -17124,14 +17246,13 @@ method(object({
17124
17246
  });
17125
17247
  /**
17126
17248
  * server-management — per-NODE singleton capability for a node's ROOT
17127
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17128
- * agents).
17249
+ * package lifecycle (runtime-updatable node packages).
17129
17250
  *
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).
17251
+ * Every node role runs the SAME root package (`@camstack/server`), which
17252
+ * carries the whole software stack in its npm dep tree, so ONE version
17253
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17254
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17255
+ * no auto-rollback).
17135
17256
  *
17136
17257
  * Providers:
17137
17258
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17239,7 +17360,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17239
17360
  /** Explicit target version; omitted = latest from the registry. */
17240
17361
  version: string().optional() }), ServerUpdateActionResultSchema, {
17241
17362
  kind: "mutation",
17242
- auth: "admin"
17363
+ auth: "admin",
17364
+ timeoutMs: 16 * 6e4
17243
17365
  }), method(_void(), ServerUpdateActionResultSchema, {
17244
17366
  kind: "mutation",
17245
17367
  auth: "admin"
@@ -18296,22 +18418,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18296
18418
  var RestartAddonResultSchema = unknown();
18297
18419
  var InstallPackageResultSchema = unknown();
18298
18420
  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
18421
  var BulkUpdateItemStatusSchema = _enum([
18316
18422
  "queued",
18317
18423
  "updating",
@@ -18439,13 +18545,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18439
18545
  }), object({ success: literal(true) }), {
18440
18546
  kind: "mutation",
18441
18547
  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
18548
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18450
18549
  kind: "mutation",
18451
18550
  auth: "admin"
@@ -19311,10 +19410,10 @@ var TopologyCategorySchema = object({
19311
19410
  addons: array(TopologyCategoryAddonSchema).readonly()
19312
19411
  });
19313
19412
  /**
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.
19413
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19414
+ * root package for every node role) as reported by its `registerNode`
19415
+ * manifest — version visibility for the Server management surface. Nullable:
19416
+ * offline rows and nodes that never reported one.
19318
19417
  */
19319
19418
  var TopologyRootPackageSchema = object({
19320
19419
  name: string(),
@@ -19702,17 +19801,28 @@ var PlatformScoreSchema = object({
19702
19801
  format: _enum([
19703
19802
  "onnx",
19704
19803
  "coreml",
19705
- "openvino"
19804
+ "openvino",
19805
+ "tflite"
19706
19806
  ]),
19707
19807
  score: number(),
19708
19808
  reason: string(),
19709
19809
  available: boolean()
19710
19810
  });
19811
+ var InferenceDeviceDescriptorSchema = object({
19812
+ key: string(),
19813
+ backend: string(),
19814
+ device: string(),
19815
+ format: ModelFormatSchema,
19816
+ runtime: literal("python"),
19817
+ score: number(),
19818
+ available: boolean()
19819
+ });
19711
19820
  var PlatformCapabilitiesSchema = object({
19712
19821
  hardware: HardwareInfoSchema,
19713
19822
  scores: array(PlatformScoreSchema).readonly(),
19714
19823
  bestScore: PlatformScoreSchema,
19715
- pythonPath: string().nullable()
19824
+ pythonPath: string().nullable(),
19825
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19716
19826
  });
19717
19827
  var ModelRequirementSchema = object({
19718
19828
  modelId: string(),
@@ -20591,12 +20701,6 @@ Object.freeze({
20591
20701
  addonId: null,
20592
20702
  access: "delete"
20593
20703
  },
20594
- "addons.updateFrameworkPackage": {
20595
- capName: "addons",
20596
- capScope: "system",
20597
- addonId: null,
20598
- access: "create"
20599
- },
20600
20704
  "addons.updatePackage": {
20601
20705
  capName: "addons",
20602
20706
  capScope: "system",
@@ -23369,12 +23473,6 @@ Object.freeze({
23369
23473
  addonId: null,
23370
23474
  access: "view"
23371
23475
  },
23372
- "pipelineExecutor.reprobeEngine": {
23373
- capName: "pipeline-executor",
23374
- capScope: "system",
23375
- addonId: null,
23376
- access: "create"
23377
- },
23378
23476
  "pipelineExecutor.runAudioTest": {
23379
23477
  capName: "pipeline-executor",
23380
23478
  capScope: "system",
@@ -23525,6 +23623,12 @@ Object.freeze({
23525
23623
  addonId: null,
23526
23624
  access: "view"
23527
23625
  },
23626
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23627
+ capName: "pipeline-orchestrator",
23628
+ capScope: "system",
23629
+ addonId: null,
23630
+ access: "view"
23631
+ },
23528
23632
  "pipelineOrchestrator.getPipelineAssignment": {
23529
23633
  capName: "pipeline-orchestrator",
23530
23634
  capScope: "system",
@@ -23537,6 +23641,12 @@ Object.freeze({
23537
23641
  addonId: null,
23538
23642
  access: "view"
23539
23643
  },
23644
+ "pipelineOrchestrator.getPipelineDevicePin": {
23645
+ capName: "pipeline-orchestrator",
23646
+ capScope: "system",
23647
+ addonId: null,
23648
+ access: "view"
23649
+ },
23540
23650
  "pipelineOrchestrator.listAgentSettings": {
23541
23651
  capName: "pipeline-orchestrator",
23542
23652
  capScope: "system",
@@ -23579,19 +23689,19 @@ Object.freeze({
23579
23689
  addonId: null,
23580
23690
  access: "create"
23581
23691
  },
23582
- "pipelineOrchestrator.setAgentAddonDefaults": {
23692
+ "pipelineOrchestrator.setAgentCapabilities": {
23583
23693
  capName: "pipeline-orchestrator",
23584
23694
  capScope: "system",
23585
23695
  addonId: null,
23586
23696
  access: "create"
23587
23697
  },
23588
- "pipelineOrchestrator.setAgentCapabilities": {
23698
+ "pipelineOrchestrator.setAgentDetectWeight": {
23589
23699
  capName: "pipeline-orchestrator",
23590
23700
  capScope: "system",
23591
23701
  addonId: null,
23592
23702
  access: "create"
23593
23703
  },
23594
- "pipelineOrchestrator.setAgentDetectWeight": {
23704
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23595
23705
  capName: "pipeline-orchestrator",
23596
23706
  capScope: "system",
23597
23707
  addonId: null,
@@ -23633,6 +23743,12 @@ Object.freeze({
23633
23743
  addonId: null,
23634
23744
  access: "create"
23635
23745
  },
23746
+ "pipelineOrchestrator.setPipelineDevicePin": {
23747
+ capName: "pipeline-orchestrator",
23748
+ capScope: "system",
23749
+ addonId: null,
23750
+ access: "create"
23751
+ },
23636
23752
  "pipelineOrchestrator.unassignAudio": {
23637
23753
  capName: "pipeline-orchestrator",
23638
23754
  capScope: "system",
@@ -25185,32 +25301,6 @@ Object.freeze({
25185
25301
  "network-access": "ingress",
25186
25302
  "smtp-provider": "email"
25187
25303
  });
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
25304
  //#endregion
25215
25305
  //#region ../../node_modules/nodemailer/lib/punycode/index.js
25216
25306
  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). */
@@ -11560,7 +11598,14 @@ var RunnerCameraConfigSchema = object({
11560
11598
  * camera's detect node differs from its source-owner (P2d, gated by the
11561
11599
  * `remoteSourcingNodes` rollout setting).
11562
11600
  */
11563
- frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" })
11601
+ frameSource: RunnerFrameSourceSchema.default({ kind: "local-broker" }),
11602
+ /**
11603
+ * Inference-device selector for this camera's sessions (Phase 2 multi-device).
11604
+ * Format `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`);
11605
+ * omitted ⇒ the runner's default device. The engine itself stays node-local —
11606
+ * this only selects WHICH device pool of that node runs the session.
11607
+ */
11608
+ deviceKey: string().optional()
11564
11609
  });
11565
11610
  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
11611
  /**
@@ -11581,6 +11626,19 @@ var RunnerLocalLoadSchema = object({
11581
11626
  avgInferenceTimeMs: number(),
11582
11627
  /** Total queue depth across motion + detection queues. */
11583
11628
  queueDepthTotal: number(),
11629
+ /**
11630
+ * Per-inference-device live load (multi-device C4). One entry per deviceKey
11631
+ * this runner currently has attached cameras on, so the orchestrator's second
11632
+ * `balance()` pass (over a node's devices) weights on real per-pool session
11633
+ * counts. Empty on single-device / pre-multi-device runners. `queueDepthTotal`
11634
+ * per device is 0 until the pool backlog gets a public accessor (follow-up).
11635
+ */
11636
+ devices: array(object({
11637
+ deviceKey: string(),
11638
+ backend: string(),
11639
+ attachedCameras: number(),
11640
+ queueDepthTotal: number()
11641
+ })).default([]),
11584
11642
  /** Hardware capability flags reported by this node. */
11585
11643
  hardware: object({
11586
11644
  hasGpu: boolean(),
@@ -13056,6 +13114,8 @@ method(_void(), _void(), { kind: "mutation" }), method(_void(), _void(), { kind:
13056
13114
  kind: "mutation",
13057
13115
  auth: "admin"
13058
13116
  });
13117
+ 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;
13118
+ new Set(Object.values(DeviceType));
13059
13119
  /**
13060
13120
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
13061
13121
  * surface that admin-ui consumes through `useAddonPagesListPages()`.
@@ -16725,13 +16785,11 @@ var PipelineTemplateSchema = object({
16725
16785
  createdAt: string(),
16726
16786
  updatedAt: string()
16727
16787
  });
16728
- var AgentAddonConfigSchema = object({
16729
- enabled: boolean(),
16788
+ var DeviceStepConfigSchema = object({
16730
16789
  modelId: string().optional(),
16731
- settings: record(string(), unknown()).readonly()
16790
+ settings: record(string(), unknown()).optional()
16732
16791
  });
16733
16792
  var AgentPipelineSettingsSchema = object({
16734
- addonDefaults: record(string(), AgentAddonConfigSchema).readonly(),
16735
16793
  maxCameras: number().int().nonnegative().nullable().default(null),
16736
16794
  /** Per-node detection weight (relative share for the quota balancer). */
16737
16795
  detectWeight: number().positive().optional(),
@@ -16755,7 +16813,22 @@ var AgentPipelineSettingsSchema = object({
16755
16813
  * it already uses to reach the hub). Set this only when the auto-detected
16756
16814
  * address is wrong (multi-homed host, NAT, custom interface).
16757
16815
  */
16758
- reachableHost: string().optional()
16816
+ reachableHost: string().optional(),
16817
+ /**
16818
+ * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
16819
+ * weight, steps}. Absent / all-disabled ⇒ the node's single default
16820
+ * accelerator (safe default); two+ enabled ⇒ the dispatcher balances
16821
+ * detection sessions across them so they run CONCURRENTLY. `steps` is the
16822
+ * per-(node,device) BASE provisioning (`stepId → {modelId?, settings?}`) —
16823
+ * the default model/settings for every camera landing on that accelerator;
16824
+ * a stepId absent ⇒ the step uses that device's format default.
16825
+ */
16826
+ inferenceDevices: record(string(), object({
16827
+ enabled: boolean(),
16828
+ weight: number().positive().optional(),
16829
+ maxSessions: number().int().positive().optional(),
16830
+ steps: record(string(), DeviceStepConfigSchema).optional()
16831
+ })).optional()
16759
16832
  });
16760
16833
  var CameraPipelineForAgentSchema = object({
16761
16834
  steps: array(PipelineStepInputSchema).readonly(),
@@ -16765,14 +16838,13 @@ var CameraPipelineForAgentSchema = object({
16765
16838
  }).nullable()
16766
16839
  });
16767
16840
  var CameraStepOverridePatchSchema = object({
16768
- enabled: boolean().optional(),
16769
16841
  modelId: string().optional(),
16770
16842
  settings: record(string(), unknown()).readonly().optional()
16771
16843
  });
16772
16844
  var CameraPipelineSettingsSchema = object({
16773
16845
  pinnedAgentNodeId: string().optional(),
16774
16846
  stepToggles: record(string(), boolean()).optional(),
16775
- stepOverridesByAgent: record(string(), record(string(), CameraStepOverridePatchSchema)).optional(),
16847
+ stepOverridesByDevice: record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).optional(),
16776
16848
  pipelineByAgent: record(string(), CameraPipelineForAgentSchema).optional()
16777
16849
  });
16778
16850
  /**
@@ -16986,6 +17058,44 @@ var CameraStatusSchema = object({
16986
17058
  /** Unix timestamp (ms) when this snapshot was composed server-side. */
16987
17059
  fetchedAt: number()
16988
17060
  });
17061
+ var NodeInferenceDeviceSchema = object({
17062
+ /** Stable per-node device key, e.g. `openvino:npu`, `edgetpu:usb`, `cpu`. */
17063
+ key: string(),
17064
+ backend: string(),
17065
+ device: string(),
17066
+ format: _enum(MODEL_FORMATS),
17067
+ /** Whether the node's live probe reports the device as usable right now. */
17068
+ available: boolean(),
17069
+ /**
17070
+ * Whether this device participates in dispatch. AUTO default (spec C2):
17071
+ * accelerators are opt-OUT (a discovered NPU/iGPU/Coral/ANE with no stored
17072
+ * entry is `true`); CPU is opt-IN (`false` by default — the fallback pool,
17073
+ * not a balanced target). An explicit stored value always wins; a stored-only
17074
+ * (unavailable) key keeps its stored value.
17075
+ */
17076
+ enabled: boolean(),
17077
+ /** Relative balancer weight for the enabled device (default 1). */
17078
+ weight: number(),
17079
+ /** Per-device concurrent-session cap; null = unlimited (multi-device C4). */
17080
+ maxSessions: number().nullable(),
17081
+ /** Object-detection model the executor defaults to for this deviceKey. */
17082
+ defaultModelId: string(),
17083
+ /**
17084
+ * Per-(node,device) BASE provisioning (C7.2/C7.4) — the RAW stored
17085
+ * `stepId → {modelId?, settings?}` map from `inferenceDevices[key].steps`.
17086
+ * Absent/empty ⇒ no base (every step uses its device format default). The
17087
+ * UI cross-references `pipelineExecutor.getSchema` for the models actually
17088
+ * available per format; this is the stored selection that becomes the
17089
+ * default for EVERY camera landing on this accelerator.
17090
+ */
17091
+ steps: record(string(), DeviceStepConfigSchema).optional()
17092
+ });
17093
+ var NodeInferenceDevicesSchema = object({
17094
+ nodeId: string(),
17095
+ /** False when the node's platform-probe was unreachable (no live device set). */
17096
+ reachable: boolean(),
17097
+ devices: array(NodeInferenceDeviceSchema).readonly()
17098
+ });
16989
17099
  method(object({
16990
17100
  deviceId: number(),
16991
17101
  agentNodeId: string()
@@ -16995,7 +17105,13 @@ method(object({
16995
17105
  }), method(object({ deviceId: number() }), object({ success: literal(true) }), {
16996
17106
  kind: "mutation",
16997
17107
  auth: "admin"
16998
- }), method(_void(), object({ migrated: number() }), {
17108
+ }), method(object({
17109
+ deviceId: number(),
17110
+ deviceKey: string()
17111
+ }), object({ success: literal(true) }), {
17112
+ kind: "mutation",
17113
+ auth: "admin"
17114
+ }), method(object({ deviceId: number() }), object({ deviceKey: string().nullable() })), method(_void(), object({ migrated: number() }), {
16999
17115
  kind: "mutation",
17000
17116
  auth: "admin"
17001
17117
  }), 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 +17145,7 @@ method(object({
17029
17145
  }))), method(object({ agentNodeId: string() }), AgentPipelineSettingsSchema.nullable()), method(_void(), array(object({
17030
17146
  nodeId: string(),
17031
17147
  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({
17148
+ })).readonly()), method(object({ agentNodeId: string() }), object({
17039
17149
  success: boolean(),
17040
17150
  removed: boolean()
17041
17151
  }), {
@@ -17067,7 +17177,18 @@ method(object({
17067
17177
  }), object({ success: literal(true) }), {
17068
17178
  kind: "mutation",
17069
17179
  auth: "admin"
17070
- }), method(object({ agentNodeId: string() }), object({
17180
+ }), method(object({
17181
+ agentNodeId: string(),
17182
+ inferenceDevices: record(string(), object({
17183
+ enabled: boolean(),
17184
+ weight: number().positive().optional(),
17185
+ maxSessions: number().int().positive().optional(),
17186
+ steps: record(string(), DeviceStepConfigSchema).optional()
17187
+ }))
17188
+ }), object({ success: literal(true) }), {
17189
+ kind: "mutation",
17190
+ auth: "admin"
17191
+ }), method(object({ nodeId: string() }), NodeInferenceDevicesSchema), method(object({ agentNodeId: string() }), object({
17071
17192
  success: literal(true),
17072
17193
  /** Hardware-aware default detection model now in effect on the node (null when unresolvable). */
17073
17194
  effectiveModelId: string().nullable(),
@@ -17083,9 +17204,10 @@ method(object({
17083
17204
  }), object({ success: literal(true) }), {
17084
17205
  kind: "mutation",
17085
17206
  auth: "admin"
17086
- }), method(object({ deviceId: number() }), record(string(), record(string(), CameraStepOverridePatchSchema)).nullable()), method(object({
17207
+ }), method(object({ deviceId: number() }), record(string(), record(string(), record(string(), CameraStepOverridePatchSchema))).nullable()), method(object({
17087
17208
  deviceId: number(),
17088
17209
  agentNodeId: string(),
17210
+ deviceKey: string(),
17089
17211
  addonId: string(),
17090
17212
  patch: CameraStepOverridePatchSchema.nullable()
17091
17213
  }), object({ success: literal(true) }), {
@@ -17122,14 +17244,13 @@ method(object({
17122
17244
  });
17123
17245
  /**
17124
17246
  * server-management — per-NODE singleton capability for a node's ROOT
17125
- * package lifecycle (runtime-updatable node packages, phase 2: hub + docker
17126
- * agents).
17247
+ * package lifecycle (runtime-updatable node packages).
17127
17248
  *
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).
17249
+ * Every node role runs the SAME root package (`@camstack/server`), which
17250
+ * carries the whole software stack in its npm dep tree, so ONE version
17251
+ * describes the node. Updates stage into `<dataDir>/server-root/` and apply
17252
+ * on restart via the baked starter (single-copy in-place swap — no probation,
17253
+ * no auto-rollback).
17133
17254
  *
17134
17255
  * Providers:
17135
17256
  * - HUB: `ServerUpdateService` behind the `server-provided` mount
@@ -17237,7 +17358,8 @@ method(_void(), ServerPackageStatusSchema, { auth: "admin" }), method(_void(), S
17237
17358
  /** Explicit target version; omitted = latest from the registry. */
17238
17359
  version: string().optional() }), ServerUpdateActionResultSchema, {
17239
17360
  kind: "mutation",
17240
- auth: "admin"
17361
+ auth: "admin",
17362
+ timeoutMs: 16 * 6e4
17241
17363
  }), method(_void(), ServerUpdateActionResultSchema, {
17242
17364
  kind: "mutation",
17243
17365
  auth: "admin"
@@ -18294,22 +18416,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
18294
18416
  var RestartAddonResultSchema = unknown();
18295
18417
  var InstallPackageResultSchema = unknown();
18296
18418
  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
18419
  var BulkUpdateItemStatusSchema = _enum([
18314
18420
  "queued",
18315
18421
  "updating",
@@ -18437,13 +18543,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
18437
18543
  }), object({ success: literal(true) }), {
18438
18544
  kind: "mutation",
18439
18545
  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
18546
  }), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
18448
18547
  kind: "mutation",
18449
18548
  auth: "admin"
@@ -19309,10 +19408,10 @@ var TopologyCategorySchema = object({
19309
19408
  addons: array(TopologyCategoryAddonSchema).readonly()
19310
19409
  });
19311
19410
  /**
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.
19411
+ * The node's runtime-updatable ROOT package (`@camstack/server` the single
19412
+ * root package for every node role) as reported by its `registerNode`
19413
+ * manifest — version visibility for the Server management surface. Nullable:
19414
+ * offline rows and nodes that never reported one.
19316
19415
  */
19317
19416
  var TopologyRootPackageSchema = object({
19318
19417
  name: string(),
@@ -19700,17 +19799,28 @@ var PlatformScoreSchema = object({
19700
19799
  format: _enum([
19701
19800
  "onnx",
19702
19801
  "coreml",
19703
- "openvino"
19802
+ "openvino",
19803
+ "tflite"
19704
19804
  ]),
19705
19805
  score: number(),
19706
19806
  reason: string(),
19707
19807
  available: boolean()
19708
19808
  });
19809
+ var InferenceDeviceDescriptorSchema = object({
19810
+ key: string(),
19811
+ backend: string(),
19812
+ device: string(),
19813
+ format: ModelFormatSchema,
19814
+ runtime: literal("python"),
19815
+ score: number(),
19816
+ available: boolean()
19817
+ });
19709
19818
  var PlatformCapabilitiesSchema = object({
19710
19819
  hardware: HardwareInfoSchema,
19711
19820
  scores: array(PlatformScoreSchema).readonly(),
19712
19821
  bestScore: PlatformScoreSchema,
19713
- pythonPath: string().nullable()
19822
+ pythonPath: string().nullable(),
19823
+ devices: array(InferenceDeviceDescriptorSchema).readonly()
19714
19824
  });
19715
19825
  var ModelRequirementSchema = object({
19716
19826
  modelId: string(),
@@ -20589,12 +20699,6 @@ Object.freeze({
20589
20699
  addonId: null,
20590
20700
  access: "delete"
20591
20701
  },
20592
- "addons.updateFrameworkPackage": {
20593
- capName: "addons",
20594
- capScope: "system",
20595
- addonId: null,
20596
- access: "create"
20597
- },
20598
20702
  "addons.updatePackage": {
20599
20703
  capName: "addons",
20600
20704
  capScope: "system",
@@ -23367,12 +23471,6 @@ Object.freeze({
23367
23471
  addonId: null,
23368
23472
  access: "view"
23369
23473
  },
23370
- "pipelineExecutor.reprobeEngine": {
23371
- capName: "pipeline-executor",
23372
- capScope: "system",
23373
- addonId: null,
23374
- access: "create"
23375
- },
23376
23474
  "pipelineExecutor.runAudioTest": {
23377
23475
  capName: "pipeline-executor",
23378
23476
  capScope: "system",
@@ -23523,6 +23621,12 @@ Object.freeze({
23523
23621
  addonId: null,
23524
23622
  access: "view"
23525
23623
  },
23624
+ "pipelineOrchestrator.getNodeInferenceDevices": {
23625
+ capName: "pipeline-orchestrator",
23626
+ capScope: "system",
23627
+ addonId: null,
23628
+ access: "view"
23629
+ },
23526
23630
  "pipelineOrchestrator.getPipelineAssignment": {
23527
23631
  capName: "pipeline-orchestrator",
23528
23632
  capScope: "system",
@@ -23535,6 +23639,12 @@ Object.freeze({
23535
23639
  addonId: null,
23536
23640
  access: "view"
23537
23641
  },
23642
+ "pipelineOrchestrator.getPipelineDevicePin": {
23643
+ capName: "pipeline-orchestrator",
23644
+ capScope: "system",
23645
+ addonId: null,
23646
+ access: "view"
23647
+ },
23538
23648
  "pipelineOrchestrator.listAgentSettings": {
23539
23649
  capName: "pipeline-orchestrator",
23540
23650
  capScope: "system",
@@ -23577,19 +23687,19 @@ Object.freeze({
23577
23687
  addonId: null,
23578
23688
  access: "create"
23579
23689
  },
23580
- "pipelineOrchestrator.setAgentAddonDefaults": {
23690
+ "pipelineOrchestrator.setAgentCapabilities": {
23581
23691
  capName: "pipeline-orchestrator",
23582
23692
  capScope: "system",
23583
23693
  addonId: null,
23584
23694
  access: "create"
23585
23695
  },
23586
- "pipelineOrchestrator.setAgentCapabilities": {
23696
+ "pipelineOrchestrator.setAgentDetectWeight": {
23587
23697
  capName: "pipeline-orchestrator",
23588
23698
  capScope: "system",
23589
23699
  addonId: null,
23590
23700
  access: "create"
23591
23701
  },
23592
- "pipelineOrchestrator.setAgentDetectWeight": {
23702
+ "pipelineOrchestrator.setAgentInferenceDevices": {
23593
23703
  capName: "pipeline-orchestrator",
23594
23704
  capScope: "system",
23595
23705
  addonId: null,
@@ -23631,6 +23741,12 @@ Object.freeze({
23631
23741
  addonId: null,
23632
23742
  access: "create"
23633
23743
  },
23744
+ "pipelineOrchestrator.setPipelineDevicePin": {
23745
+ capName: "pipeline-orchestrator",
23746
+ capScope: "system",
23747
+ addonId: null,
23748
+ access: "create"
23749
+ },
23634
23750
  "pipelineOrchestrator.unassignAudio": {
23635
23751
  capName: "pipeline-orchestrator",
23636
23752
  capScope: "system",
@@ -25183,32 +25299,6 @@ Object.freeze({
25183
25299
  "network-access": "ingress",
25184
25300
  "smtp-provider": "email"
25185
25301
  });
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
25302
  //#endregion
25213
25303
  //#region ../../node_modules/nodemailer/lib/punycode/index.js
25214
25304
  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.0",
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",