@camstack/addon-pipeline 1.2.293 → 1.2.294

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{default-detection-model-DCQlW9fx.mjs → default-detection-model-0dPKRKUD.mjs} +62 -81
  4. package/dist/{default-detection-model-DTKHLLcC.js → default-detection-model-D24AJOTn.js} +67 -80
  5. package/dist/detection-pipeline/index.js +6 -5
  6. package/dist/detection-pipeline/index.mjs +6 -5
  7. package/dist/{dist-Ce8s7XqV.js → dist-CJR259Xf.js} +11 -1
  8. package/dist/{dist-C0Fr4hM5.mjs → dist-RXbmRAwP.mjs} +11 -1
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-DpOrymbW.js → node-DWg9zbY1.js} +1 -1
  12. package/dist/{node-Xm7amG2e.mjs → node-atmRSHPk.mjs} +1 -1
  13. package/dist/pipeline-runner/index.js +80 -5
  14. package/dist/pipeline-runner/index.mjs +80 -5
  15. package/dist/{process-memory-CBRjuhyg.js → process-memory-BJUXvTjd.js} +1 -1
  16. package/dist/{process-memory-BN5qYGsD.mjs → process-memory-BgFOHFnx.mjs} +1 -1
  17. package/dist/recorder/index.js +2 -2
  18. package/dist/recorder/index.mjs +2 -2
  19. package/dist/{segment-demux-js-BhMlS_Ow.js → segment-demux-js-C_fPJub3.js} +1 -1
  20. package/dist/{segment-demux-js-Bhwpj5Wl.mjs → segment-demux-js-G7wFpHzn.mjs} +1 -1
  21. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DKd7oYba.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-6IyM-BIn.mjs} +1 -1
  22. package/dist/stream-broker/demux-worker-child.js +1 -1
  23. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  24. package/dist/stream-broker/{hostInit-CCMIHjff.mjs → hostInit-BBYHWS3M.mjs} +1 -1
  25. package/dist/stream-broker/index.js +3 -3
  26. package/dist/stream-broker/index.mjs +3 -3
  27. package/dist/stream-broker/remoteEntry.js +1 -1
  28. package/package.json +1 -1
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Ce8s7XqV.js");
7
- const require_process_memory = require("../process-memory-CBRjuhyg.js");
6
+ const require_dist = require("../dist-CJR259Xf.js");
7
+ const require_process_memory = require("../process-memory-BJUXvTjd.js");
8
8
  let node_fs = require("node:fs");
9
9
  node_fs = require_chunk.__toESM(node_fs);
10
10
  let node_path = require("node:path");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as errMsg, A as PoolMemoryWatchdog, Ln as EventCategory, T as HF_BASE_URL, U as audioAnalysisCapability, Ut as resolvePoolMemoryPolicy, W as audioAnalyzerCapability, bn as nodePin, d as DEFAULT_AUDIO_ANALYZER_CONFIG, dn as audioChunkBytesPerSample, gn as hydrateSchema, hn as expandAudioChunkToF32le, n as AUDIO_BACKEND_CHOICES, on as BaseAddon, yt as mapAudioLabelToMacro } from "../dist-C0Fr4hM5.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BN5qYGsD.mjs";
2
+ import { $t as errMsg, A as PoolMemoryWatchdog, Ln as EventCategory, T as HF_BASE_URL, U as audioAnalysisCapability, Ut as resolvePoolMemoryPolicy, W as audioAnalyzerCapability, bn as nodePin, d as DEFAULT_AUDIO_ANALYZER_CONFIG, dn as audioChunkBytesPerSample, gn as hydrateSchema, hn as expandAudioChunkToF32le, n as AUDIO_BACKEND_CHOICES, on as BaseAddon, yt as mapAudioLabelToMacro } from "../dist-RXbmRAwP.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BgFOHFnx.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
6
6
  import { downloadFile } from "@camstack/system/addon-utils";
@@ -1,4 +1,4 @@
1
- import { G as audioKindId, l as COCO_80_LABELS, mt as hfModelUrl, r as AUDIO_MACRO_LABELS, u as COCO_TO_MACRO } from "./dist-C0Fr4hM5.mjs";
1
+ import { G as audioKindId, l as COCO_80_LABELS, mt as hfModelUrl, r as AUDIO_MACRO_LABELS, u as COCO_TO_MACRO } from "./dist-RXbmRAwP.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -491,89 +491,68 @@ var OBJECT_DETECTION_MODELS = [
491
491
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "fp16", 112, true),
492
492
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "int8", 56, true)
493
493
  ];
494
- var FACE_DETECTION_MODELS = [
495
- {
496
- id: "scrfd-2.5g",
497
- name: "SCRFD 2.5G",
498
- description: "SCRFD 2.5G bnkps — balanced face detection with 5 keypoints (WIDER FACE 93.80/92.02/77.13). InsightFace pretrained weights.",
499
- inputSize: {
500
- width: 640,
501
- height: 640
502
- },
503
- labels: [{
504
- id: "face",
505
- name: "Face"
506
- }],
507
- preprocessMode: "letterbox",
508
- inputNormalization: "scrfd",
509
- license: "InsightFace-NonCommercial-Research",
510
- formats: {
511
- onnx: {
512
- url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
513
- sizeMB: 3.1
514
- },
515
- coreml: {
516
- url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
517
- sizeMB: 1.7,
518
- isDirectory: true,
519
- files: [...MLPACKAGE_FILES],
520
- runtimes: ["python"]
521
- },
522
- openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
523
- }
524
- },
525
- {
526
- id: "scrypted-yolov9t-face",
527
- name: "YOLOv9t Face ReLU",
528
- description: "YOLOv9t face detection — YOLO-based, fast, 320x320 ReLU",
529
- inputSize: {
530
- width: 320,
531
- height: 320
532
- },
533
- labels: [{
534
- id: "face",
535
- name: "Face"
536
- }],
537
- preprocessMode: "letterbox",
538
- license: "UNKNOWN",
539
- formats: {
540
- onnx: {
541
- url: hfScrypted("onnx/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.onnx"),
542
- sizeMB: 8.1
543
- },
544
- coreml: {
545
- url: hfScrypted("coreml/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.mlpackage"),
546
- sizeMB: 4,
547
- isDirectory: true,
548
- files: [...MLPACKAGE_FILES],
549
- runtimes: ["python"]
550
- },
551
- openvino: ovFormat(hf("faceDetection/scrypted-yolov9-face/openvino/scrypted_yolov9t_relu_face.xml"), 6)
552
- }
494
+ /**
495
+ * Model ids REMOVED from a step's catalog, per step id (D643).
496
+ *
497
+ * Not the same as `legacy` (still in the catalog, still runnable when chosen):
498
+ * a retired id has nothing to download and nothing that can parse it. It is
499
+ * listed rather than simply deleted because `resolveModelForFormat` passes an
500
+ * id the catalog does not know through UNCHANGED — it reads as an operator's
501
+ * custom model — so a saved pin would keep naming a model no node can load.
502
+ * A retired id resolves to the step's format default instead.
503
+ */
504
+ var RETIRED_MODEL_IDS = { "face-detection": ["scrypted-yolov9t-face"] };
505
+ var FACE_DETECTION_MODELS = [{
506
+ id: "scrfd-2.5g",
507
+ name: "SCRFD 2.5G",
508
+ description: "SCRFD 2.5G bnkps — balanced face detection with 5 keypoints (WIDER FACE 93.80/92.02/77.13). InsightFace pretrained weights.",
509
+ inputSize: {
510
+ width: 640,
511
+ height: 640
553
512
  },
554
- {
555
- id: "ssd-mobilenet-v2-face-edgetpu",
556
- legacy: true,
557
- name: "SSD MobileNet V2 Face (Coral)",
558
- description: "SSD MobileNet V2 face detector — EdgeTPU-compiled full-integer TFLite, 320×320; runs on the Coral USB Edge TPU. Requires an ssd-face postprocessor (not yet available).",
559
- inputSize: {
560
- width: 320,
561
- height: 320
513
+ labels: [{
514
+ id: "face",
515
+ name: "Face"
516
+ }],
517
+ preprocessMode: "letterbox",
518
+ inputNormalization: "scrfd",
519
+ license: "InsightFace-NonCommercial-Research",
520
+ formats: {
521
+ onnx: {
522
+ url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
523
+ sizeMB: 3.1
562
524
  },
563
- labels: [{
564
- id: "face",
565
- name: "Face"
566
- }],
567
- preprocessMode: "letterbox",
568
- postprocessor: "ssd",
569
- license: "Apache-2.0",
570
- formats: { tflite: {
571
- url: "https://github.com/google-coral/test_data/raw/master/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite",
572
- sizeMB: 6.7,
525
+ coreml: {
526
+ url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
527
+ sizeMB: 1.7,
528
+ isDirectory: true,
529
+ files: [...MLPACKAGE_FILES],
573
530
  runtimes: ["python"]
574
- } }
531
+ },
532
+ openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
575
533
  }
576
- ];
534
+ }, {
535
+ id: "ssd-mobilenet-v2-face-edgetpu",
536
+ legacy: true,
537
+ name: "SSD MobileNet V2 Face (Coral)",
538
+ description: "SSD MobileNet V2 face detector — EdgeTPU-compiled full-integer TFLite, 320×320; runs on the Coral USB Edge TPU. Requires an ssd-face postprocessor (not yet available).",
539
+ inputSize: {
540
+ width: 320,
541
+ height: 320
542
+ },
543
+ labels: [{
544
+ id: "face",
545
+ name: "Face"
546
+ }],
547
+ preprocessMode: "letterbox",
548
+ postprocessor: "ssd",
549
+ license: "Apache-2.0",
550
+ formats: { tflite: {
551
+ url: "https://github.com/google-coral/test_data/raw/master/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite",
552
+ sizeMB: 6.7,
553
+ runtimes: ["python"]
554
+ } }
555
+ }];
577
556
  var FACE_EMBEDDING_MODELS = [
578
557
  {
579
558
  id: "arcface-r100",
@@ -1877,6 +1856,7 @@ function getDefaultModelForFormatFromDef(def, format) {
1877
1856
  * - chosen is a catalog model → keep it if it has a `format` build; else
1878
1857
  * the addon's default model for `format`
1879
1858
  * (a substitution — the caller surfaces it).
1859
+ * - chosen is RETIRED (`RETIRED_MODEL_IDS`) → the format default (D643).
1880
1860
  * - chosen is NOT in the catalog (custom/unknown) → returned unchanged; the
1881
1861
  * operator owns a custom model's format compat.
1882
1862
  * - unknown stepId → chosen returned unchanged (never throws).
@@ -1889,6 +1869,7 @@ function resolveModelForFormat(stepId, chosenModelId, format) {
1889
1869
  return chosenModelId ?? "";
1890
1870
  }
1891
1871
  if (chosenModelId === null) return getDefaultModelForFormat(stepId, format);
1872
+ if (RETIRED_MODEL_IDS[stepId]?.includes(chosenModelId) === true) return getDefaultModelForFormat(stepId, format);
1892
1873
  const entry = def.models.find((m) => m.id === chosenModelId);
1893
1874
  if (!entry) return chosenModelId;
1894
1875
  if (entry.formats[format]) return chosenModelId;
@@ -2226,4 +2207,4 @@ function resolveDefaultDetectionModel(backend, device, format, getStepDef = getS
2226
2207
  return getDefaultModelForFormatFromDef(def, format);
2227
2208
  }
2228
2209
  //#endregion
2229
- export { localFrameRegistry as a, ALL_STEPS as c, getStepDefinition as d, resolveModelForFormat as f, rootObjectGate as i, getDefaultModelForFormat as l, resolveDefaultDetectionModel as n, resolveFrameViewGeometry as o, landmarkPrecisionVerdict as p, macroGateVerdict as r, ALL_PIPELINE_STEPS as s, OBJECT_DETECTION_STEP_ID as t, getStep as u };
2210
+ export { localFrameRegistry as a, ALL_STEPS as c, getStepDefinition as d, resolveModelForFormat as f, rootObjectGate as i, getDefaultModelForFormat as l, landmarkPrecisionVerdict as m, resolveDefaultDetectionModel as n, resolveFrameViewGeometry as o, RETIRED_MODEL_IDS as p, macroGateVerdict as r, ALL_PIPELINE_STEPS as s, OBJECT_DETECTION_STEP_ID as t, getStep as u };
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-Ce8s7XqV.js");
1
+ const require_dist = require("./dist-CJR259Xf.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
4
4
  /**
@@ -491,89 +491,68 @@ var OBJECT_DETECTION_MODELS = [
491
491
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "fp16", 112, true),
492
492
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "int8", 56, true)
493
493
  ];
494
- var FACE_DETECTION_MODELS = [
495
- {
496
- id: "scrfd-2.5g",
497
- name: "SCRFD 2.5G",
498
- description: "SCRFD 2.5G bnkps — balanced face detection with 5 keypoints (WIDER FACE 93.80/92.02/77.13). InsightFace pretrained weights.",
499
- inputSize: {
500
- width: 640,
501
- height: 640
502
- },
503
- labels: [{
504
- id: "face",
505
- name: "Face"
506
- }],
507
- preprocessMode: "letterbox",
508
- inputNormalization: "scrfd",
509
- license: "InsightFace-NonCommercial-Research",
510
- formats: {
511
- onnx: {
512
- url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
513
- sizeMB: 3.1
514
- },
515
- coreml: {
516
- url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
517
- sizeMB: 1.7,
518
- isDirectory: true,
519
- files: [...MLPACKAGE_FILES],
520
- runtimes: ["python"]
521
- },
522
- openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
523
- }
524
- },
525
- {
526
- id: "scrypted-yolov9t-face",
527
- name: "YOLOv9t Face ReLU",
528
- description: "YOLOv9t face detection — YOLO-based, fast, 320x320 ReLU",
529
- inputSize: {
530
- width: 320,
531
- height: 320
532
- },
533
- labels: [{
534
- id: "face",
535
- name: "Face"
536
- }],
537
- preprocessMode: "letterbox",
538
- license: "UNKNOWN",
539
- formats: {
540
- onnx: {
541
- url: hfScrypted("onnx/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.onnx"),
542
- sizeMB: 8.1
543
- },
544
- coreml: {
545
- url: hfScrypted("coreml/scrypted_yolov9t_relu_face/scrypted_yolov9t_relu_face.mlpackage"),
546
- sizeMB: 4,
547
- isDirectory: true,
548
- files: [...MLPACKAGE_FILES],
549
- runtimes: ["python"]
550
- },
551
- openvino: ovFormat(hf("faceDetection/scrypted-yolov9-face/openvino/scrypted_yolov9t_relu_face.xml"), 6)
552
- }
494
+ /**
495
+ * Model ids REMOVED from a step's catalog, per step id (D643).
496
+ *
497
+ * Not the same as `legacy` (still in the catalog, still runnable when chosen):
498
+ * a retired id has nothing to download and nothing that can parse it. It is
499
+ * listed rather than simply deleted because `resolveModelForFormat` passes an
500
+ * id the catalog does not know through UNCHANGED — it reads as an operator's
501
+ * custom model — so a saved pin would keep naming a model no node can load.
502
+ * A retired id resolves to the step's format default instead.
503
+ */
504
+ var RETIRED_MODEL_IDS = { "face-detection": ["scrypted-yolov9t-face"] };
505
+ var FACE_DETECTION_MODELS = [{
506
+ id: "scrfd-2.5g",
507
+ name: "SCRFD 2.5G",
508
+ description: "SCRFD 2.5G bnkps — balanced face detection with 5 keypoints (WIDER FACE 93.80/92.02/77.13). InsightFace pretrained weights.",
509
+ inputSize: {
510
+ width: 640,
511
+ height: 640
553
512
  },
554
- {
555
- id: "ssd-mobilenet-v2-face-edgetpu",
556
- legacy: true,
557
- name: "SSD MobileNet V2 Face (Coral)",
558
- description: "SSD MobileNet V2 face detector — EdgeTPU-compiled full-integer TFLite, 320×320; runs on the Coral USB Edge TPU. Requires an ssd-face postprocessor (not yet available).",
559
- inputSize: {
560
- width: 320,
561
- height: 320
513
+ labels: [{
514
+ id: "face",
515
+ name: "Face"
516
+ }],
517
+ preprocessMode: "letterbox",
518
+ inputNormalization: "scrfd",
519
+ license: "InsightFace-NonCommercial-Research",
520
+ formats: {
521
+ onnx: {
522
+ url: hf("faceDetection/scrfd/onnx/camstack-scrfd-2.5g.onnx"),
523
+ sizeMB: 3.1
562
524
  },
563
- labels: [{
564
- id: "face",
565
- name: "Face"
566
- }],
567
- preprocessMode: "letterbox",
568
- postprocessor: "ssd",
569
- license: "Apache-2.0",
570
- formats: { tflite: {
571
- url: "https://github.com/google-coral/test_data/raw/master/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite",
572
- sizeMB: 6.7,
525
+ coreml: {
526
+ url: hf("faceDetection/scrfd/coreml/camstack-scrfd-2.5g.mlpackage"),
527
+ sizeMB: 1.7,
528
+ isDirectory: true,
529
+ files: [...MLPACKAGE_FILES],
573
530
  runtimes: ["python"]
574
- } }
531
+ },
532
+ openvino: ovFormat(hf("faceDetection/scrfd/openvino/camstack-scrfd-2.5g.xml"), 1.8)
575
533
  }
576
- ];
534
+ }, {
535
+ id: "ssd-mobilenet-v2-face-edgetpu",
536
+ legacy: true,
537
+ name: "SSD MobileNet V2 Face (Coral)",
538
+ description: "SSD MobileNet V2 face detector — EdgeTPU-compiled full-integer TFLite, 320×320; runs on the Coral USB Edge TPU. Requires an ssd-face postprocessor (not yet available).",
539
+ inputSize: {
540
+ width: 320,
541
+ height: 320
542
+ },
543
+ labels: [{
544
+ id: "face",
545
+ name: "Face"
546
+ }],
547
+ preprocessMode: "letterbox",
548
+ postprocessor: "ssd",
549
+ license: "Apache-2.0",
550
+ formats: { tflite: {
551
+ url: "https://github.com/google-coral/test_data/raw/master/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite",
552
+ sizeMB: 6.7,
553
+ runtimes: ["python"]
554
+ } }
555
+ }];
577
556
  var FACE_EMBEDDING_MODELS = [
578
557
  {
579
558
  id: "arcface-r100",
@@ -1877,6 +1856,7 @@ function getDefaultModelForFormatFromDef(def, format) {
1877
1856
  * - chosen is a catalog model → keep it if it has a `format` build; else
1878
1857
  * the addon's default model for `format`
1879
1858
  * (a substitution — the caller surfaces it).
1859
+ * - chosen is RETIRED (`RETIRED_MODEL_IDS`) → the format default (D643).
1880
1860
  * - chosen is NOT in the catalog (custom/unknown) → returned unchanged; the
1881
1861
  * operator owns a custom model's format compat.
1882
1862
  * - unknown stepId → chosen returned unchanged (never throws).
@@ -1889,6 +1869,7 @@ function resolveModelForFormat(stepId, chosenModelId, format) {
1889
1869
  return chosenModelId ?? "";
1890
1870
  }
1891
1871
  if (chosenModelId === null) return getDefaultModelForFormat(stepId, format);
1872
+ if (RETIRED_MODEL_IDS[stepId]?.includes(chosenModelId) === true) return getDefaultModelForFormat(stepId, format);
1892
1873
  const entry = def.models.find((m) => m.id === chosenModelId);
1893
1874
  if (!entry) return chosenModelId;
1894
1875
  if (entry.formats[format]) return chosenModelId;
@@ -2244,6 +2225,12 @@ Object.defineProperty(exports, "OBJECT_DETECTION_STEP_ID", {
2244
2225
  return OBJECT_DETECTION_STEP_ID;
2245
2226
  }
2246
2227
  });
2228
+ Object.defineProperty(exports, "RETIRED_MODEL_IDS", {
2229
+ enumerable: true,
2230
+ get: function() {
2231
+ return RETIRED_MODEL_IDS;
2232
+ }
2233
+ });
2247
2234
  Object.defineProperty(exports, "getDefaultModelForFormat", {
2248
2235
  enumerable: true,
2249
2236
  get: function() {
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Ce8s7XqV.js");
7
- const require_node = require("../node-DpOrymbW.js");
8
- const require_default_detection_model = require("../default-detection-model-DTKHLLcC.js");
6
+ const require_dist = require("../dist-CJR259Xf.js");
7
+ const require_node = require("../node-DWg9zbY1.js");
8
+ const require_default_detection_model = require("../default-detection-model-D24AJOTn.js");
9
9
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
10
- const require_process_memory = require("../process-memory-CBRjuhyg.js");
10
+ const require_process_memory = require("../process-memory-BJUXvTjd.js");
11
11
  let node_os = require("node:os");
12
12
  node_os = require_chunk.__toESM(node_os);
13
13
  let node_fs = require("node:fs");
@@ -5062,7 +5062,8 @@ function buildFrameResult(input) {
5062
5062
  ...embeddingModelId !== void 0 ? { embeddingModelId } : {}
5063
5063
  } : {},
5064
5064
  ...m.faceAlignedCrop !== void 0 ? { faceAlignedCrop: m.faceAlignedCrop } : {},
5065
- ...m.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: m.nativeFaceShortSidePx } : {}
5065
+ ...m.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: m.nativeFaceShortSidePx } : {},
5066
+ ...m.landmarks !== void 0 ? { landmarks: m.landmarks } : {}
5066
5067
  };
5067
5068
  if (input.debug) {
5068
5069
  const cleanDebug = pruneUndefined({
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $ as defaultDeviceFor$1, $t as errMsg, A as PoolMemoryWatchdog, En as array, Et as overlayClusterStepSettings, Fn as string, Gt as runtimeDevices$1, In as union, Ln as EventCategory, Mn as object, Mt as pipelineExecutorCapability, Ot as pickClusterStepModels, Ut as resolvePoolMemoryPolicy, V as YAMNET_TO_MACRO, Xt as supportedRuntimes$1, _t as loadContributionCapability, bn as nodePin, ct as evaluateZoneRules, f as DEFAULT_CLUSTER_STEP_MODELS, fn as createEvent, gn as hydrateSchema, ht as inferModelProvider, kt as pickClusterStepSettings, on as BaseAddon, ot as enumerateInferenceDevices, p as DEFAULT_CLUSTER_STEP_SETTINGS, rt as detectionPipelineCapability, t as APPLE_SA_TO_MACRO, v as DEVICE_BACKEND_TO_FORMAT, wn as sleep, xn as parseJsonUnknown, zt as resolveClusterStepModelId } from "../dist-C0Fr4hM5.mjs";
3
- import { s as readProcessCost } from "../node-Xm7amG2e.mjs";
4
- import { a as localFrameRegistry, c as ALL_STEPS, d as getStepDefinition, f as resolveModelForFormat, l as getDefaultModelForFormat, n as resolveDefaultDetectionModel, p as landmarkPrecisionVerdict, r as macroGateVerdict, s as ALL_PIPELINE_STEPS, u as getStep } from "../default-detection-model-DCQlW9fx.mjs";
2
+ import { $ as defaultDeviceFor$1, $t as errMsg, A as PoolMemoryWatchdog, En as array, Et as overlayClusterStepSettings, Fn as string, Gt as runtimeDevices$1, In as union, Ln as EventCategory, Mn as object, Mt as pipelineExecutorCapability, Ot as pickClusterStepModels, Ut as resolvePoolMemoryPolicy, V as YAMNET_TO_MACRO, Xt as supportedRuntimes$1, _t as loadContributionCapability, bn as nodePin, ct as evaluateZoneRules, f as DEFAULT_CLUSTER_STEP_MODELS, fn as createEvent, gn as hydrateSchema, ht as inferModelProvider, kt as pickClusterStepSettings, on as BaseAddon, ot as enumerateInferenceDevices, p as DEFAULT_CLUSTER_STEP_SETTINGS, rt as detectionPipelineCapability, t as APPLE_SA_TO_MACRO, v as DEVICE_BACKEND_TO_FORMAT, wn as sleep, xn as parseJsonUnknown, zt as resolveClusterStepModelId } from "../dist-RXbmRAwP.mjs";
3
+ import { s as readProcessCost } from "../node-atmRSHPk.mjs";
4
+ import { a as localFrameRegistry, c as ALL_STEPS, d as getStepDefinition, f as resolveModelForFormat, l as getDefaultModelForFormat, m as landmarkPrecisionVerdict, n as resolveDefaultDetectionModel, r as macroGateVerdict, s as ALL_PIPELINE_STEPS, u as getStep } from "../default-detection-model-0dPKRKUD.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BN5qYGsD.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-BgFOHFnx.mjs";
7
7
  import * as os from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -5055,7 +5055,8 @@ function buildFrameResult(input) {
5055
5055
  ...embeddingModelId !== void 0 ? { embeddingModelId } : {}
5056
5056
  } : {},
5057
5057
  ...m.faceAlignedCrop !== void 0 ? { faceAlignedCrop: m.faceAlignedCrop } : {},
5058
- ...m.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: m.nativeFaceShortSidePx } : {}
5058
+ ...m.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: m.nativeFaceShortSidePx } : {},
5059
+ ...m.landmarks !== void 0 ? { landmarks: m.landmarks } : {}
5059
5060
  };
5060
5061
  if (input.debug) {
5061
5062
  const cleanDebug = pruneUndefined({
@@ -24768,7 +24768,17 @@ var DetailResultSchema = object({
24768
24768
  /** Face short side (px) measured on the NATIVE crop surface. The `bbox`
24769
24769
  * above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
24770
24770
  * consumers MUST prefer this when present (2026-07-22 native-gate fix). */
24771
- nativeFaceShortSidePx: number().optional()
24771
+ nativeFaceShortSidePx: number().optional(),
24772
+ /**
24773
+ * The five facial landmarks of a `face` detail, in the SAME frame space as
24774
+ * `bbox` (D644). Additive and optional: post-analysis stores them beside the
24775
+ * face's source frame so a future alignment can be re-derived exactly; a
24776
+ * runner that predates the field sends none and the face is stored without.
24777
+ */
24778
+ landmarks: array(object({
24779
+ x: number(),
24780
+ y: number()
24781
+ })).optional()
24772
24782
  });
24773
24783
  /**
24774
24784
  * Why an executing node REFUSED a stateless step run (`runStatelessStep`).
@@ -24768,7 +24768,17 @@ var DetailResultSchema = object({
24768
24768
  /** Face short side (px) measured on the NATIVE crop surface. The `bbox`
24769
24769
  * above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
24770
24770
  * consumers MUST prefer this when present (2026-07-22 native-gate fix). */
24771
- nativeFaceShortSidePx: number().optional()
24771
+ nativeFaceShortSidePx: number().optional(),
24772
+ /**
24773
+ * The five facial landmarks of a `face` detail, in the SAME frame space as
24774
+ * `bbox` (D644). Additive and optional: post-analysis stores them beside the
24775
+ * face's source frame so a future alignment can be re-derived exactly; a
24776
+ * runner that predates the field sends none and the face is stored without.
24777
+ */
24778
+ landmarks: array(object({
24779
+ x: number(),
24780
+ y: number()
24781
+ })).optional()
24772
24782
  });
24773
24783
  /**
24774
24784
  * Why an executing node REFUSED a stateless step run (`runStatelessStep`).
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-Ce8s7XqV.js");
5
+ const require_dist = require("../dist-CJR259Xf.js");
6
6
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
7
7
  let node_fs = require("node:fs");
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { Tt as motionDetectionCapability, ct as evaluateZoneRules, gn as hydrateSchema, on as BaseAddon, un as DeviceType } from "../dist-C0Fr4hM5.mjs";
1
+ import { Tt as motionDetectionCapability, ct as evaluateZoneRules, gn as hydrateSchema, on as BaseAddon, un as DeviceType } from "../dist-RXbmRAwP.mjs";
2
2
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-Ce8s7XqV.js");
2
+ const require_dist = require("./dist-CJR259Xf.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  let node_fs = require("node:fs");
5
5
  node_fs = require_chunk.__toESM(node_fs, 1);
@@ -1,4 +1,4 @@
1
- import { $t as errMsg, in as isSoftwareDecode, nn as buildFfmpegArgs, tn as Fmp4BoxSplitter } from "./dist-C0Fr4hM5.mjs";
1
+ import { $t as errMsg, in as isSoftwareDecode, nn as buildFfmpegArgs, tn as Fmp4BoxSplitter } from "./dist-RXbmRAwP.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { realpathSync } from "node:fs";
4
4
  import path from "node:path";
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Ce8s7XqV.js");
7
- const require_node = require("../node-DpOrymbW.js");
8
- const require_default_detection_model = require("../default-detection-model-DTKHLLcC.js");
6
+ const require_dist = require("../dist-CJR259Xf.js");
7
+ const require_node = require("../node-DWg9zbY1.js");
8
+ const require_default_detection_model = require("../default-detection-model-D24AJOTn.js");
9
9
  const require_worker_protocol = require("../worker-protocol-B2MfQLlu.js");
10
10
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
11
11
  const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
@@ -1024,6 +1024,68 @@ var ParkedFrameStore = class {
1024
1024
  }
1025
1025
  }
1026
1026
  };
1027
+ /**
1028
+ * The key prefix the hub parks a face's SOURCE frame under (D644). The hub
1029
+ * owns the key; the runner reads only this prefix, to keep those parcels in
1030
+ * their own budget. Mirrors `FACE_SOURCE_PARK_PREFIX` in addon-post-analysis
1031
+ * (`runtime/face-source-park-port.ts`) — both specs pin the literal.
1032
+ */
1033
+ var FACE_SOURCE_PARCEL_PREFIX = "face-src:";
1034
+ /** Is this key a face source parcel? */
1035
+ function isFaceSourceParcelKey(trackId) {
1036
+ return trackId.startsWith(FACE_SOURCE_PARCEL_PREFIX);
1037
+ }
1038
+ /**
1039
+ * Track parcels and face source parcels in TWO stores with two budgets (D644).
1040
+ *
1041
+ * A face source parcel is a full native frame parked on every held best face.
1042
+ * In the shared store its eviction took the GLOBALLY oldest parcel — a
1043
+ * track's `keyFrame` or `thumbnail` — so a busy face scene could cost a track
1044
+ * its best frame (D58: media a later pass depends on must land). Here a face
1045
+ * parcel can only ever evict another face parcel.
1046
+ */
1047
+ var PartitionedParkedFrameStore = class {
1048
+ track;
1049
+ faceSource;
1050
+ constructor(options = {}) {
1051
+ this.track = new ParkedFrameStore(options.track);
1052
+ this.faceSource = new ParkedFrameStore({
1053
+ budgetBytes: 16 * 1024 * 1024,
1054
+ perDeviceMax: 4,
1055
+ ...options.faceSource
1056
+ });
1057
+ }
1058
+ storeFor(trackId) {
1059
+ return isFaceSourceParcelKey(trackId) ? this.faceSource : this.track;
1060
+ }
1061
+ get size() {
1062
+ return this.track.size + this.faceSource.size;
1063
+ }
1064
+ get bytes() {
1065
+ return this.track.bytes + this.faceSource.bytes;
1066
+ }
1067
+ park(deviceId, trackId, kind, frame) {
1068
+ return this.storeFor(trackId).park(deviceId, trackId, kind, frame);
1069
+ }
1070
+ get(deviceId, trackId, kind) {
1071
+ return this.storeFor(trackId).get(deviceId, trackId, kind);
1072
+ }
1073
+ release(deviceId, trackId) {
1074
+ return this.storeFor(trackId).release(deviceId, trackId);
1075
+ }
1076
+ statsByDevice(deviceId) {
1077
+ const a = this.track.statsByDevice(deviceId);
1078
+ const b = this.faceSource.statsByDevice(deviceId);
1079
+ return {
1080
+ parcels: a.parcels + b.parcels,
1081
+ bytes: a.bytes + b.bytes
1082
+ };
1083
+ }
1084
+ clear() {
1085
+ this.track.clear();
1086
+ this.faceSource.clear();
1087
+ }
1088
+ };
1027
1089
  /** {@link RETAINED_FRAME_BUDGET_MB} in bytes. */
1028
1090
  var RETAINED_FRAME_BUDGET_BYTES = (() => {
1029
1091
  const raw = Number(process.env["CAMSTACK_SESSION_RETAIN_MB"]);
@@ -3298,7 +3360,14 @@ function toDetailResult(detection, stepId, crop) {
3298
3360
  ...label.modelId !== void 0 ? { labelModelId: label.modelId } : {}
3299
3361
  } : {},
3300
3362
  ...detection.faceAlignedCrop !== void 0 ? { alignedCropJpeg: detection.faceAlignedCrop } : {},
3301
- ...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {}
3363
+ ...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {},
3364
+ ...detection.landmarks !== void 0 ? { landmarks: detection.landmarks.map((p) => mapPointToFrameSpace(p, crop)) } : {}
3365
+ };
3366
+ }
3367
+ function mapPointToFrameSpace(point, crop) {
3368
+ return {
3369
+ x: crop.frameSpace.x + point.x * (crop.frameSpace.w / crop.width),
3370
+ y: crop.frameSpace.y + point.y * (crop.frameSpace.h / crop.height)
3302
3371
  };
3303
3372
  }
3304
3373
  /**
@@ -6605,6 +6674,7 @@ var PipelineRunner = class {
6605
6674
  //#endregion
6606
6675
  //#region src/pipeline-runner/stateless-step.ts
6607
6676
  function modelServability(step, modelId, format) {
6677
+ if (require_default_detection_model.RETIRED_MODEL_IDS[step.id]?.includes(modelId) === true) return { kind: "retired" };
6608
6678
  const entry = step.models.find((m) => m.id === modelId);
6609
6679
  if (entry === void 0) return { kind: "custom-model" };
6610
6680
  if (entry.formats[format] !== void 0) return { kind: "catalog-build" };
@@ -6649,6 +6719,7 @@ async function runStatelessStep(deps, input) {
6649
6719
  const format = await deps.executionFormat();
6650
6720
  if (format === null) return refuse(deps, input, "model-not-servable", "this node could not report the engine format it would dispatch on, so the model pin cannot be verified — running anyway would risk a silent format substitution");
6651
6721
  const servability = modelServability(definition, input.modelId, format);
6722
+ if (servability.kind === "retired") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" was retired from the ${definition.id} catalog — this node would have substituted the step default`);
6652
6723
  if (servability.kind === "no-build") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" has no ${format} build (catalog ships: ${servability.availableFormats.join(", ") || "none"}) — this node would have substituted the ${format} default`);
6653
6724
  let decodeError = null;
6654
6725
  const crop = await cutFromFullFrame(input.frameJpeg, {
@@ -7582,7 +7653,11 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
7582
7653
  nodeId: this.nodeId,
7583
7654
  continuousRetain: isContinuousRetainEnabled()
7584
7655
  });
7585
- this.parkedFrames = new ParkedFrameStore({ onEvict: (eviction) => this.noteParkedEviction(eviction.deviceId, eviction.cause) });
7656
+ const onEvict = (eviction) => this.noteParkedEviction(eviction.deviceId, eviction.cause);
7657
+ this.parkedFrames = new PartitionedParkedFrameStore({
7658
+ track: { onEvict },
7659
+ faceSource: { onEvict }
7660
+ });
7586
7661
  this.runner = new PipelineRunner({
7587
7662
  maxQueueDepth: this.config.maxQueueDepth,
7588
7663
  maxConcurrentInferences: this.config.maxConcurrentInferences,
@@ -1,6 +1,6 @@
1
- import { $t as errMsg, An as literal, At as pickDetailCropConvention, C as FailureCounters, D as NativeLeaseAdmissionSchema, Dn as boolean, E as MOTION_CLOSE_AFTER_MS, En as array, Fn as string, Ln as EventCategory, Mn as object, Nt as pipelineRunnerCapability, O as NativeLeaseSettingsSchema, Tn as _enum, _ as DEFAULT_NATIVE_LEASE_SETTINGS, _t as loadContributionCapability, bn as nodePin, fn as createEvent, ft as failureContributionCapability, jn as number, jt as pickNativeLeaseOverride, kn as lazy, m as DEFAULT_DETAIL_CROP_CONVENTION, mn as defineCustomActions, on as BaseAddon, pn as customAction, tt as deriveDetailCropRect, v as DEVICE_BACKEND_TO_FORMAT } from "../dist-C0Fr4hM5.mjs";
2
- import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-Xm7amG2e.mjs";
3
- import { a as localFrameRegistry, d as getStepDefinition, i as rootObjectGate, o as resolveFrameViewGeometry, r as macroGateVerdict } from "../default-detection-model-DCQlW9fx.mjs";
1
+ import { $t as errMsg, An as literal, At as pickDetailCropConvention, C as FailureCounters, D as NativeLeaseAdmissionSchema, Dn as boolean, E as MOTION_CLOSE_AFTER_MS, En as array, Fn as string, Ln as EventCategory, Mn as object, Nt as pipelineRunnerCapability, O as NativeLeaseSettingsSchema, Tn as _enum, _ as DEFAULT_NATIVE_LEASE_SETTINGS, _t as loadContributionCapability, bn as nodePin, fn as createEvent, ft as failureContributionCapability, jn as number, jt as pickNativeLeaseOverride, kn as lazy, m as DEFAULT_DETAIL_CROP_CONVENTION, mn as defineCustomActions, on as BaseAddon, pn as customAction, tt as deriveDetailCropRect, v as DEVICE_BACKEND_TO_FORMAT } from "../dist-RXbmRAwP.mjs";
2
+ import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-atmRSHPk.mjs";
3
+ import { a as localFrameRegistry, d as getStepDefinition, i as rootObjectGate, o as resolveFrameViewGeometry, p as RETIRED_MODEL_IDS, r as macroGateVerdict } from "../default-detection-model-0dPKRKUD.mjs";
4
4
  import { t as isWorkerReply } from "../worker-protocol-C_W-P_g-.mjs";
5
5
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
6
6
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
@@ -1017,6 +1017,68 @@ var ParkedFrameStore = class {
1017
1017
  }
1018
1018
  }
1019
1019
  };
1020
+ /**
1021
+ * The key prefix the hub parks a face's SOURCE frame under (D644). The hub
1022
+ * owns the key; the runner reads only this prefix, to keep those parcels in
1023
+ * their own budget. Mirrors `FACE_SOURCE_PARK_PREFIX` in addon-post-analysis
1024
+ * (`runtime/face-source-park-port.ts`) — both specs pin the literal.
1025
+ */
1026
+ var FACE_SOURCE_PARCEL_PREFIX = "face-src:";
1027
+ /** Is this key a face source parcel? */
1028
+ function isFaceSourceParcelKey(trackId) {
1029
+ return trackId.startsWith(FACE_SOURCE_PARCEL_PREFIX);
1030
+ }
1031
+ /**
1032
+ * Track parcels and face source parcels in TWO stores with two budgets (D644).
1033
+ *
1034
+ * A face source parcel is a full native frame parked on every held best face.
1035
+ * In the shared store its eviction took the GLOBALLY oldest parcel — a
1036
+ * track's `keyFrame` or `thumbnail` — so a busy face scene could cost a track
1037
+ * its best frame (D58: media a later pass depends on must land). Here a face
1038
+ * parcel can only ever evict another face parcel.
1039
+ */
1040
+ var PartitionedParkedFrameStore = class {
1041
+ track;
1042
+ faceSource;
1043
+ constructor(options = {}) {
1044
+ this.track = new ParkedFrameStore(options.track);
1045
+ this.faceSource = new ParkedFrameStore({
1046
+ budgetBytes: 16 * 1024 * 1024,
1047
+ perDeviceMax: 4,
1048
+ ...options.faceSource
1049
+ });
1050
+ }
1051
+ storeFor(trackId) {
1052
+ return isFaceSourceParcelKey(trackId) ? this.faceSource : this.track;
1053
+ }
1054
+ get size() {
1055
+ return this.track.size + this.faceSource.size;
1056
+ }
1057
+ get bytes() {
1058
+ return this.track.bytes + this.faceSource.bytes;
1059
+ }
1060
+ park(deviceId, trackId, kind, frame) {
1061
+ return this.storeFor(trackId).park(deviceId, trackId, kind, frame);
1062
+ }
1063
+ get(deviceId, trackId, kind) {
1064
+ return this.storeFor(trackId).get(deviceId, trackId, kind);
1065
+ }
1066
+ release(deviceId, trackId) {
1067
+ return this.storeFor(trackId).release(deviceId, trackId);
1068
+ }
1069
+ statsByDevice(deviceId) {
1070
+ const a = this.track.statsByDevice(deviceId);
1071
+ const b = this.faceSource.statsByDevice(deviceId);
1072
+ return {
1073
+ parcels: a.parcels + b.parcels,
1074
+ bytes: a.bytes + b.bytes
1075
+ };
1076
+ }
1077
+ clear() {
1078
+ this.track.clear();
1079
+ this.faceSource.clear();
1080
+ }
1081
+ };
1020
1082
  /** {@link RETAINED_FRAME_BUDGET_MB} in bytes. */
1021
1083
  var RETAINED_FRAME_BUDGET_BYTES = (() => {
1022
1084
  const raw = Number(process.env["CAMSTACK_SESSION_RETAIN_MB"]);
@@ -3290,7 +3352,14 @@ function toDetailResult(detection, stepId, crop) {
3290
3352
  ...label.modelId !== void 0 ? { labelModelId: label.modelId } : {}
3291
3353
  } : {},
3292
3354
  ...detection.faceAlignedCrop !== void 0 ? { alignedCropJpeg: detection.faceAlignedCrop } : {},
3293
- ...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {}
3355
+ ...detection.nativeFaceShortSidePx !== void 0 ? { nativeFaceShortSidePx: detection.nativeFaceShortSidePx } : {},
3356
+ ...detection.landmarks !== void 0 ? { landmarks: detection.landmarks.map((p) => mapPointToFrameSpace(p, crop)) } : {}
3357
+ };
3358
+ }
3359
+ function mapPointToFrameSpace(point, crop) {
3360
+ return {
3361
+ x: crop.frameSpace.x + point.x * (crop.frameSpace.w / crop.width),
3362
+ y: crop.frameSpace.y + point.y * (crop.frameSpace.h / crop.height)
3294
3363
  };
3295
3364
  }
3296
3365
  /**
@@ -6597,6 +6666,7 @@ var PipelineRunner = class {
6597
6666
  //#endregion
6598
6667
  //#region src/pipeline-runner/stateless-step.ts
6599
6668
  function modelServability(step, modelId, format) {
6669
+ if (RETIRED_MODEL_IDS[step.id]?.includes(modelId) === true) return { kind: "retired" };
6600
6670
  const entry = step.models.find((m) => m.id === modelId);
6601
6671
  if (entry === void 0) return { kind: "custom-model" };
6602
6672
  if (entry.formats[format] !== void 0) return { kind: "catalog-build" };
@@ -6641,6 +6711,7 @@ async function runStatelessStep(deps, input) {
6641
6711
  const format = await deps.executionFormat();
6642
6712
  if (format === null) return refuse(deps, input, "model-not-servable", "this node could not report the engine format it would dispatch on, so the model pin cannot be verified — running anyway would risk a silent format substitution");
6643
6713
  const servability = modelServability(definition, input.modelId, format);
6714
+ if (servability.kind === "retired") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" was retired from the ${definition.id} catalog — this node would have substituted the step default`);
6644
6715
  if (servability.kind === "no-build") return refuse(deps, input, "model-not-servable", `model "${input.modelId}" has no ${format} build (catalog ships: ${servability.availableFormats.join(", ") || "none"}) — this node would have substituted the ${format} default`);
6645
6716
  let decodeError = null;
6646
6717
  const crop = await cutFromFullFrame(input.frameJpeg, {
@@ -7574,7 +7645,11 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
7574
7645
  nodeId: this.nodeId,
7575
7646
  continuousRetain: isContinuousRetainEnabled()
7576
7647
  });
7577
- this.parkedFrames = new ParkedFrameStore({ onEvict: (eviction) => this.noteParkedEviction(eviction.deviceId, eviction.cause) });
7648
+ const onEvict = (eviction) => this.noteParkedEviction(eviction.deviceId, eviction.cause);
7649
+ this.parkedFrames = new PartitionedParkedFrameStore({
7650
+ track: { onEvict },
7651
+ faceSource: { onEvict }
7652
+ });
7578
7653
  this.runner = new PipelineRunner({
7579
7654
  maxQueueDepth: this.config.maxQueueDepth,
7580
7655
  maxConcurrentInferences: this.config.maxConcurrentInferences,
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-Ce8s7XqV.js");
2
+ const require_dist = require("./dist-CJR259Xf.js");
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_chunk.__toESM(node_fs);
5
5
  let node_child_process = require("node:child_process");
@@ -1,4 +1,4 @@
1
- import { Dt as parseProcStatus } from "./dist-C0Fr4hM5.mjs";
1
+ import { Dt as parseProcStatus } from "./dist-RXbmRAwP.mjs";
2
2
  import * as fs from "node:fs";
3
3
  import { execFile } from "node:child_process";
4
4
  //#region src/shared/node-topology-platform.ts
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Ce8s7XqV.js");
7
- const require_node = require("../node-DpOrymbW.js");
6
+ const require_dist = require("../dist-CJR259Xf.js");
7
+ const require_node = require("../node-DWg9zbY1.js");
8
8
  const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
9
9
  const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
10
10
  const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
@@ -1,5 +1,5 @@
1
- import { $t as errMsg, B as VISIT_MERGE_GAP_MS, Bt as resolveCreateExportSubject, Cn as selectAssignedProfileSlots, Ct as migrateLegacyDeviceSignalConfig, Dn as boolean, En as array, F as RECORDING_SOURCE_CAMSTACK_ADDON, Fn as string, Ft as recordingArchiveCapability, Ht as resolveLocationMode, I as RecordingConfigSchema, It as recordingCapability, J as clipExportFailure, K as batteryCapability, Kt as storageEvictableCapability, L as RecordingSignalStatusSchema, Ln as EventCategory, Lt as recordingExportCapability, Mn as object, N as RECORDING_EXPORT_MAX_READ_BYTES, Nn as preprocess, P as RECORDING_SOURCE_CAMSTACK, Pn as record, Rt as recordingSignalCapability, S as ExportRecordSchema, St as mayWriteToLocation, Tn as _enum, Wt as resolveRecordingProfiles, Y as clipExportFailureOf, Yt as stripRetiredBandPreBufferSec, Zt as videoclipsCapability, _t as loadContributionCapability, a as CLIP_BROKER_PACED_RATES, b as EVENT_PAD_MS, bn as nodePin, dt as exportSubjectOf, et as deriveBatteryPresence, gn as hydrateSchema, gt as isFirstLevelMacroClass, h as DEFAULT_EVENTS_BAND_BUFFER_SEC, i as BatteryStatusSchema, jn as number, k as OpsLogEntrySchema, ln as DeviceFeature, lt as evictionPolicyForMode, mn as defineCustomActions, nt as deriveRecordingMode, on as BaseAddon, pn as customAction, pt as gbToBytes, qt as storageOccupancyCapability, st as evaluateSensorEdge, un as DeviceType, ut as evictionPolicyOfLocation, wn as sleep$1, wt as modeMayWrite, xt as mayReadLocation, y as EVENT_OWNER_TYPES, z as VIDEOCLIPS_MAX_OFFER_BYTES } from "../dist-C0Fr4hM5.mjs";
2
- import { a as physicalRootOf, i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-Xm7amG2e.mjs";
1
+ import { $t as errMsg, B as VISIT_MERGE_GAP_MS, Bt as resolveCreateExportSubject, Cn as selectAssignedProfileSlots, Ct as migrateLegacyDeviceSignalConfig, Dn as boolean, En as array, F as RECORDING_SOURCE_CAMSTACK_ADDON, Fn as string, Ft as recordingArchiveCapability, Ht as resolveLocationMode, I as RecordingConfigSchema, It as recordingCapability, J as clipExportFailure, K as batteryCapability, Kt as storageEvictableCapability, L as RecordingSignalStatusSchema, Ln as EventCategory, Lt as recordingExportCapability, Mn as object, N as RECORDING_EXPORT_MAX_READ_BYTES, Nn as preprocess, P as RECORDING_SOURCE_CAMSTACK, Pn as record, Rt as recordingSignalCapability, S as ExportRecordSchema, St as mayWriteToLocation, Tn as _enum, Wt as resolveRecordingProfiles, Y as clipExportFailureOf, Yt as stripRetiredBandPreBufferSec, Zt as videoclipsCapability, _t as loadContributionCapability, a as CLIP_BROKER_PACED_RATES, b as EVENT_PAD_MS, bn as nodePin, dt as exportSubjectOf, et as deriveBatteryPresence, gn as hydrateSchema, gt as isFirstLevelMacroClass, h as DEFAULT_EVENTS_BAND_BUFFER_SEC, i as BatteryStatusSchema, jn as number, k as OpsLogEntrySchema, ln as DeviceFeature, lt as evictionPolicyForMode, mn as defineCustomActions, nt as deriveRecordingMode, on as BaseAddon, pn as customAction, pt as gbToBytes, qt as storageOccupancyCapability, st as evaluateSensorEdge, un as DeviceType, ut as evictionPolicyOfLocation, wn as sleep$1, wt as modeMayWrite, xt as mayReadLocation, y as EVENT_OWNER_TYPES, z as VIDEOCLIPS_MAX_OFFER_BYTES } from "../dist-RXbmRAwP.mjs";
2
+ import { a as physicalRootOf, i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-atmRSHPk.mjs";
3
3
  import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
4
4
  import { d as PREBUFFER_MAX_MS, l as withRecordingIntent, r as RECORDING_PRE_ROLL_REQUEST_MS } from "../restream-intent-DyGmLAU9.mjs";
5
5
  import { n as RowMapStore, t as retireRootKeys } from "../retire-root-keys-DZvlso2l.mjs";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-emK7D4bc.js");
2
- const require_dist = require("./dist-Ce8s7XqV.js");
2
+ const require_dist = require("./dist-CJR259Xf.js");
3
3
  let node_child_process = require("node:child_process");
4
4
  //#region src/stream-broker/recorded/avcc-annexb.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./chunk-DnnnRqeS.mjs";
2
- import { $t as errMsg } from "./dist-C0Fr4hM5.mjs";
2
+ import { $t as errMsg } from "./dist-RXbmRAwP.mjs";
3
3
  import { spawn } from "node:child_process";
4
4
  //#region src/stream-broker/recorded/avcc-annexb.ts
5
5
  /**
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.258",
21
+ version: "1.2.259",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_stream_broker_widgets",
@@ -1,4 +1,4 @@
1
- const require_segment_demux_js = require("../segment-demux-js-BhMlS_Ow.js");
1
+ const require_segment_demux_js = require("../segment-demux-js-C_fPJub3.js");
2
2
  let node_worker_threads = require("node:worker_threads");
3
3
  //#region src/stream-broker/recorded/demux-worker-child.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as demuxSegmentFullJs } from "../segment-demux-js-Bhwpj5Wl.mjs";
1
+ import { t as demuxSegmentFullJs } from "../segment-demux-js-G7wFpHzn.mjs";
2
2
  import { parentPort } from "node:worker_threads";
3
3
  //#region src/stream-broker/recorded/demux-worker-child.ts
4
4
  /**
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.258",
39
+ version: "1.2.259",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -3,12 +3,12 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../chunk-emK7D4bc.js");
6
- const require_dist = require("../dist-Ce8s7XqV.js");
7
- const require_node = require("../node-DpOrymbW.js");
6
+ const require_dist = require("../dist-CJR259Xf.js");
7
+ const require_node = require("../node-DWg9zbY1.js");
8
8
  const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
9
9
  const require_remote_restream = require("../remote-restream-CO36Sr30.js");
10
10
  const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
11
- const require_segment_demux_js = require("../segment-demux-js-BhMlS_Ow.js");
11
+ const require_segment_demux_js = require("../segment-demux-js-C_fPJub3.js");
12
12
  let node_os = require("node:os");
13
13
  node_os = require_chunk.__toESM(node_os);
14
14
  let node_crypto = require("node:crypto");
@@ -1,10 +1,10 @@
1
1
  import { r as __toESM } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as errMsg, An as literal, Dn as boolean, En as array, Fn as string, H as addonWidgetsSourceCapability, In as union, Jt as streamBrokerCapability, K as batteryCapability, Ln as EventCategory, M as RATE_CONTROL_TIGHT, Mn as object, On as discriminatedUnion, Pn as record, Pt as rankStreams, Q as declareLogChannel, Qt as webrtcSessionCapability, R as RingBuffer, Sn as parseProfileBrokerId, Tn as _enum, Vt as resolveEgressDecodeHwAccel, X as createHwAccelCache, Y as clipExportFailureOf, Z as createLogChannelsProvider, _n as isEvent, _t as loadContributionCapability, a as CLIP_BROKER_PACED_RATES, an as BOOT_RECOVERY_BACKOFF_MS, at as egressTransportFromRequest, bn as nodePin, bt as maskUrlCredentials, cn as CamProfileSchema, en as AUDIO_PRESETS, et as deriveBatteryPresence, fn as createEvent, hn as expandAudioChunkToF32le, i as BatteryStatusSchema, in as isSoftwareDecode, it as egressTranscodeSharingKey, j as RATE_CONTROL_RELAXED, jn as number, ln as DeviceFeature, nn as buildFfmpegArgs$1, o as CLIP_STILL_REASON_CODE_HEADER, on as BaseAddon, q as cameraStreamsCapability, rn as invocationFromEncodeProfile, sn as CAM_PROFILE_ORDER, un as DeviceType, vn as makeProfileBrokerId, vt as logChannelsCapability, w as G711_SCALE_CORRECTION_DB, x as EncodeProfileSchema, yn as makeSourceBrokerId } from "../dist-C0Fr4hM5.mjs";
3
- import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, o as probeFfmpegBinary, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-Xm7amG2e.mjs";
2
+ import { $t as errMsg, An as literal, Dn as boolean, En as array, Fn as string, H as addonWidgetsSourceCapability, In as union, Jt as streamBrokerCapability, K as batteryCapability, Ln as EventCategory, M as RATE_CONTROL_TIGHT, Mn as object, On as discriminatedUnion, Pn as record, Pt as rankStreams, Q as declareLogChannel, Qt as webrtcSessionCapability, R as RingBuffer, Sn as parseProfileBrokerId, Tn as _enum, Vt as resolveEgressDecodeHwAccel, X as createHwAccelCache, Y as clipExportFailureOf, Z as createLogChannelsProvider, _n as isEvent, _t as loadContributionCapability, a as CLIP_BROKER_PACED_RATES, an as BOOT_RECOVERY_BACKOFF_MS, at as egressTransportFromRequest, bn as nodePin, bt as maskUrlCredentials, cn as CamProfileSchema, en as AUDIO_PRESETS, et as deriveBatteryPresence, fn as createEvent, hn as expandAudioChunkToF32le, i as BatteryStatusSchema, in as isSoftwareDecode, it as egressTranscodeSharingKey, j as RATE_CONTROL_RELAXED, jn as number, ln as DeviceFeature, nn as buildFfmpegArgs$1, o as CLIP_STILL_REASON_CODE_HEADER, on as BaseAddon, q as cameraStreamsCapability, rn as invocationFromEncodeProfile, sn as CAM_PROFILE_ORDER, un as DeviceType, vn as makeProfileBrokerId, vt as logChannelsCapability, w as G711_SCALE_CORRECTION_DB, x as EncodeProfileSchema, yn as makeSourceBrokerId } from "../dist-RXbmRAwP.mjs";
3
+ import { i as NO_COST_CLAIM, n as Fmp4FragmentChild, o as probeFfmpegBinary, r as Fmp4FragmentPlane, t as ChildCostRegistry } from "../node-atmRSHPk.mjs";
4
4
  import { a as parseRestreamPath, d as PREBUFFER_MAX_MS, f as capPreRollRequestMs, i as isLiveEdgeOnlyDial, m as resolvePrebuffer, n as NO_DECLARATION, p as prebufferRetentionMs, s as sdpVariantFor, u as withSentryIntent } from "../restream-intent-DyGmLAU9.mjs";
5
5
  import { n as profileForStreamId } from "../remote-restream-BeHi78PZ.mjs";
6
6
  import { n as RowMapStore, t as retireRootKeys } from "../retire-root-keys-DZvlso2l.mjs";
7
- import { a as avccSampleToAnnexB, i as require_mp4box_all, n as demuxSegmentPreferJs, o as buildKeyframeAnnexB, r as runFfmpegOnce, s as parseNalLengthSize, t as demuxSegmentFullJs } from "../segment-demux-js-Bhwpj5Wl.mjs";
7
+ import { a as avccSampleToAnnexB, i as require_mp4box_all, n as demuxSegmentPreferJs, o as buildKeyframeAnnexB, r as runFfmpegOnce, s as parseNalLengthSize, t as demuxSegmentFullJs } from "../segment-demux-js-G7wFpHzn.mjs";
8
8
  import { createRequire } from "node:module";
9
9
  import * as os from "node:os";
10
10
  import { networkInterfaces, tmpdir } from "node:os";
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DKd7oYba.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-6IyM-BIn.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline",
3
- "version": "1.2.293",
3
+ "version": "1.2.294",
4
4
  "description": "Pipeline bundle — runner, detection, motion, audio + stream broker. Multi-entry npm package shipping pipeline addons under a single bundle.",
5
5
  "keywords": [
6
6
  "camstack",