@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
@@ -1,4 +1,4 @@
1
- import { Tt as inferModelProvider, X as audioKindId, b as DEVICE_BACKEND_TO_FORMAT, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, k as LABEL_SUPPLY_VOCABULARIES, on as stepModelRunsOnFormat, p as COCO_TO_MACRO, wt as hfModelUrl } from "./dist-BsT15i7i.mjs";
1
+ import { Tt as inferModelProvider, X as audioKindId, b as DEVICE_BACKEND_TO_FORMAT, f as COCO_80_LABELS, i as AUDIO_MACRO_LABELS, k as LABEL_SUPPLY_VOCABULARIES, on as stepModelRunsOnFormat, p as COCO_TO_MACRO, wt as hfModelUrl } from "./dist-Dn3knu_K.mjs";
2
2
  import { t as isWorkerReply } from "./worker-protocol-D_NzPcnh.mjs";
3
3
  import { randomUUID } from "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 = 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,86 +3409,4 @@ 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
- export { getStep as _, buildSubtreeCanRun as a, landmarkPrecisionVerdict as b, macroGateVerdict as c, isSessionDecodeReadGone as d, createSessionDecodeCoordinator as f, getDefaultModelForFormat as g, ALL_STEPS as h, mergeCustomModels as i, rootObjectGate as l, ALL_PIPELINE_STEPS as m, resolveDefaultDetectionModel as n, placeDetailStep as o, resolveFrameViewGeometry as p, CustomModelCatalog as r, stepsForElectedPool as s, OBJECT_DETECTION_STEP_ID as t, localFrameRegistry as u, getStepDefinition as v, resolveModelDefaultConfidence as x, resolveModelForFormat as y };
3412
+ export { resolveModelDefaultConfidence as C, landmarkPrecisionVerdict as S, ALL_STEPS as _, stepsForElectedPool as a, getStepDefinition as b, OBJECT_DETECTION_STEP_ID as c, rootObjectGate as d, localFrameRegistry as f, ALL_PIPELINE_STEPS as g, resolveFrameViewGeometry as h, placeDetailStep as i, resolveDefaultDetectionModel as l, createSessionDecodeCoordinator as m, mergeCustomModels as n, deviceKeyOf as o, isSessionDecodeReadGone as p, buildSubtreeCanRun as r, resolveDeviceEngine as s, CustomModelCatalog as t, macroGateVerdict as u, getDefaultModelForFormat as v, resolveModelForFormat as x, getStep as y };