@camstack/addon-pipeline 1.1.56 → 1.1.58

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 (42) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/detection-pipeline/index.js +71 -74
  4. package/dist/detection-pipeline/index.mjs +70 -73
  5. package/dist/{dist-ClE6_i0p.js → dist-Bn6Uq4vq.js} +4750 -4644
  6. package/dist/{dist-CrjLGrkj.mjs → dist-CnwwDzX3.mjs} +4751 -4645
  7. package/dist/motion-wasm/index.js +9 -41
  8. package/dist/motion-wasm/index.mjs +9 -41
  9. package/dist/pipeline-runner/index.js +238 -656
  10. package/dist/pipeline-runner/index.mjs +227 -647
  11. package/dist/recorder/index.js +2 -2
  12. package/dist/recorder/index.mjs +2 -2
  13. package/dist/remote-restream-BeHi78PZ.mjs +25 -0
  14. package/dist/remote-restream-CO36Sr30.js +36 -0
  15. package/dist/session-decode/decode-worker-child.js +97 -2
  16. package/dist/session-decode/decode-worker-child.mjs +97 -2
  17. package/dist/{step-definitions-C9kUXgC7.js → step-definitions-D7NOrnzz.js} +44 -2
  18. package/dist/{step-definitions-dCghpdRo.mjs → step-definitions-DhEe57Wn.mjs} +44 -2
  19. package/dist/stream-broker/_stub.js +282 -222
  20. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D4xH4Tm-.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B8FQ1e0a.mjs} +3 -3
  21. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D2z_vRMH.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Ba7Eyd47.mjs} +1 -1
  22. package/dist/stream-broker/{hostInit-Di9WUNlQ.mjs → hostInit-D1Vdyu-4.mjs} +3 -3
  23. package/dist/stream-broker/index.js +881 -40
  24. package/dist/stream-broker/index.mjs +878 -37
  25. package/dist/stream-broker/remoteEntry.js +1 -1
  26. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-Ca93F1js.js → MaskShapeCanvas-DI4BY7W2-CG5EE0W4.js} +1 -1
  27. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CDqgb-WA.js → MotionZonesSettings-NcxxQN8r-BFeLUNOl.js} +1 -1
  28. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BlxPhY_w.js → PrivacyMaskSettings-APgPLF7p-pQQunq1F.js} +1 -1
  29. package/embed-dist/assets/index-BxqQ931j.js +81 -0
  30. package/embed-dist/index.html +1 -1
  31. package/package.json +7 -5
  32. package/python/inference_pool.py +172 -28
  33. package/python/postprocessors/__init__.py +2 -0
  34. package/python/postprocessors/ssd.py +128 -0
  35. package/python/requirements-edgetpu.txt +23 -0
  36. package/python/test_inference_pool_layout.py +16 -1
  37. package/python/test_inference_pool_preprocess.py +65 -0
  38. package/dist/remote-source-plane-B28iGi7h.mjs +0 -1001
  39. package/dist/remote-source-plane-BAqEHSgm.js +0 -1030
  40. package/embed-dist/assets/index-B23riUw8.js +0 -81
  41. package/dist/{model-download-service-C-IHWnXx-BPy6aoAx.mjs → model-download-service-C-IHWnXx-3Mmeob3l.mjs} +1 -1
  42. package/dist/{model-download-service-C-IHWnXx-BLXzxpRB.js → model-download-service-C-IHWnXx-D326YNnt.js} +1 -1
@@ -1,14 +1,13 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { D as nodePin, H as createEvent, I as errMsg, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, U as hydrateSchema, V as EventCategory, X as sleep, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, j as runtimeDevices$1, q as parseJsonUnknown, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-CrjLGrkj.mjs";
3
- import { a as getStepDefinition, i as getStep, n as ALL_STEPS, o as resolveModelForFormat, r as getDefaultModelForFormat, t as ALL_PIPELINE_STEPS } from "../step-definitions-dCghpdRo.mjs";
2
+ import { D as nodePin, H as hydrateSchema, I as errMsg, K as parseJsonUnknown, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, V as createEvent, Y as sleep, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, j as runtimeDevices$1, st as EventCategory, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-CnwwDzX3.mjs";
3
+ import { a as getStepDefinition, i as getStep, n as ALL_STEPS, o as resolveModelForFormat, r as getDefaultModelForFormat, t as ALL_PIPELINE_STEPS } from "../step-definitions-DhEe57Wn.mjs";
4
4
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
5
- import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
6
- import { FrameRingReaderCache } from "@camstack/shm-ring";
5
+ import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-3Mmeob3l.mjs";
7
6
  import { spawn } from "node:child_process";
7
+ import sharp from "sharp";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
10
10
  import * as os from "node:os";
11
- import sharp from "sharp";
12
11
  //#region src/detection-pipeline/runtimes.ts
13
12
  var KNOWN_PLATFORMS = [
14
13
  "darwin",
@@ -44,6 +43,9 @@ function npuInfoFrom(hw) {
44
43
  if (!type) return null;
45
44
  return { type };
46
45
  }
46
+ function coralInfoFrom(hw) {
47
+ return hw.coral?.type === "coral-edgetpu" ? { type: "coral-edgetpu" } : null;
48
+ }
47
49
  function envToHardwareInfo(env) {
48
50
  return {
49
51
  platform: toKnownPlatform(env.platform),
@@ -53,7 +55,8 @@ function envToHardwareInfo(env) {
53
55
  totalRAM_MB: 0,
54
56
  availableRAM_MB: 0,
55
57
  gpu: env.hardware ? gpuInfoFrom(env.hardware) : null,
56
- npu: env.hardware ? npuInfoFrom(env.hardware) : null
58
+ npu: env.hardware ? npuInfoFrom(env.hardware) : null,
59
+ coral: env.hardware ? coralInfoFrom(env.hardware) : null
57
60
  };
58
61
  }
59
62
  function probedToHardwareInfo(hw) {
@@ -66,7 +69,8 @@ function probedToHardwareInfo(hw) {
66
69
  totalRAM_MB: 0,
67
70
  availableRAM_MB: 0,
68
71
  gpu: gpuInfoFrom(hw),
69
- npu: npuInfoFrom(hw)
72
+ npu: npuInfoFrom(hw),
73
+ coral: coralInfoFrom(hw)
70
74
  };
71
75
  }
72
76
  var RUNTIME_DETAIL = {
@@ -99,6 +103,15 @@ var RUNTIME_DETAIL = {
99
103
  maxBatchSize: 8,
100
104
  numWorkers: 1
101
105
  }
106
+ },
107
+ edgetpu: {
108
+ label: "Coral Edge TPU",
109
+ pythonRequirements: ["requirements.txt", "requirements-edgetpu.txt"],
110
+ tuning: {
111
+ concurrency: 1,
112
+ batchMode: "none",
113
+ numWorkers: 1
114
+ }
102
115
  }
103
116
  };
104
117
  /**
@@ -126,11 +139,12 @@ function defaultDeviceFor(id) {
126
139
  var RUNTIME_FORMAT = {
127
140
  onnx: "onnx",
128
141
  openvino: "openvino",
129
- coreml: "coreml"
142
+ coreml: "coreml",
143
+ edgetpu: "tflite"
130
144
  };
131
145
  /**
132
146
  * Returns the model format required for a given runtime.
133
- * Returns the locally-typed format string ('onnx' | 'openvino' | 'coreml')
147
+ * Returns the locally-typed format string ('onnx' | 'openvino' | 'coreml' | 'tflite')
134
148
  * matching the engine-provisioner's own ModelFormat type.
135
149
  */
136
150
  function modelFormatFor(id) {
@@ -159,6 +173,7 @@ function shouldInstallOpenvino(env) {
159
173
  var PREFERENCE = [
160
174
  "coreml",
161
175
  "openvino",
176
+ "edgetpu",
162
177
  "onnx"
163
178
  ];
164
179
  /**
@@ -928,6 +943,9 @@ function serializeModelConfig(config) {
928
943
  postprocessor: config.postprocessor,
929
944
  confidence: config.confidence
930
945
  };
946
+ if (config.inputWidth !== void 0) result["inputWidth"] = config.inputWidth;
947
+ if (config.inputHeight !== void 0) result["inputHeight"] = config.inputHeight;
948
+ if (config.inputChannels !== void 0) result["inputChannels"] = config.inputChannels;
931
949
  if (config.labels) result["labels"] = config.labels;
932
950
  if (config.charset) result["charset"] = config.charset;
933
951
  if (config.numClasses) result["numClasses"] = config.numClasses;
@@ -1223,12 +1241,14 @@ var BACKEND_TO_POOL_RUNTIME = {
1223
1241
  openvino: "openvino",
1224
1242
  onnx: "onnxruntime",
1225
1243
  cpu: "onnxruntime",
1226
- cuda: "onnxruntime"
1244
+ cuda: "onnxruntime",
1245
+ edgetpu: "edgetpu"
1227
1246
  };
1228
1247
  var RUNTIME_TO_FORMAT = {
1229
1248
  coreml: "coreml",
1230
1249
  openvino: "openvino",
1231
- onnxruntime: "onnx"
1250
+ onnxruntime: "onnx",
1251
+ edgetpu: "tflite"
1232
1252
  };
1233
1253
  var EngineFactory = class {
1234
1254
  pool = null;
@@ -1347,13 +1367,15 @@ var EngineFactory = class {
1347
1367
  const concurrency = this.opts.concurrency ?? {
1348
1368
  coreml: 1,
1349
1369
  openvino: 1,
1350
- onnxruntime: 4
1370
+ onnxruntime: 4,
1371
+ edgetpu: 1
1351
1372
  }[poolRuntime];
1352
1373
  const isAutoDefault = this.opts.concurrency === void 0;
1353
1374
  const defaultBatchMode = {
1354
1375
  coreml: "window",
1355
1376
  openvino: "none",
1356
- onnxruntime: "list"
1377
+ onnxruntime: "list",
1378
+ edgetpu: "none"
1357
1379
  };
1358
1380
  const tuning = this.opts.tuning ?? {};
1359
1381
  const resolvedTuning = {
@@ -1391,7 +1413,10 @@ var EngineFactory = class {
1391
1413
  const urlParts = formatEntry.url.split("/");
1392
1414
  const filename = urlParts[urlParts.length - 1] ?? `${modelId}.${format}`;
1393
1415
  const modelPath = `${this.opts.modelsDir}/${filename}`;
1394
- const inputSize = Math.max(modelEntry.inputSize.width, modelEntry.inputSize.height);
1416
+ const inputWidth = modelEntry.inputSize.width;
1417
+ const inputHeight = modelEntry.inputSize.height;
1418
+ const inputSize = Math.max(inputWidth, inputHeight);
1419
+ const inputChannels = modelEntry.inputChannels ?? 3;
1395
1420
  let labels = def.labels;
1396
1421
  if (!labels && modelEntry.extraFiles) {
1397
1422
  const labelsFile = modelEntry.extraFiles.find((f) => f.filename.endsWith("-labels.json"));
@@ -1403,8 +1428,11 @@ var EngineFactory = class {
1403
1428
  return {
1404
1429
  path: modelPath,
1405
1430
  inputSize,
1431
+ inputWidth,
1432
+ inputHeight,
1433
+ inputChannels,
1406
1434
  preprocessMode: modelEntry.preprocessMode ?? "letterbox",
1407
- postprocessor: def.postprocessor,
1435
+ postprocessor: modelEntry.postprocessor ?? def.postprocessor,
1408
1436
  confidence: def.defaultConfidence,
1409
1437
  labels,
1410
1438
  charset: def.charset,
@@ -1603,6 +1631,11 @@ function postprocessYolo(output, stepDef) {
1603
1631
  detections: simpleNms(dets, .45)
1604
1632
  };
1605
1633
  }
1634
+ function postprocessSsd(output, _stepDef) {
1635
+ const structured = tryStructured(output);
1636
+ if (structured) return structured;
1637
+ throw new Error("SSD postprocessing runs in the Python inference pool (ssd.py); no TypeScript raw-tensor path.");
1638
+ }
1606
1639
  function postprocessScrfd(output, stepDef) {
1607
1640
  const structured = tryStructured(output);
1608
1641
  if (structured) return structured;
@@ -2025,6 +2058,7 @@ function postprocessYamnet(output, _stepDef) {
2025
2058
  }
2026
2059
  var DISPATCH = {
2027
2060
  yolo: postprocessYolo,
2061
+ ssd: postprocessSsd,
2028
2062
  "yolo-seg": postprocessYoloSeg,
2029
2063
  scrfd: postprocessScrfd,
2030
2064
  arcface: postprocessArcface,
@@ -2835,14 +2869,17 @@ var MIN_FACE_DETECTION_FLOOR_PX = 6;
2835
2869
  var NATIVE_FACE_CROP_MAX_WIDTH = 320;
2836
2870
  /**
2837
2871
  * StepOutput kinds that synthesize a full-frame detection when they run at
2838
- * the tree ROOT (see `synthesizeRootDetection`) — classifier/embedding steps
2839
- * promoted to root by `pipelineRunner.runDetailSubtree` (task 6b), e.g.
2840
- * `clip-embedding`, `animal-classifier`. Detector (`'detections'`) roots take
2841
- * the normal path; `'text'`/`'mask'` roots are out of scope and still
2842
- * `continue` with no output, matching pre-existing behaviour.
2872
+ * the tree ROOT (see `synthesizeRootDetection`) — classifier/embedding/OCR
2873
+ * steps promoted to root by `pipelineRunner.runDetailSubtree` (task 6b), e.g.
2874
+ * `clip-embedding`, `animal-classifier`, `plate-ocr`. Detector (`'detections'`)
2875
+ * roots take the normal path. `'text'` is included so a `plate-ocr` step run
2876
+ * standalone on an already-cut plate crop (parent class `plate`) synthesizes a
2877
+ * full-frame detection carrying the recognized text as a label, instead of
2878
+ * silently dropping — the OCR chain otherwise only surfaces text when nested
2879
+ * under `plate-detection`. `'mask'` roots remain out of scope.
2843
2880
  */
2844
2881
  function isEnrichmentOutput(output) {
2845
- return output.kind === "classifications" || output.kind === "embedding";
2882
+ return output.kind === "classifications" || output.kind === "embedding" || output.kind === "text";
2846
2883
  }
2847
2884
  var PipelineExecutor = class {
2848
2885
  opts;
@@ -3625,7 +3662,8 @@ function toProbedHardware(hw) {
3625
3662
  if (!hw) return null;
3626
3663
  return {
3627
3664
  npu: hw.npu ? { type: hw.npu.type } : null,
3628
- gpu: hw.gpu ? { type: hw.gpu.type } : null
3665
+ gpu: hw.gpu ? { type: hw.gpu.type } : null,
3666
+ coral: hw.coral ? { type: hw.coral.type } : null
3629
3667
  };
3630
3668
  }
3631
3669
  var ONNX_FLOOR = {
@@ -3731,16 +3769,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
3731
3769
  */
3732
3770
  loggedLiveDispatchIssues = /* @__PURE__ */ new Set();
3733
3771
  /**
3734
- * CB5 shm passthrough — the process-local, LONG-LIVED reader cache for
3735
- * `runPipeline({ frameHandle })`. Opens each named shm segment ONCE and
3736
- * reuses the mapping for every later handle on the same ring (never
3737
- * open/close per-call). Lazily created on first handle, unmapped in
3738
- * {@link shutdown}. The executor and the runner are both hub-local
3739
- * processes sharing `/dev/shm`, so a LOCAL handle resolves to a zero-copy
3740
- * read here.
3741
- */
3742
- frameHandleReaders = null;
3743
- /**
3744
3772
  * Lazy detection-engine runtime provisioner (Phase 2). Owns the
3745
3773
  * idle → installing → verifying → ready state machine for the
3746
3774
  * currently-selected engine and is the SOLE authority the inference
@@ -3937,14 +3965,15 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
3937
3965
  */
3938
3966
  resolvedEngineBackend() {
3939
3967
  const backend = this.currentEngine.backend;
3940
- return backend === "openvino" || backend === "coreml" ? backend : "onnx";
3968
+ return backend === "openvino" || backend === "coreml" || backend === "edgetpu" ? backend : "onnx";
3941
3969
  }
3942
3970
  /** Map a backend string to a known RuntimeId, flooring to onnx. */
3943
3971
  toRuntimeId(backend) {
3944
3972
  return [
3945
3973
  "onnx",
3946
3974
  "openvino",
3947
- "coreml"
3975
+ "coreml",
3976
+ "edgetpu"
3948
3977
  ].find((id) => id === backend) ?? "onnx";
3949
3978
  }
3950
3979
  /**
@@ -4607,35 +4636,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4607
4636
  } });
4608
4637
  return { success: true };
4609
4638
  }
4610
- /** This executor's cluster node id (suffix-stripped, matching the runner). */
4611
- ownNodeId() {
4612
- const raw = this.addonCtx?.kernel?.localNodeId ?? "hub";
4613
- return raw.includes("/") ? raw.split("/")[0] : raw;
4614
- }
4615
- /**
4616
- * CB5 — resolve a shm `FrameHandle` to pixels zero-copy. Returns `null`
4617
- * when:
4618
- * - the handle is FOREIGN (its segment lives on another node — a local
4619
- * `shm_open` would flood ENOENT; the runner only sends LOCAL handles, so
4620
- * this is a defensive guard against an unexpected topology);
4621
- * - the ring slot was recycled before the read (latest-wins drop) or the
4622
- * segment could not be mapped.
4623
- * A `null` degrades the caller to an empty `FrameResult` — the runner ships
4624
- * pixels via `frame` as the fallback.
4625
- */
4626
- resolveFrameHandle(handle) {
4627
- if (handle.nodeId !== this.ownNodeId()) return null;
4628
- if (!this.frameHandleReaders) this.frameHandleReaders = new FrameRingReaderCache(this.log);
4629
- const decoded = this.frameHandleReaders.read(handle);
4630
- if (!decoded) return null;
4631
- return {
4632
- data: decoded.data,
4633
- width: decoded.width,
4634
- height: decoded.height,
4635
- format: decoded.format,
4636
- timestamp: decoded.timestamp
4637
- };
4638
- }
4639
4639
  /**
4640
4640
  * Minimal detection-free `FrameResult` returned when a `frameHandle` read
4641
4641
  * misses (recycled slot / foreign / unmappable). Shape-identical to a
@@ -4728,12 +4728,8 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4728
4728
  ].filter((s) => s !== null);
4729
4729
  if (sources.length === 0) throw new Error("runPipeline requires exactly one of: frame, frameHandle, image, imageBase64, referenceImage");
4730
4730
  if (sources.length > 1) throw new Error(`runPipeline received conflicting image sources: ${sources.join(", ")}`);
4731
- let handleFrame = null;
4732
- if (input.frameHandle) {
4733
- handleFrame = this.resolveFrameHandle(input.frameHandle);
4734
- if (!handleFrame) return this.emptyFrameHandleResult(input);
4735
- }
4736
- const runtimeFrame = input.frame ?? handleFrame ?? void 0;
4731
+ if (input.frameHandle) return this.emptyFrameHandleResult(input);
4732
+ const runtimeFrame = input.frame ?? void 0;
4737
4733
  const decodeT0 = performance.now();
4738
4734
  if (runtimeFrame) {
4739
4735
  const frame = runtimeFrame;
@@ -5488,8 +5484,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5488
5484
  this.executor = null;
5489
5485
  }
5490
5486
  for (const id of Array.from(this.deviceProxies.keys())) this.releaseDeviceProxy(id);
5491
- this.frameHandleReaders?.close();
5492
- this.frameHandleReaders = null;
5493
5487
  }
5494
5488
  /**
5495
5489
  * Resolve and cache a {@link DeviceProxy} for the given camera. Pins
@@ -6225,7 +6219,8 @@ var BACKEND_TO_FORMAT = {
6225
6219
  cpu: "onnx",
6226
6220
  coreml: "coreml",
6227
6221
  openvino: "openvino",
6228
- onnx: "onnx"
6222
+ onnx: "onnx",
6223
+ edgetpu: "tflite"
6229
6224
  };
6230
6225
  /**
6231
6226
  * Every runtime the registry knows about, in offer order. Used only to build
@@ -6236,7 +6231,8 @@ var BACKEND_TO_FORMAT = {
6236
6231
  var ALL_RUNTIME_IDS = [
6237
6232
  "onnx",
6238
6233
  "openvino",
6239
- "coreml"
6234
+ "coreml",
6235
+ "edgetpu"
6240
6236
  ];
6241
6237
  /**
6242
6238
  * Narrow an arbitrary stored backend string to a known `RuntimeId`. Legacy or
@@ -6704,6 +6700,7 @@ var DetectionPipelineAddon = class DetectionPipelineAddon extends BaseAddon {
6704
6700
  return {
6705
6701
  npu: hw.npu ? { type: hw.npu.type } : null,
6706
6702
  gpu: hw.gpu ? { type: hw.gpu.type } : null,
6703
+ coral: hw.coral ? { type: hw.coral.type } : null,
6707
6704
  platform: hw.platform,
6708
6705
  arch: hw.arch
6709
6706
  };