@camstack/addon-pipeline 1.2.333 → 1.2.334

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 (35) hide show
  1. package/THIRD_PARTY_MODELS.md +3 -8
  2. package/dist/audio-analyzer/index.js +2 -2
  3. package/dist/audio-analyzer/index.mjs +2 -2
  4. package/dist/{default-detection-model-Biwf5-ML.js → custom-model-catalog-CVeosmYm.js} +236 -165
  5. package/dist/{default-detection-model-CDffuH2m.mjs → custom-model-catalog-DoOVE7kz.mjs} +225 -166
  6. package/dist/detection-pipeline/index.js +70 -104
  7. package/dist/detection-pipeline/index.mjs +18 -52
  8. package/dist/{dist-DJV7Z6Bb.js → dist-C7v30DMP.js} +69 -22
  9. package/dist/{dist-BsT15i7i.mjs → dist-Dn3knu_K.mjs} +69 -22
  10. package/dist/motion-wasm/index.js +1 -1
  11. package/dist/motion-wasm/index.mjs +1 -1
  12. package/dist/{node-CkmucLYG.js → node-DWdekhW3.js} +1 -1
  13. package/dist/{node-Crsi_8ea.mjs → node-_BruMF4L.mjs} +1 -1
  14. package/dist/pipeline-runner/index.js +228 -42
  15. package/dist/pipeline-runner/index.mjs +206 -20
  16. package/dist/{process-memory-BJb7Ihdp.js → process-memory-CaDpfUdM.js} +1 -1
  17. package/dist/{process-memory-1mAUV8S1.mjs → process-memory-Dp-4bFOp.mjs} +1 -1
  18. package/dist/recorder/index.js +2 -2
  19. package/dist/recorder/index.mjs +2 -2
  20. package/dist/{segment-demux-js-B_tboBcJ.mjs → segment-demux-js-B_-zBECg.mjs} +1 -1
  21. package/dist/{segment-demux-js-mK9IBGLf.js → segment-demux-js-BqPTLFZG.js} +1 -1
  22. package/dist/stream-broker/_stub.js +1 -1
  23. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-a3HMFtd5.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BP8FFU2i.mjs} +2 -2
  24. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CpjKK9II.mjs +26 -0
  25. package/dist/stream-broker/demux-worker-child.js +1 -1
  26. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  27. package/dist/stream-broker/{hostInit-DChPnZ5C.mjs → hostInit-BEh-hm1x.mjs} +2 -2
  28. package/dist/stream-broker/index.js +3 -3
  29. package/dist/stream-broker/index.mjs +3 -3
  30. package/dist/stream-broker/remoteEntry.js +1 -1
  31. package/package.json +1 -1
  32. package/python/postprocessors/test_yolo_seg_root.py +109 -0
  33. package/python/postprocessors/yolo.py +52 -13
  34. package/python/postprocessors/yolo_seg.py +79 -156
  35. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DPbj3ML4.mjs +0 -26
@@ -48,7 +48,7 @@ under [Non-commercial models](#non-commercial-models).
48
48
 
49
49
  Training data under attribution terms:
50
50
 
51
- - **COCO 2017** (training data of `yolo26n` and 50 more): annotations CC-BY-4.0; images under their Flickr owners' terms. https://cocodataset.org/#termsofuse
51
+ - **COCO 2017** (training data of `yolo26n-seg` and 50 more): annotations CC-BY-4.0; images under their Flickr owners' terms. https://cocodataset.org/#termsofuse
52
52
  - **WIDER FACE** (training data of `yunet-2023mar`): research-oriented terms; images CC BY-NC-ND. http://shuoyang1213.me/WIDERFACE/
53
53
  - **Open Images V7** (training data of `animal-classifier`): annotations CC-BY-4.0 (Google LLC); images listed as CC-BY-2.0, no warranty. https://storage.googleapis.com/openimages/web/factsfigures_v7.html
54
54
  - **DrBimmer/vehicle-classification** (training data of `vehicle-type-v1`): CC-BY-NC-4.0 — treated as binding the trained weights (conservative reading). https://huggingface.co/datasets/DrBimmer/vehicle-classification
@@ -62,7 +62,7 @@ Training data under attribution terms:
62
62
  cards link here instead of repeating it.
63
63
  -->
64
64
 
65
- The folders `objectDetection/yolo26`, `objectDetection/yolov9` and `segmentation/yolo26-seg` of the model mirror hold Ultralytics weights,
65
+ The folders `segmentation/yolo26-seg`, `objectDetection/yolo26` and `objectDetection/yolov9` of the model mirror hold Ultralytics weights,
66
66
  modified by CamStack and distributed under AGPL-3.0. Their Corresponding Source
67
67
  is published in the mirror itself, in its **`source/`** folder,
68
68
  **https://huggingface.co/camstack/camstack-models/tree/main/source**, together
@@ -120,6 +120,7 @@ entry kept resolvable for a saved selection but no longer offered.
120
120
 
121
121
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
122
122
  | --- | --- | --- | --- | --- | --- |
123
+ | `yolo26n-seg`, `yolo26s-seg`, `yolo26m-seg` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported to ONNX, OpenVINO IR and CoreML | mirror `segmentation/yolo26-seg` |
123
124
  | `yolo26n` (default), `yolo26s`, `yolo26m`, `yolo26l`, `yolo26x` (hidden), `yolo26n-fp16` (hidden), `yolo26n-int8`, `yolo26s-fp16` (hidden), `yolo26s-int8`, `yolo26m-fp16` (hidden), `yolo26m-int8`, `yolo26l-fp16` (hidden), `yolo26l-int8`, `yolo26n-320`, `yolo26n-320-int8`, `yolo26n-256`, `yolo26n-256-int8`, `yolo26s-320`, `yolo26s-320-int8`, `yolo26s-256`, `yolo26s-256-int8`, `yolo26m-320`, `yolo26m-320-int8`, `yolo26m-256`, `yolo26m-256-int8`, `yolo26l-320`, `yolo26l-320-int8`, `yolo26l-256`, `yolo26l-256-int8`, `yolo26x-fp16` (hidden), `yolo26x-int8` (hidden) | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported to ONNX, OpenVINO IR and CoreML (scripts/build-camstack-models.py); OpenVINO FP16 export; exported to OpenVINO IR, then OpenVINO NNCF INT8 post-training quantisation; re-exported at 320×320 to ONNX, OpenVINO IR and CoreML; re-exported at 320×320 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation; re-exported at 256×256 to ONNX, OpenVINO IR and CoreML; re-exported at 256×256 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation | mirror `objectDetection/yolo26` |
124
125
  | `ssd-mobilenet-v2-coco-edgetpu` (default) | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | none | https://github.com/google-coral/test_data |
125
126
  | `yolov9t-320`, `yolov9t-320-int8`, `yolov9t-640`, `yolov9t-640-int8`, `yolov9s-320`, `yolov9s-320-int8`, `yolov9s-640`, `yolov9s-640-int8`, `yolov9m-320`, `yolov9m-320-int8`, `yolov9m-640`, `yolov9m-640-int8`, `yolov9c-320`, `yolov9c-320-int8`, `yolov9c-640`, `yolov9c-640-int8` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported at 320×320 to ONNX, OpenVINO IR FP16 and CoreML; exported at 320×320 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation; exported at 640×640 to ONNX, OpenVINO IR FP16 and CoreML; exported at 640×640 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation | mirror `objectDetection/yolov9` |
@@ -190,12 +191,6 @@ entry kept resolvable for a saved selection but no longer offered.
190
191
  | --- | --- | --- | --- | --- | --- |
191
192
  | `u2netp` (default) | [xuebinqin/U-2-Net](https://github.com/xuebinqin/U-2-Net) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | DUTS-TR: not checked | converted to ONNX, OpenVINO IR and CoreML | mirror `segmentationRefiner/u2netp` |
192
193
 
193
- ### Instance segmentation (dormant step)
194
-
195
- | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
196
- | --- | --- | --- | --- | --- | --- |
197
- | `yolo26n-seg`, `yolo26s-seg`, `yolo26m-seg` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported to ONNX, OpenVINO IR and CoreML | mirror `segmentation/yolo26-seg` |
198
-
199
194
  ### Audio
200
195
 
201
196
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
@@ -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-DJV7Z6Bb.js");
7
- const require_process_memory = require("../process-memory-BJb7Ihdp.js");
6
+ const require_dist = require("../dist-C7v30DMP.js");
7
+ const require_process_memory = require("../process-memory-CaDpfUdM.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 { Cn as errMsg, D as HF_BASE_URL, J as audioAnalysisCapability, Ln as nodePin, Mn as expandAudioChunkToF32le, N as PoolMemoryWatchdog, Nn as hydrateSchema, On as audioChunkBytesPerSample, Tn as BaseAddon, Y as audioAnalyzerCapability, er as EventCategory, h as DEFAULT_AUDIO_ANALYZER_CONFIG, jt as mapAudioLabelToMacro, r as AUDIO_BACKEND_CHOICES, tn as resolvePoolMemoryPolicy } from "../dist-BsT15i7i.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-1mAUV8S1.mjs";
2
+ import { Cn as errMsg, D as HF_BASE_URL, J as audioAnalysisCapability, Ln as nodePin, Mn as expandAudioChunkToF32le, N as PoolMemoryWatchdog, Nn as hydrateSchema, On as audioChunkBytesPerSample, Tn as BaseAddon, Y as audioAnalyzerCapability, er as EventCategory, h as DEFAULT_AUDIO_ANALYZER_CONFIG, jt as mapAudioLabelToMacro, r as AUDIO_BACKEND_CHOICES, tn as resolvePoolMemoryPolicy } from "../dist-Dn3knu_K.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Dp-4bFOp.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
- const require_dist = require("./dist-DJV7Z6Bb.js");
1
+ const require_dist = require("./dist-C7v30DMP.js");
2
2
  const require_worker_protocol = require("./worker-protocol-C-G8qmye.js");
3
3
  let node_crypto = require("node:crypto");
4
4
  //#region src/detection-pipeline/registry/effective-confidence.ts
@@ -447,6 +447,10 @@ var yolo26Reduced = (tier, res, sizes) => {
447
447
  formats: { openvino: ovFormat(hf(`objectDetection/yolo26/openvino/camstack-yolo26${tier}-${res}-int8.xml`), sizes.ovInt8) }
448
448
  }];
449
449
  };
450
+ /** Variant family of the YOLO26 builds with an instance-segmentation head. */
451
+ var YOLO26_SEG_FAMILY = "yolo26-seg";
452
+ /** What choosing a seg build as the root means, in the catalog's own words. */
453
+ var YOLO26_SEG_ROOT_NOTE = "As the root model it detects like YOLO26 and also supplies the Segmentation step its masks (detection + masks, slightly heavier).";
450
454
  var OBJECT_DETECTION_MODELS = [
451
455
  {
452
456
  id: "yolo26n",
@@ -617,6 +621,102 @@ var OBJECT_DETECTION_MODELS = [
617
621
  runtimes: ["python"]
618
622
  } }
619
623
  },
624
+ {
625
+ id: "yolo26n-seg",
626
+ license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
627
+ group: {
628
+ family: YOLO26_SEG_FAMILY,
629
+ tier: "n",
630
+ resolution: 640
631
+ },
632
+ name: "YOLO26-seg Nano",
633
+ description: `YOLO26 Nano with its instance-segmentation head — ultra-lightweight. ${YOLO26_SEG_ROOT_NOTE}`,
634
+ inputSize: {
635
+ width: 640,
636
+ height: 640
637
+ },
638
+ labels: [],
639
+ preprocessMode: "letterbox",
640
+ postprocessor: "yolo-seg",
641
+ formats: {
642
+ onnx: {
643
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
644
+ sizeMB: 11
645
+ },
646
+ coreml: {
647
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
648
+ sizeMB: 6,
649
+ isDirectory: true,
650
+ files: [...MLPACKAGE_FILES],
651
+ runtimes: ["python"]
652
+ },
653
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
654
+ }
655
+ },
656
+ {
657
+ id: "yolo26s-seg",
658
+ license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
659
+ group: {
660
+ family: YOLO26_SEG_FAMILY,
661
+ tier: "s",
662
+ resolution: 640
663
+ },
664
+ name: "YOLO26-seg Small",
665
+ description: `YOLO26 Small with its instance-segmentation head — balanced. ${YOLO26_SEG_ROOT_NOTE}`,
666
+ inputSize: {
667
+ width: 640,
668
+ height: 640
669
+ },
670
+ labels: [],
671
+ preprocessMode: "letterbox",
672
+ postprocessor: "yolo-seg",
673
+ formats: {
674
+ onnx: {
675
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
676
+ sizeMB: 40
677
+ },
678
+ coreml: {
679
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
680
+ sizeMB: 20,
681
+ isDirectory: true,
682
+ files: [...MLPACKAGE_FILES],
683
+ runtimes: ["python"]
684
+ },
685
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
686
+ }
687
+ },
688
+ {
689
+ id: "yolo26m-seg",
690
+ license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
691
+ group: {
692
+ family: YOLO26_SEG_FAMILY,
693
+ tier: "m",
694
+ resolution: 640
695
+ },
696
+ name: "YOLO26-seg Medium",
697
+ description: `YOLO26 Medium with its instance-segmentation head — high accuracy. ${YOLO26_SEG_ROOT_NOTE}`,
698
+ inputSize: {
699
+ width: 640,
700
+ height: 640
701
+ },
702
+ labels: [],
703
+ preprocessMode: "letterbox",
704
+ postprocessor: "yolo-seg",
705
+ formats: {
706
+ onnx: {
707
+ url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
708
+ sizeMB: 90
709
+ },
710
+ coreml: {
711
+ url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
712
+ sizeMB: 45,
713
+ isDirectory: true,
714
+ files: [...MLPACKAGE_FILES],
715
+ runtimes: ["python"]
716
+ },
717
+ openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
718
+ }
719
+ },
620
720
  ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "fp16", 5, true),
621
721
  ovPrecisionVariant("yolo26n", "objectDetection/yolo26/openvino", "YOLO26 Nano", "int8", 3),
622
722
  ovPrecisionVariant("yolo26s", "objectDetection/yolo26/openvino", "YOLO26 Small", "fp16", 19, true),
@@ -1030,86 +1130,13 @@ var SEGMENTATION_REFINER_MODELS = [{
1030
1130
  openvino: ovFormat(hf("segmentationRefiner/u2netp/openvino/camstack-u2netp.xml"), 2.5)
1031
1131
  }
1032
1132
  }];
1033
- var INSTANCE_SEGMENTATION_MODELS = [
1034
- {
1035
- id: "yolo26n-seg",
1036
- license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
1037
- name: "YOLO26 Nano Seg",
1038
- description: "YOLO26 Nano Segmentation — ultra-lightweight instance segmentation with masks",
1039
- inputSize: {
1040
- width: 640,
1041
- height: 640
1042
- },
1043
- labels: [],
1044
- preprocessMode: "letterbox",
1045
- formats: {
1046
- onnx: {
1047
- url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26n-seg.onnx"),
1048
- sizeMB: 11
1049
- },
1050
- coreml: {
1051
- url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26n-seg.mlpackage"),
1052
- sizeMB: 6,
1053
- isDirectory: true,
1054
- files: [...MLPACKAGE_FILES],
1055
- runtimes: ["python"]
1056
- },
1057
- openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26n-seg.xml"), 11)
1058
- }
1059
- },
1060
- {
1061
- id: "yolo26s-seg",
1062
- license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
1063
- name: "YOLO26 Small Seg",
1064
- description: "YOLO26 Small Segmentation — balanced instance segmentation",
1065
- inputSize: {
1066
- width: 640,
1067
- height: 640
1068
- },
1069
- labels: [],
1070
- preprocessMode: "letterbox",
1071
- formats: {
1072
- onnx: {
1073
- url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26s-seg.onnx"),
1074
- sizeMB: 40
1075
- },
1076
- coreml: {
1077
- url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26s-seg.mlpackage"),
1078
- sizeMB: 20,
1079
- isDirectory: true,
1080
- files: [...MLPACKAGE_FILES],
1081
- runtimes: ["python"]
1082
- },
1083
- openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26s-seg.xml"), 40)
1084
- }
1085
- },
1086
- {
1087
- id: "yolo26m-seg",
1088
- license: licensed(ULTRALYTICS_AGPL, { modifications: "exported to ONNX, OpenVINO IR and CoreML" }),
1089
- name: "YOLO26 Medium Seg",
1090
- description: "YOLO26 Medium Segmentation — high-accuracy instance segmentation",
1091
- inputSize: {
1092
- width: 640,
1093
- height: 640
1094
- },
1095
- labels: [],
1096
- preprocessMode: "letterbox",
1097
- formats: {
1098
- onnx: {
1099
- url: hf("segmentation/yolo26-seg/onnx/camstack-yolo26m-seg.onnx"),
1100
- sizeMB: 90
1101
- },
1102
- coreml: {
1103
- url: hf("segmentation/yolo26-seg/coreml/camstack-yolo26m-seg.mlpackage"),
1104
- sizeMB: 45,
1105
- isDirectory: true,
1106
- files: [...MLPACKAGE_FILES],
1107
- runtimes: ["python"]
1108
- },
1109
- openvino: ovFormat(hf("segmentation/yolo26-seg/openvino/camstack-yolo26m-seg.xml"), 90)
1110
- }
1111
- }
1112
- ];
1133
+ /**
1134
+ * The dormant `instance-segmentation` step's catalog: the YOLO26-seg entries of
1135
+ * {@link OBJECT_DETECTION_MODELS}, by reference. One entry per model (D703) —
1136
+ * the artifact lives once, in the root's catalog, where it can be selected as
1137
+ * the camera root and supply the `segmentation` step's masks (D737).
1138
+ */
1139
+ var INSTANCE_SEGMENTATION_MODELS = OBJECT_DETECTION_MODELS.filter((m) => m.group?.family === YOLO26_SEG_FAMILY);
1113
1140
  var CLIP_EMBEDDING_MODELS = [{
1114
1141
  id: "siglip2-b16-224",
1115
1142
  license: SIGLIP2_APACHE,
@@ -1391,7 +1418,7 @@ var AnimalClassifierStep = class {
1391
1418
  labelTier: 1,
1392
1419
  models: [...ANIMAL_CLASSIFIER_MODELS],
1393
1420
  defaultModelId: "animal-classifier",
1394
- enabledByDefault: false,
1421
+ enabledByDefault: true,
1395
1422
  defaultConfidence: .5,
1396
1423
  labels: [...ANIMAL_10_LABELS],
1397
1424
  cadence: {
@@ -1705,7 +1732,7 @@ var STEP_VEHICLE_CLASSIFIER = new VehicleClassifierStep({
1705
1732
  labelTier: 1,
1706
1733
  models: [...VEHICLE_CLASSIFIER_MODELS],
1707
1734
  defaultModelId: "vehicle-type-v1",
1708
- enabledByDefault: false,
1735
+ enabledByDefault: true,
1709
1736
  defaultConfidence: .5,
1710
1737
  cadence: {
1711
1738
  trigger: "once",
@@ -2959,6 +2986,120 @@ function rootObjectGate(steps) {
2959
2986
  return (steps?.find((s) => s.enabled !== false))?.settings;
2960
2987
  }
2961
2988
  //#endregion
2989
+ //#region src/detection-pipeline/default-detection-model.ts
2990
+ /** The object-detection step id — the only slot this resolver applies to. */
2991
+ var OBJECT_DETECTION_STEP_ID = "object-detection";
2992
+ /**
2993
+ * Balanced default object-detection model per accelerator class. `'cpu'` maps to
2994
+ * `null` → the caller substitutes the step's own `defaultModelId` (`yolo26n`).
2995
+ * INTEL NPU + iGPU default to the Ultralytics YOLOv9 re-export (int8 @320): yolo26 does NOT compile on
2996
+ * the Intel NPU (arch incompat → 0 frames), while yolov9 runs on it (~298 fps
2997
+ * measured). Apple ANE uses the CoreML yolov9 @320 build.
2998
+ *
2999
+ * Do **not** promote these ids to `yolov9m-640` / `*-640`. The controlled
3000
+ * evaluation recovered 0/3 misses at the current 0.50 threshold and failed the
3001
+ * false-positive and capacity gates — see
3002
+ * `docs/benchmarks/pipeline-frame-model-eval.md`. 640 remains an explicit
3003
+ * operator pick, not a hardware-aware default.
3004
+ */
3005
+ var MODEL_BY_CLASS = {
3006
+ "apple-ane": "yolov9m-320",
3007
+ "intel-npu": "yolov9m-320-int8",
3008
+ "intel-gpu": "yolov9m-320-int8",
3009
+ cpu: null
3010
+ };
3011
+ /**
3012
+ * Classify a node's engine into an {@link AcceleratorClass} from its resolved
3013
+ * `backend` + `device`. Pure, total, never throws.
3014
+ *
3015
+ * OpenVINO's default device is `'auto'` (the python pool resolves NPU > GPU >
3016
+ * CPU at load). Because OpenVINO is only ever OFFERED when an Intel iGPU is
3017
+ * present, the GPU is the guaranteed accelerator while the NPU is an explicit
3018
+ * opt-in — so `'auto'` (and any non-cpu/non-npu device) is treated as
3019
+ * GPU-class conservatively. An operator who explicitly pins `device: 'npu'`
3020
+ * gets the NPU-tuned m-320.
3021
+ *
3022
+ * Also accepts the accelerator carried in the `backend` slot (e.g. `'ane'`,
3023
+ * `'mps'`, `'npu'`, `'intel-gpu'`) so a caller passing a device-style backend
3024
+ * still classifies correctly — real callers pass onnx/openvino/coreml.
3025
+ */
3026
+ function classifyAccelerator(backend, device) {
3027
+ const b = backend.toLowerCase();
3028
+ const d = device?.toLowerCase() ?? null;
3029
+ if (b === "coreml" || b === "ane" || b === "mps") return "apple-ane";
3030
+ if (b === "openvino") {
3031
+ if (d === "npu") return "intel-npu";
3032
+ if (d === "cpu") return "cpu";
3033
+ return "intel-gpu";
3034
+ }
3035
+ if (b === "npu" || b === "intel-npu") return "intel-npu";
3036
+ if (b === "gpu" || b === "intel-gpu" || b === "gpu-openvino") return "intel-gpu";
3037
+ return "cpu";
3038
+ }
3039
+ /**
3040
+ * Resolve the hardware-aware default object-detection model id for a node's
3041
+ * engine `(backend, device, format)`.
3042
+ *
3043
+ * Guarantees:
3044
+ * - never throws (hot default-tree path);
3045
+ * - never returns a model id without a build for `format` (unless the step
3046
+ * has ZERO builds for `format`, which is unloadable regardless of pick and
3047
+ * flagged by `collectZeroBuildIssues`) — an unmapped backend, a `'cpu'`
3048
+ * class, a mapped id missing from the catalog, or a mapped id without a
3049
+ * `format` build all fall back to the step's PER-FORMAT default
3050
+ * (`getDefaultModelForFormatFromDef`), NOT the bare `defaultModelId`.
3051
+ *
3052
+ * `getStepDef` is injectable (defaults to the real catalog lookup) so the
3053
+ * missing-build fallback branch is unit-testable without a live catalog —
3054
+ * mirrors `collectZeroBuildIssues`' injection seam.
3055
+ */
3056
+ function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
3057
+ let def;
3058
+ try {
3059
+ def = getStepDef(OBJECT_DETECTION_STEP_ID);
3060
+ } catch {
3061
+ return "yolo26n";
3062
+ }
3063
+ const candidate = MODEL_BY_CLASS[classifyAccelerator(backend, device)];
3064
+ if (candidate !== null) {
3065
+ const entry = def.models.find((m) => m.id === candidate);
3066
+ if (entry && entry.formats[format] !== void 0) return candidate;
3067
+ }
3068
+ return getDefaultModelForFormatFromDef(def, format);
3069
+ }
3070
+ //#endregion
3071
+ //#region src/detection-pipeline/engine/resolve-device-engine.ts
3072
+ /**
3073
+ * Resolve a Phase-1 device key (`<backend>:<device>`, or bare `cpu`) into the
3074
+ * {@link PipelineEngineChoice} used to build that device's inference pool.
3075
+ * Throws on an unknown backend token so a bad `deviceKey` fails loud rather
3076
+ * than silently building a wrong pool. Format comes from the shared
3077
+ * {@link DEVICE_BACKEND_TO_FORMAT} SSOT (`@camstack/types`) — no local copy.
3078
+ */
3079
+ function resolveDeviceEngine(deviceKey) {
3080
+ const colon = deviceKey.indexOf(":");
3081
+ const backend = colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
3082
+ const device = colon >= 0 ? deviceKey.slice(colon + 1) : deviceKey;
3083
+ const format = require_dist.DEVICE_BACKEND_TO_FORMAT[backend];
3084
+ if (format === void 0) throw new Error(`resolveDeviceEngine: unknown backend "${backend}" in deviceKey "${deviceKey}"`);
3085
+ return {
3086
+ runtime: "python",
3087
+ backend,
3088
+ format,
3089
+ device
3090
+ };
3091
+ }
3092
+ /**
3093
+ * The inverse of {@link resolveDeviceEngine}: the `<backend>:<device>` key that
3094
+ * names the pool an engine belongs to. Every pool-level log line carries this —
3095
+ * without it a default pool logs anonymously and six hours of logs cannot tell
3096
+ * "the NPU is unused" from "the NPU IS the anonymous default pool".
3097
+ * Falls back to the bare backend when the engine carries no device.
3098
+ */
3099
+ function deviceKeyOf(engine) {
3100
+ return engine.device ? `${engine.backend}:${engine.device}` : engine.backend;
3101
+ }
3102
+ //#endregion
2962
3103
  //#region src/pipeline-runner/device-jump.ts
2963
3104
  /**
2964
3105
  * Step-tree device jump (same-node, phase 1) — the PURE resolution core.
@@ -3268,88 +3409,6 @@ var CustomModelCatalog = class {
3268
3409
  stepDefinition = (stepId) => mergedStepDefinition(stepId, this.byStep);
3269
3410
  };
3270
3411
  //#endregion
3271
- //#region src/detection-pipeline/default-detection-model.ts
3272
- /** The object-detection step id — the only slot this resolver applies to. */
3273
- var OBJECT_DETECTION_STEP_ID = "object-detection";
3274
- /**
3275
- * Balanced default object-detection model per accelerator class. `'cpu'` maps to
3276
- * `null` → the caller substitutes the step's own `defaultModelId` (`yolo26n`).
3277
- * INTEL NPU + iGPU default to the Ultralytics YOLOv9 re-export (int8 @320): yolo26 does NOT compile on
3278
- * the Intel NPU (arch incompat → 0 frames), while yolov9 runs on it (~298 fps
3279
- * measured). Apple ANE uses the CoreML yolov9 @320 build.
3280
- *
3281
- * Do **not** promote these ids to `yolov9m-640` / `*-640`. The controlled
3282
- * evaluation recovered 0/3 misses at the current 0.50 threshold and failed the
3283
- * false-positive and capacity gates — see
3284
- * `docs/benchmarks/pipeline-frame-model-eval.md`. 640 remains an explicit
3285
- * operator pick, not a hardware-aware default.
3286
- */
3287
- var MODEL_BY_CLASS = {
3288
- "apple-ane": "yolov9m-320",
3289
- "intel-npu": "yolov9m-320-int8",
3290
- "intel-gpu": "yolov9m-320-int8",
3291
- cpu: null
3292
- };
3293
- /**
3294
- * Classify a node's engine into an {@link AcceleratorClass} from its resolved
3295
- * `backend` + `device`. Pure, total, never throws.
3296
- *
3297
- * OpenVINO's default device is `'auto'` (the python pool resolves NPU > GPU >
3298
- * CPU at load). Because OpenVINO is only ever OFFERED when an Intel iGPU is
3299
- * present, the GPU is the guaranteed accelerator while the NPU is an explicit
3300
- * opt-in — so `'auto'` (and any non-cpu/non-npu device) is treated as
3301
- * GPU-class conservatively. An operator who explicitly pins `device: 'npu'`
3302
- * gets the NPU-tuned m-320.
3303
- *
3304
- * Also accepts the accelerator carried in the `backend` slot (e.g. `'ane'`,
3305
- * `'mps'`, `'npu'`, `'intel-gpu'`) so a caller passing a device-style backend
3306
- * still classifies correctly — real callers pass onnx/openvino/coreml.
3307
- */
3308
- function classifyAccelerator(backend, device) {
3309
- const b = backend.toLowerCase();
3310
- const d = device?.toLowerCase() ?? null;
3311
- if (b === "coreml" || b === "ane" || b === "mps") return "apple-ane";
3312
- if (b === "openvino") {
3313
- if (d === "npu") return "intel-npu";
3314
- if (d === "cpu") return "cpu";
3315
- return "intel-gpu";
3316
- }
3317
- if (b === "npu" || b === "intel-npu") return "intel-npu";
3318
- if (b === "gpu" || b === "intel-gpu" || b === "gpu-openvino") return "intel-gpu";
3319
- return "cpu";
3320
- }
3321
- /**
3322
- * Resolve the hardware-aware default object-detection model id for a node's
3323
- * engine `(backend, device, format)`.
3324
- *
3325
- * Guarantees:
3326
- * - never throws (hot default-tree path);
3327
- * - never returns a model id without a build for `format` (unless the step
3328
- * has ZERO builds for `format`, which is unloadable regardless of pick and
3329
- * flagged by `collectZeroBuildIssues`) — an unmapped backend, a `'cpu'`
3330
- * class, a mapped id missing from the catalog, or a mapped id without a
3331
- * `format` build all fall back to the step's PER-FORMAT default
3332
- * (`getDefaultModelForFormatFromDef`), NOT the bare `defaultModelId`.
3333
- *
3334
- * `getStepDef` is injectable (defaults to the real catalog lookup) so the
3335
- * missing-build fallback branch is unit-testable without a live catalog —
3336
- * mirrors `collectZeroBuildIssues`' injection seam.
3337
- */
3338
- function resolveDefaultDetectionModel(backend, device, format, getStepDef = getStepDefinition) {
3339
- let def;
3340
- try {
3341
- def = getStepDef(OBJECT_DETECTION_STEP_ID);
3342
- } catch {
3343
- return "yolo26n";
3344
- }
3345
- const candidate = MODEL_BY_CLASS[classifyAccelerator(backend, device)];
3346
- if (candidate !== null) {
3347
- const entry = def.models.find((m) => m.id === candidate);
3348
- if (entry && entry.formats[format] !== void 0) return candidate;
3349
- }
3350
- return getDefaultModelForFormatFromDef(def, format);
3351
- }
3352
- //#endregion
3353
3412
  Object.defineProperty(exports, "ALL_PIPELINE_STEPS", {
3354
3413
  enumerable: true,
3355
3414
  get: function() {
@@ -3386,6 +3445,12 @@ Object.defineProperty(exports, "createSessionDecodeCoordinator", {
3386
3445
  return createSessionDecodeCoordinator;
3387
3446
  }
3388
3447
  });
3448
+ Object.defineProperty(exports, "deviceKeyOf", {
3449
+ enumerable: true,
3450
+ get: function() {
3451
+ return deviceKeyOf;
3452
+ }
3453
+ });
3389
3454
  Object.defineProperty(exports, "getDefaultModelForFormat", {
3390
3455
  enumerable: true,
3391
3456
  get: function() {
@@ -3446,6 +3511,12 @@ Object.defineProperty(exports, "resolveDefaultDetectionModel", {
3446
3511
  return resolveDefaultDetectionModel;
3447
3512
  }
3448
3513
  });
3514
+ Object.defineProperty(exports, "resolveDeviceEngine", {
3515
+ enumerable: true,
3516
+ get: function() {
3517
+ return resolveDeviceEngine;
3518
+ }
3519
+ });
3449
3520
  Object.defineProperty(exports, "resolveFrameViewGeometry", {
3450
3521
  enumerable: true,
3451
3522
  get: function() {