@camstack/addon-pipeline 1.2.334 → 1.2.336

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 (36) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/{custom-model-catalog-DoOVE7kz.mjs → custom-model-catalog-DSN-2fxO.mjs} +298 -18
  4. package/dist/{custom-model-catalog-CVeosmYm.js → custom-model-catalog-jyP-7H7P.js} +298 -18
  5. package/dist/detection-pipeline/index.js +121 -21
  6. package/dist/detection-pipeline/index.mjs +121 -21
  7. package/dist/{dist-C7v30DMP.js → dist-C5DlS_lW.js} +145 -0
  8. package/dist/{dist-Dn3knu_K.mjs → dist-CPhDwlSN.mjs} +134 -1
  9. package/dist/motion-wasm/index.js +1 -1
  10. package/dist/motion-wasm/index.mjs +1 -1
  11. package/dist/{node-DWdekhW3.js → node-BUafKArW.js} +1 -1
  12. package/dist/{node-_BruMF4L.mjs → node-DYfEOwjW.mjs} +1 -1
  13. package/dist/pipeline-runner/index.js +23 -5
  14. package/dist/pipeline-runner/index.mjs +23 -5
  15. package/dist/{process-memory-CaDpfUdM.js → process-memory-DWOQCbg5.js} +1 -1
  16. package/dist/{process-memory-Dp-4bFOp.mjs → process-memory-WPRYnN8c.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-BqPTLFZG.js → segment-demux-js-DWIgUPW1.js} +1 -1
  20. package/dist/{segment-demux-js-B_-zBECg.mjs → segment-demux-js-Kz4EnmOr.mjs} +1 -1
  21. package/dist/stream-broker/_stub.js +1 -1
  22. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BP8FFU2i.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-RPk9F8CY.mjs} +2 -2
  23. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-1Y-WK-Zy.mjs +26 -0
  24. package/dist/stream-broker/demux-worker-child.js +1 -1
  25. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  26. package/dist/stream-broker/{hostInit-BEh-hm1x.mjs → hostInit-DXXdQdLd.mjs} +2 -2
  27. package/dist/stream-broker/index.js +3 -3
  28. package/dist/stream-broker/index.mjs +3 -3
  29. package/dist/stream-broker/remoteEntry.js +1 -1
  30. package/package.json +1 -1
  31. package/python/coreml_load_probe.py +223 -0
  32. package/python/inference_pool.py +81 -5
  33. package/python/test_coreml_load_probe.py +295 -0
  34. package/python/test_inference_pool_coreml_cache.py +37 -1
  35. package/python/test_inference_pool_ov_precision.py +98 -0
  36. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CpjKK9II.mjs +0 -26
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C7v30DMP.js");
1
+ const require_dist = require("./dist-C5DlS_lW.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
@@ -290,7 +290,7 @@ var ovFormat = (url, sizeMB) => {
290
290
  var ovPrecisionVariant = (baseId, ovDir, baseName, precision, sizeMB, legacy = false) => ({
291
291
  id: `${baseId}-${precision}`,
292
292
  name: `${baseName} (${precision.toUpperCase()})`,
293
- description: `${baseName} — OpenVINO ${precision.toUpperCase()} variant for Intel iGPU/NPU; scale by hardware`,
293
+ description: precision === "int8" ? `${baseName} — OpenVINO INT8 variant for Intel iGPU/CPU; scale by hardware. On the Intel NPU it loses recall — use the base model there` : `${baseName} — OpenVINO ${precision.toUpperCase()} variant for Intel iGPU/NPU; scale by hardware`,
294
294
  inputSize: {
295
295
  width: 640,
296
296
  height: 640
@@ -326,9 +326,11 @@ var YOLOV9_TIER_NAME = {
326
326
  };
327
327
  /**
328
328
  * The Ultralytics YOLOv9 family (COCO-pretrained Ultralytics weights,
329
- * re-exported by CamStack — not trained by us) — the NPU-detection line. Unlike
330
- * yolo26 (whose arch the Intel NPU rejects → 0 frames), yolov9 COMPILES AND RUNS
331
- * on the Intel NPU ("AI Boost"). Empirically: the yolov9t-320-int8 export = ~298 fps on the
329
+ * re-exported by CamStack — not trained by us) — the default NPU-detection line.
330
+ * It runs on the Intel NPU ("AI Boost"), and its INT8 builds are as accurate
331
+ * there as on the CPU. YOLO26 runs on the NPU too since OpenVINO 2025.4
332
+ * (measured 2026-10-07): its base IRs match the CPU, its INT8 IRs lose recall
333
+ * there (see `yolo26Reduced`). Empirically: the yolov9t-320-int8 export = ~298 fps on the
332
334
  * NPU vs yolo26n = 103 on the iGPU (~2.9×). t/s/m/c × {320,640}; each size ships
333
335
  * a base entry (onnx + coreml + openvino **fp16**) + an OpenVINO **int8** entry
334
336
  * (the NPU/iGPU-optimal config). CoreML (fp16) runs on the Mac ANE — the
@@ -344,7 +346,7 @@ var yolov9Reduced = (tier, res, sizes) => {
344
346
  resolution: res
345
347
  },
346
348
  name: `YOLOv9 ${name} @${res}`,
347
- description: `YOLOv9 ${name} @${res}×${res} (Ultralytics) — OpenVINO fp16, runs on Intel NPU + iGPU (NPU-compatible; yolo26 is not).`,
349
+ description: `YOLOv9 ${name} @${res}×${res} (Ultralytics) — OpenVINO fp16, runs on Intel NPU + iGPU.`,
348
350
  inputSize: {
349
351
  width: res,
350
352
  height: res
@@ -394,6 +396,11 @@ var yolov9Reduced = (tier, res, sizes) => {
394
396
  * grouped under `{family, tier, resolution}`, plus an OpenVINO INT8 entry (best
395
397
  * on Intel/N100) grouped with `precision:'int8'`. The grouped selector surfaces
396
398
  * `resolution` as a variant axis alongside precision.
399
+ *
400
+ * Intel NPU (OpenVINO 2025.4, measured 2026-10-07): every YOLO26 IR compiles
401
+ * and runs. The base IRs are as accurate as the CPU; the INT8 IRs lose recall
402
+ * there (`yolo26s-int8` 0.58 on the NPU vs 0.70 on CPU/iGPU, `yolo26m-int8`
403
+ * 0.78 vs 0.83), so on an NPU the base IR is the one to run.
397
404
  */
398
405
  var yolo26Reduced = (tier, res, sizes) => {
399
406
  const name = YOLO26_TIER_NAME[tier] ?? tier.toUpperCase();
@@ -419,7 +426,7 @@ var yolo26Reduced = (tier, res, sizes) => {
419
426
  sizeMB: sizes.onnx
420
427
  },
421
428
  coreml: {
422
- url: hf(`objectDetection/yolo26/coreml/camstack-yolo26${tier}-${res}.mlpackage`),
429
+ url: hf(`objectDetection/yolo26/coreml/camstack-yolo26${tier}-${res}-static.mlpackage`),
423
430
  sizeMB: sizes.coreml,
424
431
  isDirectory: true,
425
432
  files: [...MLPACKAGE_FILES],
@@ -436,7 +443,7 @@ var yolo26Reduced = (tier, res, sizes) => {
436
443
  resolution: res
437
444
  },
438
445
  name: `YOLO26 ${name} @${res} (INT8)`,
439
- description: `YOLO26 ${name} @${res} — OpenVINO INT8 for Intel iGPU/CPU; the N100's fastest config`,
446
+ description: `YOLO26 ${name} @${res} — OpenVINO INT8 for Intel iGPU/CPU; the N100's fastest config. On the Intel NPU it loses recall — use the base model there`,
440
447
  inputSize: {
441
448
  width: res,
442
449
  height: res
@@ -451,7 +458,7 @@ var yolo26Reduced = (tier, res, sizes) => {
451
458
  var YOLO26_SEG_FAMILY = "yolo26-seg";
452
459
  /** What choosing a seg build as the root means, in the catalog's own words. */
453
460
  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).";
454
- var OBJECT_DETECTION_MODELS = [
461
+ var OBJECT_DETECTION_MODEL_ENTRIES = [
455
462
  {
456
463
  id: "yolo26n",
457
464
  license: ULTRALYTICS_AGPL,
@@ -824,6 +831,254 @@ var OBJECT_DETECTION_MODELS = [
824
831
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "fp16", 112, true),
825
832
  ovPrecisionVariant("yolo26x", "objectDetection/yolo26/openvino", "YOLO26 XLarge", "int8", 56, true)
826
833
  ];
834
+ /**
835
+ * The per-class confidence-floor DEFAULTS of each object-detection model
836
+ * (D738), keyed by model id. Applied onto the catalog entries below as
837
+ * `defaultClassFloors`; this is the ONLY place a model's floor is written. A
838
+ * model absent here runs at the step slider's global default
839
+ * (`ObjectDetectionStep.getConfigSchema`: person 0.65, vehicle 0.50, animal
840
+ * 0.50).
841
+ *
842
+ * Measured 2026-10-07 (`docs/benchmarks/model-floors.json`, which also holds
843
+ * precision/recall per class): the floor is the lowest score at which the model
844
+ * makes no more false positives than the production root (`yolov9m-320-int8` at
845
+ * 0.65 / 0.50 / 0.50) on the same 409 hub frames, against an ensemble
846
+ * pseudo-ground-truth, rounded to 0.05, minimum 0.25. Floors carry about
847
+ * +/-0.05-0.10 of noise. Where a floor hinges on a single high-score false
848
+ * positive, the next-lower value the measurement gives is used instead (marked
849
+ * below). A re-measurement replaces the JSON and these rows together; a spec
850
+ * holds them equal.
851
+ *
852
+ * `package` is not calibrated (7 objects in the set) and stays at its global
853
+ * default. Every catalog model NOT listed here (the 256 builds, yolo26 l/x,
854
+ * the seg builds, the fp16 legacy IRs) is untuned and runs at the global
855
+ * defaults.
856
+ */
857
+ var OBJECT_DETECTION_CLASS_FLOORS = {
858
+ "ssd-mobilenet-v2-coco-edgetpu": {
859
+ person: .6,
860
+ vehicle: .35,
861
+ animal: .4
862
+ },
863
+ yolo26m: {
864
+ person: .4,
865
+ vehicle: .25,
866
+ animal: .3
867
+ },
868
+ "yolo26m-320": {
869
+ person: .7,
870
+ vehicle: .3,
871
+ animal: .4
872
+ },
873
+ "yolo26m-320-int8": {
874
+ person: .6,
875
+ vehicle: .4,
876
+ animal: .3
877
+ },
878
+ "yolo26m-int8": {
879
+ person: .4,
880
+ vehicle: .35,
881
+ animal: .45
882
+ },
883
+ yolo26n: {
884
+ person: .65,
885
+ vehicle: .4,
886
+ animal: .5
887
+ },
888
+ "yolo26n-320": {
889
+ person: .6,
890
+ vehicle: .6,
891
+ animal: .4
892
+ },
893
+ "yolo26n-320-int8": {
894
+ person: .45,
895
+ vehicle: .55,
896
+ animal: .35
897
+ },
898
+ "yolo26n-int8": {
899
+ person: .55,
900
+ vehicle: .3,
901
+ animal: .4
902
+ },
903
+ yolo26s: {
904
+ person: .4,
905
+ vehicle: .45,
906
+ animal: .4
907
+ },
908
+ "yolo26s-320": {
909
+ person: .6,
910
+ vehicle: .45,
911
+ animal: .45
912
+ },
913
+ "yolo26s-320-int8": {
914
+ person: .5,
915
+ vehicle: .55,
916
+ animal: .45
917
+ },
918
+ "yolo26s-int8": {
919
+ person: .4,
920
+ vehicle: .3,
921
+ animal: .4
922
+ },
923
+ "yolov9c-320": {
924
+ person: .7,
925
+ vehicle: .45,
926
+ animal: .45
927
+ },
928
+ "yolov9c-320-int8": {
929
+ person: .7,
930
+ vehicle: .5,
931
+ animal: .25
932
+ },
933
+ "yolov9c-640": {
934
+ person: .55,
935
+ vehicle: .45,
936
+ animal: .3
937
+ },
938
+ "yolov9c-640-int8": {
939
+ person: .45,
940
+ vehicle: .4,
941
+ animal: .3
942
+ },
943
+ "yolov9m-320": {
944
+ person: .7,
945
+ vehicle: .5,
946
+ animal: .55
947
+ },
948
+ "yolov9m-320-int8": {
949
+ person: .65,
950
+ vehicle: .4,
951
+ animal: .45
952
+ },
953
+ "yolov9m-640": {
954
+ person: .6,
955
+ vehicle: .4,
956
+ animal: .55
957
+ },
958
+ "yolov9m-640-int8": {
959
+ person: .55,
960
+ vehicle: .4,
961
+ animal: .7
962
+ },
963
+ "yolov9s-320": {
964
+ person: .7,
965
+ vehicle: .55,
966
+ animal: .4
967
+ },
968
+ "yolov9s-320-int8": {
969
+ person: .7,
970
+ vehicle: .45,
971
+ animal: .4
972
+ },
973
+ "yolov9s-640": {
974
+ person: .7,
975
+ vehicle: .4,
976
+ animal: .6
977
+ },
978
+ "yolov9s-640-int8": {
979
+ person: .5,
980
+ vehicle: .3,
981
+ animal: .55
982
+ },
983
+ "yolov9t-320": {
984
+ person: .55,
985
+ vehicle: .45,
986
+ animal: .3
987
+ },
988
+ "yolov9t-320-int8": {
989
+ person: .55,
990
+ vehicle: .4,
991
+ animal: .3
992
+ },
993
+ "yolov9t-640": {
994
+ person: .65,
995
+ vehicle: .5,
996
+ animal: .5
997
+ },
998
+ "yolov9t-640-int8": {
999
+ person: .6,
1000
+ vehicle: .55,
1001
+ animal: .55
1002
+ }
1003
+ };
1004
+ /**
1005
+ * The floor on the DETECTION score below which a root detector's own fine
1006
+ * label (a species, a vehicle type — the D736 root supply) is not taken (D741).
1007
+ * Keyed by root model, then by the supplied step. Below it the detection keeps
1008
+ * its macro class with no fine label; it is never dropped. A floor of 1 means
1009
+ * "never take this label from this root". A root or step absent here has no
1010
+ * extra floor — the macro floor alone gates the label, as before D741.
1011
+ *
1012
+ * Measured 2026-10-07 (`docs/benchmarks/classifier-floors.json`): the
1013
+ * lowest detection score from which the root's species was right ~90% of the
1014
+ * time, against a two-model zero-shot reference on 219 animal crops dominated
1015
+ * by one dog. Unlisted roots behave alike — ~0.89-0.90 at the macro floor for
1016
+ * 640 roots, ~0.74 for 320 roots. Vehicle types needed no extra floor on any
1017
+ * root (0.99-1.00 at the macro floor). The Coral SSD named the species wrongly
1018
+ * three times in four.
1019
+ */
1020
+ var ROOT_SUPPLIED_LABEL_FLOORS = {
1021
+ "yolov9m-320-int8": { "animal-classifier": .75 },
1022
+ "yolov9m-640-int8": { "animal-classifier": .7 },
1023
+ "yolov9c-640-int8": { "animal-classifier": .75 },
1024
+ yolo26s: { "animal-classifier": .45 },
1025
+ yolo26m: { "animal-classifier": .7 },
1026
+ "yolo26s-int8": { "animal-classifier": .55 },
1027
+ "ssd-mobilenet-v2-coco-edgetpu": { "animal-classifier": 1 }
1028
+ };
1029
+ /** Stamp each entry's row of `floors` on it as `suppliedLabelFloors`. Fresh objects only. */
1030
+ function withSuppliedLabelFloors(entries, floors) {
1031
+ return entries.map((entry) => {
1032
+ const row = floors[entry.id];
1033
+ return row === void 0 ? entry : {
1034
+ ...entry,
1035
+ suppliedLabelFloors: { ...row }
1036
+ };
1037
+ });
1038
+ }
1039
+ /** Stamp each entry's row of `floors` on it as `defaultClassFloors`. Fresh objects only. */
1040
+ function withDefaultClassFloors(entries, floors) {
1041
+ return entries.map((entry) => {
1042
+ const row = floors[entry.id];
1043
+ return row === void 0 ? entry : {
1044
+ ...entry,
1045
+ defaultClassFloors: { ...row }
1046
+ };
1047
+ });
1048
+ }
1049
+ /**
1050
+ * Object-detection IRs that need f32 inference on an Intel GPU
1051
+ * (`gpuInferencePrecision`). At the GPU's default f16 the YOLO26 FP32 IRs of
1052
+ * the larger tiers return no valid detection — measured 2026-10-07 on the Core
1053
+ * Ultra iGPU and the N100: `yolo26s` (640) 0 true / 146 false positives,
1054
+ * `yolo26m` and `yolo26m-320` NaN scores; at f32 they match the CPU, at ~60%
1055
+ * more GPU latency. `yolo26n`, `yolo26n-320` and `yolo26s-320` were measured
1056
+ * correct at f16 and are NOT listed. The rest of the list is the same pattern
1057
+ * not yet measured (tier m / l / x at any input, tier s at 640, the seg builds
1058
+ * of those tiers): f32 costs latency, f16 risks a detector that silently finds
1059
+ * nothing. INT8 IRs and every YOLOv9 IR are correct at the device default.
1060
+ */
1061
+ var OPENVINO_GPU_F32_MODEL_IDS = new Set([
1062
+ "yolo26s",
1063
+ "yolo26m",
1064
+ "yolo26m-320",
1065
+ "yolo26m-256",
1066
+ "yolo26l",
1067
+ "yolo26l-320",
1068
+ "yolo26l-256",
1069
+ "yolo26x",
1070
+ "yolo26s-seg",
1071
+ "yolo26m-seg"
1072
+ ]);
1073
+ /** Stamp `gpuInferencePrecision: 'f32'` on the listed entries. Fresh objects only. */
1074
+ function withGpuF32(entries, ids) {
1075
+ return entries.map((entry) => ids.has(entry.id) ? {
1076
+ ...entry,
1077
+ gpuInferencePrecision: "f32"
1078
+ } : entry);
1079
+ }
1080
+ [...OPENVINO_GPU_F32_MODEL_IDS];
1081
+ var OBJECT_DETECTION_MODELS = withSuppliedLabelFloors(withGpuF32(withDefaultClassFloors(OBJECT_DETECTION_MODEL_ENTRIES, OBJECT_DETECTION_CLASS_FLOORS), OPENVINO_GPU_F32_MODEL_IDS), ROOT_SUPPLIED_LABEL_FLOORS);
827
1082
  var FACE_DETECTION_MODELS = [{
828
1083
  id: "yunet-2023mar",
829
1084
  license: YUNET_MIT,
@@ -839,7 +1094,7 @@ var FACE_DETECTION_MODELS = [{
839
1094
  }],
840
1095
  preprocessMode: "letterbox",
841
1096
  postprocessor: "yunet",
842
- defaultConfidence: .85,
1097
+ defaultConfidence: .7,
843
1098
  formats: {
844
1099
  onnx: {
845
1100
  url: hf("faceDetection/yunet/onnx/camstack-yunet-2023mar.onnx"),
@@ -991,7 +1246,8 @@ var ANIMAL_CLASSIFIER_MODELS = [{
991
1246
  id: "animal-classifier",
992
1247
  license: ANIMAL_CLASSIFIER_APACHE,
993
1248
  name: "Animal Classifier (8)",
994
- description: "EfficientNet-Lite0 animal classifier — bird, cat, cow, deer, dog, horse, sheep, squirrel (Open Images V7, publicly distributable)",
1249
+ description: "EfficientNet-Lite0 animal classifier — bird, cat, cow, deer, dog, horse, sheep, squirrel (Open Images V7, publicly distributable). Unreliable on home cameras: it has no reject class, so it names a species for anything it is given, and calls light curly-coated dogs sheep or cat at high confidence. Prefer a root detector that names animals itself.",
1250
+ defaultConfidence: .8,
995
1251
  inputSize: {
996
1252
  width: 224,
997
1253
  height: 224
@@ -1070,6 +1326,7 @@ var VEHICLE_CLASSIFIER_MODELS = [{
1070
1326
  license: VEHICLE_TYPE_V1_NC,
1071
1327
  name: "Vehicle Type (8)",
1072
1328
  description: "MobileNetV3-Large vehicle type classifier — Ambulance, Bicycle, Bus, Car, Motorcycle, Taxi, Truck, Van (val 89.4%)",
1329
+ defaultConfidence: .6,
1073
1330
  inputSize: {
1074
1331
  width: 224,
1075
1332
  height: 224
@@ -1242,6 +1499,20 @@ var PipelineStepBase = class {
1242
1499
  return [];
1243
1500
  }
1244
1501
  };
1502
+ /**
1503
+ * The GLOBAL per-class confidence floors of the object-detection step — what a
1504
+ * model that declares no `defaultClassFloors` row runs at (D738). Tuned on the
1505
+ * YOLOv9 root; see the person slider for the measurement behind 0.65.
1506
+ */
1507
+ var GLOBAL_CLASS_FLOORS = {
1508
+ person: .65,
1509
+ vehicle: .5,
1510
+ animal: .5
1511
+ };
1512
+ /** The model's own default floor for `macroClass`, else the global one (D738). */
1513
+ function classFloorDefault(model, macroClass, globalFloor) {
1514
+ return model?.defaultClassFloors?.[macroClass] ?? globalFloor;
1515
+ }
1245
1516
  var ObjectDetectionStep = class {
1246
1517
  definition = {
1247
1518
  id: "object-detection",
@@ -1264,7 +1535,7 @@ var ObjectDetectionStep = class {
1264
1535
  labels: require_dist.COCO_80_LABELS.map((l) => l.id),
1265
1536
  classMap: require_dist.COCO_TO_MACRO
1266
1537
  };
1267
- getConfigSchema() {
1538
+ getConfigSchema(model) {
1268
1539
  return [
1269
1540
  {
1270
1541
  type: "multiselect",
@@ -1299,7 +1570,8 @@ var ObjectDetectionStep = class {
1299
1570
  min: 0,
1300
1571
  max: 1,
1301
1572
  step: .05,
1302
- default: .65,
1573
+ default: classFloorDefault(model, "person", GLOBAL_CLASS_FLOORS.person),
1574
+ bindsToModel: true,
1303
1575
  showValue: true
1304
1576
  },
1305
1577
  {
@@ -1321,7 +1593,8 @@ var ObjectDetectionStep = class {
1321
1593
  min: 0,
1322
1594
  max: 1,
1323
1595
  step: .05,
1324
- default: .5,
1596
+ default: classFloorDefault(model, "vehicle", GLOBAL_CLASS_FLOORS.vehicle),
1597
+ bindsToModel: true,
1325
1598
  showValue: true
1326
1599
  },
1327
1600
  {
@@ -1332,7 +1605,8 @@ var ObjectDetectionStep = class {
1332
1605
  min: 0,
1333
1606
  max: 1,
1334
1607
  step: .05,
1335
- default: .5,
1608
+ default: classFloorDefault(model, "animal", GLOBAL_CLASS_FLOORS.animal),
1609
+ bindsToModel: true,
1336
1610
  showValue: true
1337
1611
  },
1338
1612
  {
@@ -1444,6 +1718,7 @@ var AnimalClassifierStep = class {
1444
1718
  label: "Min Confidence",
1445
1719
  description: "Drop classifications whose score is below this threshold.",
1446
1720
  default: resolveModelDefaultConfidence(this.definition, model),
1721
+ bindsToModel: true,
1447
1722
  min: 0,
1448
1723
  max: 1,
1449
1724
  step: .05,
@@ -1485,6 +1760,7 @@ var PackageDetectionStep = class extends PipelineStepBase {
1485
1760
  max: 1,
1486
1761
  step: .05,
1487
1762
  default: resolveModelDefaultConfidence(this.definition, model),
1763
+ bindsToModel: true,
1488
1764
  showValue: true
1489
1765
  }];
1490
1766
  }
@@ -1497,6 +1773,7 @@ var ClassifierWithMinConfidence = class extends PipelineStepBase {
1497
1773
  label: "Min Confidence",
1498
1774
  description: "Drop classifications whose score is below this threshold.",
1499
1775
  default: resolveModelDefaultConfidence(this.definition, model),
1776
+ bindsToModel: true,
1500
1777
  min: 0,
1501
1778
  max: 1,
1502
1779
  step: .05,
@@ -1597,6 +1874,7 @@ var STEP_FACE_EMBEDDING = new FaceEmbeddingStep({
1597
1874
  defaultModelId: "auraface-r100",
1598
1875
  modelScope: "cluster",
1599
1876
  defaultConfidence: 0,
1877
+ defaultMinParentScore: .85,
1600
1878
  cadence: {
1601
1879
  trigger: "improve",
1602
1880
  minIntervalMs: 1e3,
@@ -2992,9 +3270,11 @@ var OBJECT_DETECTION_STEP_ID = "object-detection";
2992
3270
  /**
2993
3271
  * Balanced default object-detection model per accelerator class. `'cpu'` maps to
2994
3272
  * `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.
3273
+ * INTEL NPU + iGPU default to the Ultralytics YOLOv9 re-export (int8 @320), which
3274
+ * runs on both (~298 fps measured on the NPU). YOLO26 also runs on the NPU since
3275
+ * OpenVINO 2025.4 (its base IRs as accurately as the CPU, its INT8 IRs with lost
3276
+ * recall) and is an operator pick there, not the default. Apple ANE uses the
3277
+ * CoreML yolov9 @320 build.
2998
3278
  *
2999
3279
  * Do **not** promote these ids to `yolov9m-640` / `*-640`. The controlled
3000
3280
  * evaluation recovered 0/3 misses at the current 0.50 threshold and failed the