@camstack/addon-provider-rademacher 0.2.1 → 0.2.2

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.
package/dist/addon.js CHANGED
@@ -13306,7 +13306,8 @@ var PipelineStepInputSchema = lazy(() => object({
13306
13306
  modelId: string().optional(),
13307
13307
  enabled: boolean().default(true),
13308
13308
  children: array(PipelineStepInputSchema).optional(),
13309
- settings: record(string(), unknown()).optional()
13309
+ settings: record(string(), unknown()).optional(),
13310
+ jumpDeviceKey: string().optional()
13310
13311
  }));
13311
13312
  var ModelSubstitutionSchema = object({
13312
13313
  addonId: string(),
@@ -13645,8 +13646,24 @@ var NativeCropBboxSchema = object({
13645
13646
  });
13646
13647
  /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
13647
13648
  var NativeCropResultSchema = object({
13648
- /** Packed rgb (24-bit) pixels of the crop. */
13649
- bytes: _instanceof(Uint8Array),
13649
+ /**
13650
+ * Packed rgb (24-bit) pixels of the crop. Present on the DEFAULT (raw) path —
13651
+ * same-node (in-process / UDS) callers get zero-copy RGB and encode locally.
13652
+ * OMITTED when the caller requested `encodeJpeg` (the cross-node compressed
13653
+ * path below), where shipping raw RGB is both an invariant violation and, for
13654
+ * a native full frame (~26 MB at 4K), larger than Moleculer's 10 MB
13655
+ * `maxPacketSize` → the packet is dropped and the call 60s-times-out. That is
13656
+ * the cross-node native-media miss: `bytes` is replaced by `jpeg`.
13657
+ */
13658
+ bytes: _instanceof(Uint8Array).optional(),
13659
+ /**
13660
+ * Base64 JPEG of the crop — the COMPRESSED cross-node payload. The OWNING node
13661
+ * (which holds the native surface) encodes it in-process, so a native 4K frame
13662
+ * ships as ~0.5–2 MB (well under `maxPacketSize`) and NO raw pixels ever cross
13663
+ * a process boundary (CLAUDE.md invariant #21). Present ONLY when the request
13664
+ * set `encodeJpeg: true`; `bytes` is then absent.
13665
+ */
13666
+ jpeg: string().optional(),
13650
13667
  width: number().int().positive(),
13651
13668
  height: number().int().positive(),
13652
13669
  /**
@@ -13792,6 +13809,20 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
13792
13809
  hubHostnameOverride: string().optional()
13793
13810
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
13794
13811
  /**
13812
+ * One ENABLED inference device on the runner's node, as the step-tree
13813
+ * device-jump resolver sees it (phase 1). The orchestrator populates this
13814
+ * roster on the attach payload whenever the camera is elected onto a specific
13815
+ * `deviceKey` and the node has ≥2 enabled devices — it is the candidate set the
13816
+ * runner auto-jumps an enrichment step to when the elected device's format
13817
+ * cannot run that step's model. `weight`/`maxSessions` mirror the balancer's
13818
+ * per-device knobs so the auto choice is weighted-least-loaded.
13819
+ */
13820
+ var RunnerInferenceDeviceSchema = object({
13821
+ deviceKey: string(),
13822
+ weight: number().positive().default(1),
13823
+ maxSessions: number().int().positive().nullable().default(null)
13824
+ });
13825
+ /**
13795
13826
  * Camera assignment payload sent by `addon-pipeline-orchestrator` to a
13796
13827
  * specific runner instance via `attachCamera`. Carries everything the
13797
13828
  * runner needs to subscribe to the local broker and execute inference.
@@ -13909,7 +13940,16 @@ var RunnerCameraConfigSchema = object({
13909
13940
  * omitted ⇒ the runner's default device. The engine itself stays node-local —
13910
13941
  * this only selects WHICH device pool of that node runs the session.
13911
13942
  */
13912
- deviceKey: string().optional()
13943
+ deviceKey: string().optional(),
13944
+ /**
13945
+ * Step-tree device-jump roster (phase 1): the node's ENABLED inference
13946
+ * devices, populated by the orchestrator ONLY when `deviceKey` is set and the
13947
+ * node has ≥2 enabled devices. The runner uses it to AUTO-jump an enrichment
13948
+ * step whose model has no build for the elected device's format onto another
13949
+ * enabled device of the SAME node (weighted-least-loaded). Absent/single-entry
13950
+ * ⇒ no jump possible; the step runs on `deviceKey`.
13951
+ */
13952
+ inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
13913
13953
  });
13914
13954
  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;
13915
13955
  /**
@@ -13965,7 +14005,18 @@ var RunnerLocalMetricsSchema = object({
13965
14005
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
13966
14006
  handle: FrameHandleSchema,
13967
14007
  bbox: NativeCropBboxSchema,
13968
- maxWidth: number().int().positive().optional()
14008
+ maxWidth: number().int().positive().optional(),
14009
+ /**
14010
+ * When `true`, the runner encodes the resolved crop to JPEG ON THE
14011
+ * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
14012
+ * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
14013
+ * agent) so the compressed payload fits Moleculer's `maxPacketSize` and
14014
+ * no raw pixels cross the process boundary. Same-node callers omit it
14015
+ * and keep the zero-copy raw `bytes` path. Additive + optional: a
14016
+ * pre-encode runner (version skew) ignores it and returns `bytes`, so
14017
+ * the caller falls back to encoding locally.
14018
+ */
14019
+ encodeJpeg: boolean().optional()
13969
14020
  }), NativeCropResultSchema.nullable()), method(object({
13970
14021
  deviceId: number(),
13971
14022
  frameHandle: FrameHandleSchema.optional(),
@@ -20767,7 +20818,16 @@ var PipelineTemplateSchema = object({
20767
20818
  });
20768
20819
  var DeviceStepConfigSchema = object({
20769
20820
  modelId: string().optional(),
20770
- settings: record(string(), unknown()).optional()
20821
+ settings: record(string(), unknown()).optional(),
20822
+ /**
20823
+ * Step-tree device jump (same-node, phase 1) — OPTIONAL manual override.
20824
+ * When set, this step runs on the named enabled device of the SAME node
20825
+ * (`<backend>:<device>`) instead of the camera's elected device, bypassing
20826
+ * the runtime AUTO-jump. The orchestrator rejects a `jumpDeviceKey` pointing
20827
+ * at a disabled/absent device on that node at save time. Absent ⇒ the runner
20828
+ * auto-jumps only when the effective device's format cannot run the step.
20829
+ */
20830
+ jumpDeviceKey: string().optional()
20771
20831
  });
20772
20832
  var AgentPipelineSettingsSchema = object({
20773
20833
  maxCameras: number().int().nonnegative().nullable().default(null),
package/dist/addon.mjs CHANGED
@@ -13305,7 +13305,8 @@ var PipelineStepInputSchema = lazy(() => object({
13305
13305
  modelId: string().optional(),
13306
13306
  enabled: boolean().default(true),
13307
13307
  children: array(PipelineStepInputSchema).optional(),
13308
- settings: record(string(), unknown()).optional()
13308
+ settings: record(string(), unknown()).optional(),
13309
+ jumpDeviceKey: string().optional()
13309
13310
  }));
13310
13311
  var ModelSubstitutionSchema = object({
13311
13312
  addonId: string(),
@@ -13644,8 +13645,24 @@ var NativeCropBboxSchema = object({
13644
13645
  });
13645
13646
  /** Result of a best-effort native-resolution crop (`getNativeCrop`). */
13646
13647
  var NativeCropResultSchema = object({
13647
- /** Packed rgb (24-bit) pixels of the crop. */
13648
- bytes: _instanceof(Uint8Array),
13648
+ /**
13649
+ * Packed rgb (24-bit) pixels of the crop. Present on the DEFAULT (raw) path —
13650
+ * same-node (in-process / UDS) callers get zero-copy RGB and encode locally.
13651
+ * OMITTED when the caller requested `encodeJpeg` (the cross-node compressed
13652
+ * path below), where shipping raw RGB is both an invariant violation and, for
13653
+ * a native full frame (~26 MB at 4K), larger than Moleculer's 10 MB
13654
+ * `maxPacketSize` → the packet is dropped and the call 60s-times-out. That is
13655
+ * the cross-node native-media miss: `bytes` is replaced by `jpeg`.
13656
+ */
13657
+ bytes: _instanceof(Uint8Array).optional(),
13658
+ /**
13659
+ * Base64 JPEG of the crop — the COMPRESSED cross-node payload. The OWNING node
13660
+ * (which holds the native surface) encodes it in-process, so a native 4K frame
13661
+ * ships as ~0.5–2 MB (well under `maxPacketSize`) and NO raw pixels ever cross
13662
+ * a process boundary (CLAUDE.md invariant #21). Present ONLY when the request
13663
+ * set `encodeJpeg: true`; `bytes` is then absent.
13664
+ */
13665
+ jpeg: string().optional(),
13649
13666
  width: number().int().positive(),
13650
13667
  height: number().int().positive(),
13651
13668
  /**
@@ -13791,6 +13808,20 @@ var RunnerFrameSourceSchema = discriminatedUnion("kind", [object({ kind: literal
13791
13808
  hubHostnameOverride: string().optional()
13792
13809
  })]).describe("Per-camera frame-source mode for the runner (P2c)");
13793
13810
  /**
13811
+ * One ENABLED inference device on the runner's node, as the step-tree
13812
+ * device-jump resolver sees it (phase 1). The orchestrator populates this
13813
+ * roster on the attach payload whenever the camera is elected onto a specific
13814
+ * `deviceKey` and the node has ≥2 enabled devices — it is the candidate set the
13815
+ * runner auto-jumps an enrichment step to when the elected device's format
13816
+ * cannot run that step's model. `weight`/`maxSessions` mirror the balancer's
13817
+ * per-device knobs so the auto choice is weighted-least-loaded.
13818
+ */
13819
+ var RunnerInferenceDeviceSchema = object({
13820
+ deviceKey: string(),
13821
+ weight: number().positive().default(1),
13822
+ maxSessions: number().int().positive().nullable().default(null)
13823
+ });
13824
+ /**
13794
13825
  * Camera assignment payload sent by `addon-pipeline-orchestrator` to a
13795
13826
  * specific runner instance via `attachCamera`. Carries everything the
13796
13827
  * runner needs to subscribe to the local broker and execute inference.
@@ -13908,7 +13939,16 @@ var RunnerCameraConfigSchema = object({
13908
13939
  * omitted ⇒ the runner's default device. The engine itself stays node-local —
13909
13940
  * this only selects WHICH device pool of that node runs the session.
13910
13941
  */
13911
- deviceKey: string().optional()
13942
+ deviceKey: string().optional(),
13943
+ /**
13944
+ * Step-tree device-jump roster (phase 1): the node's ENABLED inference
13945
+ * devices, populated by the orchestrator ONLY when `deviceKey` is set and the
13946
+ * node has ≥2 enabled devices. The runner uses it to AUTO-jump an enrichment
13947
+ * step whose model has no build for the elected device's format onto another
13948
+ * enabled device of the SAME node (weighted-least-loaded). Absent/single-entry
13949
+ * ⇒ no jump possible; the step runs on `deviceKey`.
13950
+ */
13951
+ inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
13912
13952
  });
13913
13953
  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;
13914
13954
  /**
@@ -13964,7 +14004,18 @@ var RunnerLocalMetricsSchema = object({
13964
14004
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
13965
14005
  handle: FrameHandleSchema,
13966
14006
  bbox: NativeCropBboxSchema,
13967
- maxWidth: number().int().positive().optional()
14007
+ maxWidth: number().int().positive().optional(),
14008
+ /**
14009
+ * When `true`, the runner encodes the resolved crop to JPEG ON THE
14010
+ * OWNING NODE and returns it in `jpeg` (base64) INSTEAD of raw `bytes`.
14011
+ * Callers set this for CROSS-NODE fetches (`handle.nodeId` is a remote
14012
+ * agent) so the compressed payload fits Moleculer's `maxPacketSize` and
14013
+ * no raw pixels cross the process boundary. Same-node callers omit it
14014
+ * and keep the zero-copy raw `bytes` path. Additive + optional: a
14015
+ * pre-encode runner (version skew) ignores it and returns `bytes`, so
14016
+ * the caller falls back to encoding locally.
14017
+ */
14018
+ encodeJpeg: boolean().optional()
13968
14019
  }), NativeCropResultSchema.nullable()), method(object({
13969
14020
  deviceId: number(),
13970
14021
  frameHandle: FrameHandleSchema.optional(),
@@ -20766,7 +20817,16 @@ var PipelineTemplateSchema = object({
20766
20817
  });
20767
20818
  var DeviceStepConfigSchema = object({
20768
20819
  modelId: string().optional(),
20769
- settings: record(string(), unknown()).optional()
20820
+ settings: record(string(), unknown()).optional(),
20821
+ /**
20822
+ * Step-tree device jump (same-node, phase 1) — OPTIONAL manual override.
20823
+ * When set, this step runs on the named enabled device of the SAME node
20824
+ * (`<backend>:<device>`) instead of the camera's elected device, bypassing
20825
+ * the runtime AUTO-jump. The orchestrator rejects a `jumpDeviceKey` pointing
20826
+ * at a disabled/absent device on that node at save time. Absent ⇒ the runner
20827
+ * auto-jumps only when the effective device's format cannot run the step.
20828
+ */
20829
+ jumpDeviceKey: string().optional()
20770
20830
  });
20771
20831
  var AgentPipelineSettingsSchema = object({
20772
20832
  maxCameras: number().int().nonnegative().nullable().default(null),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",