@camstack/addon-pipeline 1.0.1 → 1.0.2
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.
- package/dist/audio-analyzer/index.js +5 -5
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +1 -1
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +71 -9
- package/dist/detection-pipeline/index.mjs +64 -3
- package/dist/{dist-7ewQjTle.js → dist-C1goFC50.js} +4 -4
- package/dist/{dist-C5jnNl0n.mjs → dist-XRXnZrVC.mjs} +4 -4
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +1 -1
- package/dist/pipeline-runner/index.mjs +1 -1
- package/dist/recorder/index.js +3 -3
- package/dist/recorder/index.mjs +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +2 -2
- package/package.json +3 -3
|
@@ -3,12 +3,12 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
10
10
|
node_path = require_chunk.__toESM(node_path);
|
|
11
|
-
let
|
|
11
|
+
let _camstack_system = require("@camstack/system");
|
|
12
12
|
//#region src/audio-analyzer/audio-pipeline.ts
|
|
13
13
|
/**
|
|
14
14
|
* Create the appropriate audio pipeline.
|
|
@@ -27,7 +27,7 @@ async function createAudioPipeline(modelsDir, logger, options) {
|
|
|
27
27
|
* Canonical model URLs on the camstack HuggingFace mirror. Mirrors the
|
|
28
28
|
* convention every detection model follows (single point of truth =
|
|
29
29
|
* `HF_BASE_URL` from `@camstack/types`); the auto-download path uses
|
|
30
|
-
* `downloadFile` from `@camstack/
|
|
30
|
+
* `downloadFile` from `@camstack/system`, the SAME helper detection-
|
|
31
31
|
* pipeline uses to materialise its YOLO/face/plate models.
|
|
32
32
|
*
|
|
33
33
|
* {domain}/{family}/{format}/{filename}
|
|
@@ -83,7 +83,7 @@ var YamnetPythonPipeline = class {
|
|
|
83
83
|
url: YAMNET_MODEL_URL,
|
|
84
84
|
dest: modelPath
|
|
85
85
|
} });
|
|
86
|
-
await (0,
|
|
86
|
+
await (0, _camstack_system.downloadFile)(YAMNET_MODEL_URL, modelPath);
|
|
87
87
|
this.log.info("YAMNet ONNX model downloaded", { meta: { sizeBytes: node_fs.statSync(modelPath).size } });
|
|
88
88
|
}
|
|
89
89
|
if (!node_fs.existsSync(labelsPath)) {
|
|
@@ -91,7 +91,7 @@ var YamnetPythonPipeline = class {
|
|
|
91
91
|
url: YAMNET_LABELS_URL,
|
|
92
92
|
dest: labelsPath
|
|
93
93
|
} });
|
|
94
|
-
await (0,
|
|
94
|
+
await (0, _camstack_system.downloadFile)(YAMNET_LABELS_URL, labelsPath);
|
|
95
95
|
}
|
|
96
96
|
const pythonDir = resolveAudioPythonDir();
|
|
97
97
|
if (this.installPythonRequirements) await this.installPythonRequirements(node_path.join(pythonDir, "requirements-audio.txt"));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { L as mapAudioLabelToMacro, P as hydrateSchema, S as audioAnalyzerCapability, c as DEFAULT_AUDIO_ANALYZER_CONFIG, i as BaseAddon, j as errMsg, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, x as audioAnalysisCapability } from "../dist-
|
|
2
|
+
import { L as mapAudioLabelToMacro, P as hydrateSchema, S as audioAnalyzerCapability, c as DEFAULT_AUDIO_ANALYZER_CONFIG, i as BaseAddon, j as errMsg, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, x as audioAnalysisCapability } from "../dist-XRXnZrVC.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
|
-
import { downloadFile } from "@camstack/
|
|
5
|
+
import { downloadFile } from "@camstack/system";
|
|
6
6
|
//#region src/audio-analyzer/audio-pipeline.ts
|
|
7
7
|
/**
|
|
8
8
|
* Create the appropriate audio pipeline.
|
|
@@ -21,7 +21,7 @@ async function createAudioPipeline(modelsDir, logger, options) {
|
|
|
21
21
|
* Canonical model URLs on the camstack HuggingFace mirror. Mirrors the
|
|
22
22
|
* convention every detection model follows (single point of truth =
|
|
23
23
|
* `HF_BASE_URL` from `@camstack/types`); the auto-download path uses
|
|
24
|
-
* `downloadFile` from `@camstack/
|
|
24
|
+
* `downloadFile` from `@camstack/system`, the SAME helper detection-
|
|
25
25
|
* pipeline uses to materialise its YOLO/face/plate models.
|
|
26
26
|
*
|
|
27
27
|
* {domain}/{family}/{format}/{filename}
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
const require_codec_runtime = require("../codec-runtime-BOk-13PN.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
//#region src/audio-codec-nodeav/addon/index.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as audioCodecCapability, i as BaseAddon, j as errMsg } from "../dist-
|
|
1
|
+
import { C as audioCodecCapability, i as BaseAddon, j as errMsg } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { t as DecodeRuntime } from "../codec-runtime-BsqlEjPi.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
//#region src/audio-codec-nodeav/addon/index.ts
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
//#region src/decoder-nodeav/frame-ring-sink.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { O as decoderCapability, _ as RingBuffer, h as HWACCEL_OPTIONS, i as BaseAddon, j as errMsg, l as DEFAULT_DECODER_HWACCEL_CONFIG } from "../dist-
|
|
1
|
+
import { O as decoderCapability, _ as RingBuffer, h as HWACCEL_OPTIONS, i as BaseAddon, j as errMsg, l as DEFAULT_DECODER_HWACCEL_CONFIG } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { FrameRingReaderCache, FrameRingWriter, MIN_RING_SLOTS, computeSegmentSize, computeSlotByteLength, createSegment, deriveSlotCount } from "@camstack/shm-ring";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
//#region src/decoder-nodeav/frame-ring-sink.ts
|
|
@@ -3,14 +3,14 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
10
10
|
node_path = require_chunk.__toESM(node_path);
|
|
11
11
|
let node_os = require("node:os");
|
|
12
12
|
node_os = require_chunk.__toESM(node_os);
|
|
13
|
-
let
|
|
13
|
+
let _camstack_system = require("@camstack/system");
|
|
14
14
|
let node_child_process = require("node:child_process");
|
|
15
15
|
let sharp = require("sharp");
|
|
16
16
|
sharp = require_chunk.__toESM(sharp);
|
|
@@ -3873,6 +3873,18 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3873
3873
|
device: "cuda"
|
|
3874
3874
|
};
|
|
3875
3875
|
} catch {}
|
|
3876
|
+
try {
|
|
3877
|
+
const fsmod = require("node:fs");
|
|
3878
|
+
const isIntel = require("node:os").cpus()[0]?.model?.includes("Intel") ?? false;
|
|
3879
|
+
const hasIgpu = fsmod.existsSync("/dev/dri/renderD128");
|
|
3880
|
+
const hasNpu = fsmod.existsSync("/dev/accel/accel0") || fsmod.existsSync("/dev/accel");
|
|
3881
|
+
if (isIntel && (hasIgpu || hasNpu)) return {
|
|
3882
|
+
runtime: "python",
|
|
3883
|
+
backend: "openvino",
|
|
3884
|
+
format: "openvino",
|
|
3885
|
+
device: "auto"
|
|
3886
|
+
};
|
|
3887
|
+
} catch {}
|
|
3876
3888
|
return {
|
|
3877
3889
|
runtime: "python",
|
|
3878
3890
|
backend: "onnx",
|
|
@@ -4001,7 +4013,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4001
4013
|
const formats = {};
|
|
4002
4014
|
for (const [formatKey, entry] of Object.entries(m.formats)) {
|
|
4003
4015
|
if (!entry) continue;
|
|
4004
|
-
const downloaded = (0,
|
|
4016
|
+
const downloaded = (0, _camstack_system.isModelDownloaded)(this.modelsDir, m, formatKey);
|
|
4005
4017
|
formats[formatKey] = {
|
|
4006
4018
|
url: entry.url,
|
|
4007
4019
|
sizeMB: entry.sizeMB,
|
|
@@ -4128,7 +4140,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4128
4140
|
const { modelId, format, addonId } = input;
|
|
4129
4141
|
const modelEntry = getStepDefinition(addonId).models.find((m) => m.id === modelId);
|
|
4130
4142
|
if (!modelEntry) throw new Error(`Model "${modelId}" not found in step "${addonId}" catalog`);
|
|
4131
|
-
if (!(0,
|
|
4143
|
+
if (!(0, _camstack_system.deleteModelFromDisk)(this.modelsDir, modelEntry, format)) throw new Error(`Model "${modelId}" (${format}) is not downloaded — nothing to delete`);
|
|
4132
4144
|
this.log.info("Model deleted from disk", { meta: {
|
|
4133
4145
|
modelId,
|
|
4134
4146
|
format
|
|
@@ -4583,7 +4595,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4583
4595
|
const format = this.currentEngine?.format ?? "onnx";
|
|
4584
4596
|
for (const step of needed) {
|
|
4585
4597
|
const modelEntry = getStepDefinition(step.addonId).models.find((m) => m.id === step.modelId);
|
|
4586
|
-
if (modelEntry && !(0,
|
|
4598
|
+
if (modelEntry && !(0, _camstack_system.isModelDownloaded)(this.modelsDir, modelEntry, format)) {
|
|
4587
4599
|
this.log.info("Downloading model for step", { meta: {
|
|
4588
4600
|
modelId: step.modelId,
|
|
4589
4601
|
format,
|
|
@@ -4608,7 +4620,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4608
4620
|
/** Download a model with retry + exponential backoff */
|
|
4609
4621
|
async downloadWithRetry(entry, format, maxRetries, onProgress) {
|
|
4610
4622
|
for (let attempt = 1; attempt <= maxRetries; attempt++) try {
|
|
4611
|
-
await (0,
|
|
4623
|
+
await (0, _camstack_system.ensureModel)(this.modelsDir, entry, format, onProgress);
|
|
4612
4624
|
this.log.info("Model downloaded successfully", { meta: { modelId: entry.id } });
|
|
4613
4625
|
return;
|
|
4614
4626
|
} catch (err) {
|
|
@@ -5083,11 +5095,11 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5083
5095
|
} });
|
|
5084
5096
|
continue;
|
|
5085
5097
|
}
|
|
5086
|
-
if (!(0,
|
|
5098
|
+
if (!(0, _camstack_system.isModelDownloaded)(this.modelsDir, modelEntry, format)) this.log.info("Downloading model", { meta: {
|
|
5087
5099
|
modelId: step.modelId,
|
|
5088
5100
|
format
|
|
5089
5101
|
} });
|
|
5090
|
-
downloads.push((0,
|
|
5102
|
+
downloads.push((0, _camstack_system.ensureModel)(this.modelsDir, modelEntry, format).then(() => {}));
|
|
5091
5103
|
}
|
|
5092
5104
|
await Promise.all(downloads);
|
|
5093
5105
|
await this.ensureBackendDeps(this.currentEngine);
|
|
@@ -5467,7 +5479,7 @@ function buildSchemaSlots(format, modelsDir) {
|
|
|
5467
5479
|
id: m.id,
|
|
5468
5480
|
name: m.name,
|
|
5469
5481
|
formats: Object.fromEntries(Object.entries(m.formats).map(([f, entry]) => [f, {
|
|
5470
|
-
downloaded: (0,
|
|
5482
|
+
downloaded: (0, _camstack_system.isModelDownloaded)(modelsDir, m, f),
|
|
5471
5483
|
sizeMB: entry.sizeMB
|
|
5472
5484
|
}]))
|
|
5473
5485
|
})),
|
|
@@ -5701,6 +5713,28 @@ function resolveAddonPythonDir() {
|
|
|
5701
5713
|
for (const c of candidates) if (node_fs.existsSync(node_path.join(c, "inference_pool.py"))) return c;
|
|
5702
5714
|
throw new Error(`addon-pipeline/detection-pipeline: python/ dir not found. Searched:\n${candidates.join("\n")}`);
|
|
5703
5715
|
}
|
|
5716
|
+
/**
|
|
5717
|
+
* Returns true when proactive OpenVINO installation is warranted.
|
|
5718
|
+
*
|
|
5719
|
+
* Gate: Linux host + Intel iGPU or Intel NPU detected.
|
|
5720
|
+
*
|
|
5721
|
+
* Intentionally addon-local — addons are self-contained and cannot import
|
|
5722
|
+
* `@camstack/system` internals (see architecture invariant: no cross-addon
|
|
5723
|
+
* imports). This mirrors the logic in `resolveRuntimePackages` from that
|
|
5724
|
+
* package without importing it.
|
|
5725
|
+
*
|
|
5726
|
+
* darwin is never true: coremltools handles Apple Silicon + Intel Mac.
|
|
5727
|
+
* linux-amd (or any non-Intel linux GPU) is never true: the openvino
|
|
5728
|
+
* package has no AMD backend and would fail at import time.
|
|
5729
|
+
*
|
|
5730
|
+
* @internal exported only for unit tests in the same package
|
|
5731
|
+
*/
|
|
5732
|
+
function shouldInstallOpenvino(hardware) {
|
|
5733
|
+
if (hardware.platform !== "linux") return false;
|
|
5734
|
+
const hasIntelGpu = hardware.gpu?.type === "intel";
|
|
5735
|
+
const hasIntelNpu = hardware.npu?.type === "intel-npu";
|
|
5736
|
+
return hasIntelGpu || hasIntelNpu;
|
|
5737
|
+
}
|
|
5704
5738
|
var RUNTIMES = [{
|
|
5705
5739
|
value: "python",
|
|
5706
5740
|
label: "Python (CoreML / OpenVINO / ONNX Runtime)"
|
|
@@ -6190,6 +6224,7 @@ var DetectionPipelineAddon = class extends require_dist.BaseAddon {
|
|
|
6190
6224
|
const pythonPath = await this.ctx.deps.ensurePython();
|
|
6191
6225
|
if (pythonPath) this.pythonPath = pythonPath;
|
|
6192
6226
|
else this.ctx.logger.warn("Embedded Python unavailable — runtime=\"python\" pipelines will fail until the download succeeds.");
|
|
6227
|
+
await this.proactivelyInstallOpenvino();
|
|
6193
6228
|
const effectiveTuning = this.resolveBackendTuning();
|
|
6194
6229
|
this.provider = new DetectionPipelineProvider(this.ctx.settings, modelsDir, this.ctx.logger, this.ctx.eventBus ?? null, () => ({ sections: [] }), {
|
|
6195
6230
|
concurrency: effectiveTuning.concurrency,
|
|
@@ -6255,6 +6290,32 @@ var DetectionPipelineAddon = class extends require_dist.BaseAddon {
|
|
|
6255
6290
|
getModelCatalog() {
|
|
6256
6291
|
return ALL_STEPS.flatMap((s) => [...s.models]);
|
|
6257
6292
|
}
|
|
6293
|
+
/**
|
|
6294
|
+
* Proactively install the OpenVINO Python package when Intel hardware
|
|
6295
|
+
* (iGPU or NPU) is detected. Called once from `onInitialize`, before the
|
|
6296
|
+
* provider is constructed, so the module is available when the platform
|
|
6297
|
+
* probe runs its next `import openvino.runtime` check.
|
|
6298
|
+
*
|
|
6299
|
+
* Failure is non-fatal: a warning is logged and the addon continues with
|
|
6300
|
+
* the onnx-cpu baseline. The hardware query itself is also best-effort —
|
|
6301
|
+
* if the platform-probe cap isn't wired yet the error is caught here.
|
|
6302
|
+
*/
|
|
6303
|
+
async proactivelyInstallOpenvino() {
|
|
6304
|
+
if (!this.pythonAddonDir || !this.pythonPath) return;
|
|
6305
|
+
try {
|
|
6306
|
+
const hardware = await this.ctx.api.platformProbe.getHardware.query();
|
|
6307
|
+
if (!shouldInstallOpenvino(hardware)) return;
|
|
6308
|
+
this.ctx.logger.info("Intel hardware detected — proactively installing OpenVINO Python package", { meta: {
|
|
6309
|
+
gpu: hardware.gpu?.type ?? null,
|
|
6310
|
+
npu: hardware.npu?.type ?? null
|
|
6311
|
+
} });
|
|
6312
|
+
const requirementsFile = node_path.join(this.pythonAddonDir, "requirements-openvino.txt");
|
|
6313
|
+
await this.ctx.deps.installPythonRequirements(requirementsFile);
|
|
6314
|
+
this.ctx.logger.info("Proactive OpenVINO install complete");
|
|
6315
|
+
} catch (err) {
|
|
6316
|
+
this.ctx.logger.warn("Proactive OpenVINO install failed — falling back to onnx-cpu baseline", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6258
6319
|
async onShutdown() {
|
|
6259
6320
|
if (this.engineMetricsTimer) {
|
|
6260
6321
|
clearInterval(this.engineMetricsTimer);
|
|
@@ -6349,3 +6410,4 @@ exports.backendToFormat = backendToFormat;
|
|
|
6349
6410
|
exports.default = DetectionPipelineAddon;
|
|
6350
6411
|
exports.getDefaultModelForFormat = getDefaultModelForFormat;
|
|
6351
6412
|
exports.getStepDefinition = getStepDefinition;
|
|
6413
|
+
exports.shouldInstallOpenvino = shouldInstallOpenvino;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { A as detectionPipelineCapability, E as createEvent, M as evaluateZoneRules, N as hfModelUrl, P as hydrateSchema, U as pipelineExecutorCapability, V as parseJsonUnknown, i as BaseAddon, j as errMsg, o as COCO_80_LABELS, p as EventCategory, q as sleep, r as AUDIO_MACRO_LABELS, s as COCO_TO_MACRO, t as APPLE_SA_TO_MACRO, v as YAMNET_TO_MACRO } from "../dist-
|
|
2
|
+
import { A as detectionPipelineCapability, E as createEvent, M as evaluateZoneRules, N as hfModelUrl, P as hydrateSchema, U as pipelineExecutorCapability, V as parseJsonUnknown, i as BaseAddon, j as errMsg, o as COCO_80_LABELS, p as EventCategory, q as sleep, r as AUDIO_MACRO_LABELS, s as COCO_TO_MACRO, t as APPLE_SA_TO_MACRO, v as YAMNET_TO_MACRO } from "../dist-XRXnZrVC.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
5
|
import * as os from "node:os";
|
|
6
|
-
import { deleteModelFromDisk, ensureModel, isModelDownloaded } from "@camstack/
|
|
6
|
+
import { deleteModelFromDisk, ensureModel, isModelDownloaded } from "@camstack/system";
|
|
7
7
|
import { spawn } from "node:child_process";
|
|
8
8
|
import sharp from "sharp";
|
|
9
9
|
//#region src/detection-pipeline/engine/shared-inference-pool.ts
|
|
@@ -3865,6 +3865,18 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3865
3865
|
device: "cuda"
|
|
3866
3866
|
};
|
|
3867
3867
|
} catch {}
|
|
3868
|
+
try {
|
|
3869
|
+
const fsmod = __require("node:fs");
|
|
3870
|
+
const isIntel = __require("node:os").cpus()[0]?.model?.includes("Intel") ?? false;
|
|
3871
|
+
const hasIgpu = fsmod.existsSync("/dev/dri/renderD128");
|
|
3872
|
+
const hasNpu = fsmod.existsSync("/dev/accel/accel0") || fsmod.existsSync("/dev/accel");
|
|
3873
|
+
if (isIntel && (hasIgpu || hasNpu)) return {
|
|
3874
|
+
runtime: "python",
|
|
3875
|
+
backend: "openvino",
|
|
3876
|
+
format: "openvino",
|
|
3877
|
+
device: "auto"
|
|
3878
|
+
};
|
|
3879
|
+
} catch {}
|
|
3868
3880
|
return {
|
|
3869
3881
|
runtime: "python",
|
|
3870
3882
|
backend: "onnx",
|
|
@@ -5693,6 +5705,28 @@ function resolveAddonPythonDir() {
|
|
|
5693
5705
|
for (const c of candidates) if (fs.existsSync(path$1.join(c, "inference_pool.py"))) return c;
|
|
5694
5706
|
throw new Error(`addon-pipeline/detection-pipeline: python/ dir not found. Searched:\n${candidates.join("\n")}`);
|
|
5695
5707
|
}
|
|
5708
|
+
/**
|
|
5709
|
+
* Returns true when proactive OpenVINO installation is warranted.
|
|
5710
|
+
*
|
|
5711
|
+
* Gate: Linux host + Intel iGPU or Intel NPU detected.
|
|
5712
|
+
*
|
|
5713
|
+
* Intentionally addon-local — addons are self-contained and cannot import
|
|
5714
|
+
* `@camstack/system` internals (see architecture invariant: no cross-addon
|
|
5715
|
+
* imports). This mirrors the logic in `resolveRuntimePackages` from that
|
|
5716
|
+
* package without importing it.
|
|
5717
|
+
*
|
|
5718
|
+
* darwin is never true: coremltools handles Apple Silicon + Intel Mac.
|
|
5719
|
+
* linux-amd (or any non-Intel linux GPU) is never true: the openvino
|
|
5720
|
+
* package has no AMD backend and would fail at import time.
|
|
5721
|
+
*
|
|
5722
|
+
* @internal exported only for unit tests in the same package
|
|
5723
|
+
*/
|
|
5724
|
+
function shouldInstallOpenvino(hardware) {
|
|
5725
|
+
if (hardware.platform !== "linux") return false;
|
|
5726
|
+
const hasIntelGpu = hardware.gpu?.type === "intel";
|
|
5727
|
+
const hasIntelNpu = hardware.npu?.type === "intel-npu";
|
|
5728
|
+
return hasIntelGpu || hasIntelNpu;
|
|
5729
|
+
}
|
|
5696
5730
|
var RUNTIMES = [{
|
|
5697
5731
|
value: "python",
|
|
5698
5732
|
label: "Python (CoreML / OpenVINO / ONNX Runtime)"
|
|
@@ -6182,6 +6216,7 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6182
6216
|
const pythonPath = await this.ctx.deps.ensurePython();
|
|
6183
6217
|
if (pythonPath) this.pythonPath = pythonPath;
|
|
6184
6218
|
else this.ctx.logger.warn("Embedded Python unavailable — runtime=\"python\" pipelines will fail until the download succeeds.");
|
|
6219
|
+
await this.proactivelyInstallOpenvino();
|
|
6185
6220
|
const effectiveTuning = this.resolveBackendTuning();
|
|
6186
6221
|
this.provider = new DetectionPipelineProvider(this.ctx.settings, modelsDir, this.ctx.logger, this.ctx.eventBus ?? null, () => ({ sections: [] }), {
|
|
6187
6222
|
concurrency: effectiveTuning.concurrency,
|
|
@@ -6247,6 +6282,32 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6247
6282
|
getModelCatalog() {
|
|
6248
6283
|
return ALL_STEPS.flatMap((s) => [...s.models]);
|
|
6249
6284
|
}
|
|
6285
|
+
/**
|
|
6286
|
+
* Proactively install the OpenVINO Python package when Intel hardware
|
|
6287
|
+
* (iGPU or NPU) is detected. Called once from `onInitialize`, before the
|
|
6288
|
+
* provider is constructed, so the module is available when the platform
|
|
6289
|
+
* probe runs its next `import openvino.runtime` check.
|
|
6290
|
+
*
|
|
6291
|
+
* Failure is non-fatal: a warning is logged and the addon continues with
|
|
6292
|
+
* the onnx-cpu baseline. The hardware query itself is also best-effort —
|
|
6293
|
+
* if the platform-probe cap isn't wired yet the error is caught here.
|
|
6294
|
+
*/
|
|
6295
|
+
async proactivelyInstallOpenvino() {
|
|
6296
|
+
if (!this.pythonAddonDir || !this.pythonPath) return;
|
|
6297
|
+
try {
|
|
6298
|
+
const hardware = await this.ctx.api.platformProbe.getHardware.query();
|
|
6299
|
+
if (!shouldInstallOpenvino(hardware)) return;
|
|
6300
|
+
this.ctx.logger.info("Intel hardware detected — proactively installing OpenVINO Python package", { meta: {
|
|
6301
|
+
gpu: hardware.gpu?.type ?? null,
|
|
6302
|
+
npu: hardware.npu?.type ?? null
|
|
6303
|
+
} });
|
|
6304
|
+
const requirementsFile = path$1.join(this.pythonAddonDir, "requirements-openvino.txt");
|
|
6305
|
+
await this.ctx.deps.installPythonRequirements(requirementsFile);
|
|
6306
|
+
this.ctx.logger.info("Proactive OpenVINO install complete");
|
|
6307
|
+
} catch (err) {
|
|
6308
|
+
this.ctx.logger.warn("Proactive OpenVINO install failed — falling back to onnx-cpu baseline", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
6309
|
+
}
|
|
6310
|
+
}
|
|
6250
6311
|
async onShutdown() {
|
|
6251
6312
|
if (this.engineMetricsTimer) {
|
|
6252
6313
|
clearInterval(this.engineMetricsTimer);
|
|
@@ -6335,4 +6396,4 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6335
6396
|
}
|
|
6336
6397
|
};
|
|
6337
6398
|
//#endregion
|
|
6338
|
-
export { ALL_STEPS, DetectionPipelineProvider, backendToFormat, DetectionPipelineAddon as default, getDefaultModelForFormat, getStepDefinition };
|
|
6399
|
+
export { ALL_STEPS, DetectionPipelineProvider, backendToFormat, DetectionPipelineAddon as default, getDefaultModelForFormat, getStepDefinition, shouldInstallOpenvino };
|
|
@@ -13314,7 +13314,7 @@ method(_void(), DeviceExportStatusSchema), method(_void(), array(DeviceKindSchem
|
|
|
13314
13314
|
* rebuilds without manual reload.
|
|
13315
13315
|
*
|
|
13316
13316
|
* The hub-local builtin `addon-pages-aggregator` (see
|
|
13317
|
-
* `@camstack/
|
|
13317
|
+
* `@camstack/system/builtins/addon-pages-aggregator`) registers the
|
|
13318
13318
|
* provider. Splitting the public aggregator from the raw collection
|
|
13319
13319
|
* keeps both ends in codegen — there's no hand-written
|
|
13320
13320
|
* `addon-pages.router.ts` wrapper anymore.
|
|
@@ -13503,7 +13503,7 @@ var addonWidgetsSourceCapability = {
|
|
|
13503
13503
|
* manual reload — same scheme used by `addon-pages`.
|
|
13504
13504
|
*
|
|
13505
13505
|
* The hub-local builtin `addon-widgets-aggregator` (see
|
|
13506
|
-
* `@camstack/
|
|
13506
|
+
* `@camstack/system/builtins/addon-widgets-aggregator`) registers the
|
|
13507
13507
|
* provider. Splitting the public aggregator from the raw collection
|
|
13508
13508
|
* keeps both ends in codegen — there's no hand-written wrapper.
|
|
13509
13509
|
*/
|
|
@@ -16569,7 +16569,7 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
16569
16569
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
16570
16570
|
* via the same surface would leak internal topology with no upside.
|
|
16571
16571
|
*
|
|
16572
|
-
* Implementation in `@camstack/
|
|
16572
|
+
* Implementation in `@camstack/system/builtins/local-network/`.
|
|
16573
16573
|
*/
|
|
16574
16574
|
/** Coarse classification derived from the interface name + IP range. */
|
|
16575
16575
|
var InterfaceKindEnum = _enum([
|
|
@@ -17116,7 +17116,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
|
|
|
17116
17116
|
* jitter, and observed/peak bandwidth per device + per client.
|
|
17117
17117
|
*
|
|
17118
17118
|
* Implementation lives in the server's `NetworkQualityService` (thin
|
|
17119
|
-
* wrapper over the shared `NetworkQualityTracker` from `@camstack/
|
|
17119
|
+
* wrapper over the shared `NetworkQualityTracker` from `@camstack/system`).
|
|
17120
17120
|
* The provider is registered from `trpc.router.ts` against the existing
|
|
17121
17121
|
* service instance — no addon owns this state.
|
|
17122
17122
|
*
|
|
@@ -13314,7 +13314,7 @@ method(_void(), DeviceExportStatusSchema), method(_void(), array(DeviceKindSchem
|
|
|
13314
13314
|
* rebuilds without manual reload.
|
|
13315
13315
|
*
|
|
13316
13316
|
* The hub-local builtin `addon-pages-aggregator` (see
|
|
13317
|
-
* `@camstack/
|
|
13317
|
+
* `@camstack/system/builtins/addon-pages-aggregator`) registers the
|
|
13318
13318
|
* provider. Splitting the public aggregator from the raw collection
|
|
13319
13319
|
* keeps both ends in codegen — there's no hand-written
|
|
13320
13320
|
* `addon-pages.router.ts` wrapper anymore.
|
|
@@ -13503,7 +13503,7 @@ var addonWidgetsSourceCapability = {
|
|
|
13503
13503
|
* manual reload — same scheme used by `addon-pages`.
|
|
13504
13504
|
*
|
|
13505
13505
|
* The hub-local builtin `addon-widgets-aggregator` (see
|
|
13506
|
-
* `@camstack/
|
|
13506
|
+
* `@camstack/system/builtins/addon-widgets-aggregator`) registers the
|
|
13507
13507
|
* provider. Splitting the public aggregator from the raw collection
|
|
13508
13508
|
* keeps both ends in codegen — there's no hand-written wrapper.
|
|
13509
13509
|
*/
|
|
@@ -16569,7 +16569,7 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
16569
16569
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
16570
16570
|
* via the same surface would leak internal topology with no upside.
|
|
16571
16571
|
*
|
|
16572
|
-
* Implementation in `@camstack/
|
|
16572
|
+
* Implementation in `@camstack/system/builtins/local-network/`.
|
|
16573
16573
|
*/
|
|
16574
16574
|
/** Coarse classification derived from the interface name + IP range. */
|
|
16575
16575
|
var InterfaceKindEnum = _enum([
|
|
@@ -17116,7 +17116,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
|
|
|
17116
17116
|
* jitter, and observed/peak bandwidth per device + per client.
|
|
17117
17117
|
*
|
|
17118
17118
|
* Implementation lives in the server's `NetworkQualityService` (thin
|
|
17119
|
-
* wrapper over the shared `NetworkQualityTracker` from `@camstack/
|
|
17119
|
+
* wrapper over the shared `NetworkQualityTracker` from `@camstack/system`).
|
|
17120
17120
|
* The provider is registered from `trpc.router.ts` against the existing
|
|
17121
17121
|
* service instance — no addon owns this state.
|
|
17122
17122
|
*
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as motionDetectionCapability, M as evaluateZoneRules, P as hydrateSchema, d as DeviceType, i as BaseAddon } from "../dist-
|
|
1
|
+
import { B as motionDetectionCapability, M as evaluateZoneRules, P as hydrateSchema, d as DeviceType, i as BaseAddon } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
7
7
|
//#region src/pipeline-runner/frame-queue.ts
|
|
8
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as boolean, D as customAction, E as createEvent, I as makeSourceBrokerId, Q as array, W as pipelineRunnerCapability, Z as _enum, i as BaseAddon, it as object, j as errMsg, k as defineCustomActions, ot as string, p as EventCategory, rt as number, tt as lazy } from "../dist-
|
|
1
|
+
import { $ as boolean, D as customAction, E as createEvent, I as makeSourceBrokerId, Q as array, W as pipelineRunnerCapability, Z as _enum, i as BaseAddon, it as object, j as errMsg, k as defineCustomActions, ot as string, p as EventCategory, rt as number, tt as lazy } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { FrameRingReaderCache } from "@camstack/shm-ring";
|
|
3
3
|
//#region src/pipeline-runner/frame-queue.ts
|
|
4
4
|
/**
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
|
6
|
-
let
|
|
6
|
+
let _camstack_system = require("@camstack/system");
|
|
7
7
|
let node_child_process = require("node:child_process");
|
|
8
8
|
//#region src/recorder/segment-path.ts
|
|
9
9
|
function segmentRelPath(deviceId, profile, startMs, durMs, bytes) {
|
|
@@ -1935,7 +1935,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
1935
1935
|
store: this.segmentStore
|
|
1936
1936
|
});
|
|
1937
1937
|
try {
|
|
1938
|
-
const handler = (0,
|
|
1938
|
+
const handler = (0, _camstack_system.createFileDataPlaneHandler)({ getRoots: () => this.playbackRoots() });
|
|
1939
1939
|
const served = await this.ctx.dataPlane?.serve({
|
|
1940
1940
|
prefix: PLAYBACK_PREFIX,
|
|
1941
1941
|
access: "authenticated",
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { G as recordingCapability, J as storageEvictableCapability, K as selectAssignedProfileSlots, P as hydrateSchema, T as createDurableState, at as record, g as RecordingConfigSchema, i as BaseAddon, j as errMsg, ot as string, p as EventCategory, z as migrateConfigToBands } from "../dist-
|
|
1
|
+
import { G as recordingCapability, J as storageEvictableCapability, K as selectAssignedProfileSlots, P as hydrateSchema, T as createDurableState, at as record, g as RecordingConfigSchema, i as BaseAddon, j as errMsg, ot as string, p as EventCategory, z as migrateConfigToBands } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { promises } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { createFileDataPlaneHandler } from "@camstack/
|
|
4
|
+
import { createFileDataPlaneHandler } from "@camstack/system";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
//#region src/recorder/segment-path.ts
|
|
7
7
|
function segmentRelPath(deviceId, profile, startMs, durMs, bytes) {
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
7
7
|
const require_codec_runtime = require("../codec-runtime-BOk-13PN.js");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -11,7 +11,7 @@ let node_path = require("node:path");
|
|
|
11
11
|
node_path = require_chunk.__toESM(node_path);
|
|
12
12
|
let node_os = require("node:os");
|
|
13
13
|
node_os = require_chunk.__toESM(node_os);
|
|
14
|
-
let
|
|
14
|
+
let _camstack_system = require("@camstack/system");
|
|
15
15
|
let node_child_process = require("node:child_process");
|
|
16
16
|
let node_crypto = require("node:crypto");
|
|
17
17
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
@@ -27,7 +27,7 @@ let node_events = require("node:events");
|
|
|
27
27
|
/** Build a `(req, res)` handler serving the embed bundle at `root` with SPA fallback.
|
|
28
28
|
* Web MIME types (`.html`/`.js`/`.css`/…) come from the core handler's defaults. */
|
|
29
29
|
function createEmbedSpaHandler(root) {
|
|
30
|
-
const fileHandler = (0,
|
|
30
|
+
const fileHandler = (0, _camstack_system.createFileDataPlaneHandler)({ getRoots: () => [root] });
|
|
31
31
|
return (req, res) => {
|
|
32
32
|
const [pathPart = "/", query] = (req.url ?? "/").split("?");
|
|
33
33
|
const lastSegment = pathPart.split("/").pop() ?? "";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { $ as boolean, E as createEvent, F as makeProfileBrokerId, H as parseProfileBrokerId, I as makeSourceBrokerId, R as maskUrlCredentials, X as webrtcSessionCapability, Y as streamBrokerCapability, Z as _enum, _ as RingBuffer, a as CAM_PROFILE_ORDER, at as record, b as asJsonObject, d as DeviceType, et as discriminatedUnion, f as EncodeProfileSchema, i as BaseAddon, it as object, j as errMsg, nt as literal, ot as string, p as EventCategory, rt as number, st as union, u as DeviceFeature, w as cameraStreamsCapability, y as addonWidgetsSourceCapability } from "../dist-
|
|
2
|
+
import { $ as boolean, E as createEvent, F as makeProfileBrokerId, H as parseProfileBrokerId, I as makeSourceBrokerId, R as maskUrlCredentials, X as webrtcSessionCapability, Y as streamBrokerCapability, Z as _enum, _ as RingBuffer, a as CAM_PROFILE_ORDER, at as record, b as asJsonObject, d as DeviceType, et as discriminatedUnion, f as EncodeProfileSchema, i as BaseAddon, it as object, j as errMsg, nt as literal, ot as string, p as EventCategory, rt as number, st as union, u as DeviceFeature, w as cameraStreamsCapability, y as addonWidgetsSourceCapability } from "../dist-XRXnZrVC.mjs";
|
|
3
3
|
import { t as DecodeRuntime } from "../codec-runtime-BsqlEjPi.mjs";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
6
6
|
import path, { join } from "node:path";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
9
|
-
import { createFileDataPlaneHandler } from "@camstack/
|
|
9
|
+
import { createFileDataPlaneHandler } from "@camstack/system";
|
|
10
10
|
import { spawn } from "node:child_process";
|
|
11
11
|
import * as crypto$1 from "node:crypto";
|
|
12
12
|
import crypto, { createHash, randomBytes, randomUUID } from "node:crypto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "CamStack Pipeline bundle — runner, detection, motion, decoders, audio + stream broker. Multi-entry npm package shipping 7 addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -291,13 +291,13 @@
|
|
|
291
291
|
"publish": "npm publish --access public"
|
|
292
292
|
},
|
|
293
293
|
"peerDependencies": {
|
|
294
|
-
"@camstack/types": "
|
|
294
|
+
"@camstack/types": "*",
|
|
295
295
|
"react": ">=18",
|
|
296
296
|
"react-dom": ">=18",
|
|
297
297
|
"werift": "^0.22.9"
|
|
298
298
|
},
|
|
299
299
|
"dependencies": {
|
|
300
|
-
"@camstack/
|
|
300
|
+
"@camstack/system": "*",
|
|
301
301
|
"lucide-react": "^0.511.0",
|
|
302
302
|
"mp4box": "0.5.4",
|
|
303
303
|
"node-av": "^5.2.4",
|