@camstack/addon-pipeline 1.0.1 → 1.0.3
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 +276 -61
- package/dist/detection-pipeline/index.mjs +268 -55
- 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/_stub.js +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-qX99--rF.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-dGO6_Xee.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B0Z2W5UM.mjs +26 -0
- package/dist/stream-broker/{hostInit-Bx41KdYV.mjs → hostInit-ClKL4kbX.mjs} +3 -3
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +2 -2
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/MaskShapeCanvas-DI4BY7W2-DEYqSd2k.js +33 -0
- package/embed-dist/assets/MotionZonesSettings-C1EEbk2V-CRvYkSju.js +1 -0
- package/embed-dist/assets/PrivacyMaskSettings-APgPLF7p-CIq73-7y.js +1 -0
- package/embed-dist/assets/index-C5Az4io-.js +80 -0
- package/embed-dist/index.html +1 -1
- package/package.json +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-C9WX5HNw.mjs +0 -26
- package/embed-dist/assets/index-B8VlSD0-.js +0 -150
|
@@ -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",
|
|
@@ -3876,22 +3888,68 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3876
3888
|
async setApi(addonCtx) {
|
|
3877
3889
|
this.addonCtx = addonCtx;
|
|
3878
3890
|
}
|
|
3891
|
+
/**
|
|
3892
|
+
* Fetch platform-probe data for engine + device gating. Returns null for
|
|
3893
|
+
* both fields when the probe cap is not yet reachable (cold-start / probe
|
|
3894
|
+
* addon not installed), so callers fall back to the full static catalog.
|
|
3895
|
+
*/
|
|
3896
|
+
async fetchProbeGatingData() {
|
|
3897
|
+
try {
|
|
3898
|
+
const api = this.addonCtx?.api;
|
|
3899
|
+
if (!api) return {
|
|
3900
|
+
availableBackends: null,
|
|
3901
|
+
hardware: null
|
|
3902
|
+
};
|
|
3903
|
+
const caps = await api.platformProbe.getCapabilities.query();
|
|
3904
|
+
if (!caps?.scores) return {
|
|
3905
|
+
availableBackends: null,
|
|
3906
|
+
hardware: null
|
|
3907
|
+
};
|
|
3908
|
+
return {
|
|
3909
|
+
availableBackends: caps.scores.filter((s) => s.runtime === "python" && s.available).map((s) => s.backend),
|
|
3910
|
+
hardware: caps.hardware ?? null
|
|
3911
|
+
};
|
|
3912
|
+
} catch {
|
|
3913
|
+
return {
|
|
3914
|
+
availableBackends: null,
|
|
3915
|
+
hardware: null
|
|
3916
|
+
};
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3879
3919
|
async getSchema(engine) {
|
|
3880
3920
|
if (!engine || !engine.runtime) engine = await this.getSelectedEngine();
|
|
3881
3921
|
const format = engine.format;
|
|
3882
3922
|
const slots = buildSchemaSlots(format, this.modelsDir);
|
|
3923
|
+
const { availableBackends, hardware } = await this.fetchProbeGatingData();
|
|
3883
3924
|
return {
|
|
3884
|
-
availableEngines: this.getAvailableEnginesWithDevices(),
|
|
3925
|
+
availableEngines: this.getAvailableEnginesWithDevices(availableBackends, hardware),
|
|
3885
3926
|
selectedEngine: { ...engine },
|
|
3886
3927
|
slots
|
|
3887
3928
|
};
|
|
3888
3929
|
}
|
|
3889
3930
|
async getAvailableEngines() {
|
|
3890
|
-
|
|
3931
|
+
const { availableBackends, hardware } = await this.fetchProbeGatingData();
|
|
3932
|
+
return this.getAvailableEnginesWithDevices(availableBackends, hardware).map((e) => e.engine);
|
|
3891
3933
|
}
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3934
|
+
/**
|
|
3935
|
+
* Build the engine catalog filtered by probe data.
|
|
3936
|
+
*
|
|
3937
|
+
* When `availableBackends` is not null, only engines whose backend is
|
|
3938
|
+
* reported as available by the platform-probe cap are included. This
|
|
3939
|
+
* prevents the benchmark picker from offering (e.g.) CoreML on an Intel
|
|
3940
|
+
* Linux host where the Python coremltools package is absent.
|
|
3941
|
+
*
|
|
3942
|
+
* When `hardware` is not null, the per-engine device list is narrowed to
|
|
3943
|
+
* entries that are valid on this host's hardware (no Intel NPU → no 'npu'
|
|
3944
|
+
* device for OpenVINO, no NVIDIA GPU → no 'cuda' for ONNX, etc.).
|
|
3945
|
+
*
|
|
3946
|
+
* When either argument is null (probe unreachable / cold-start), the full
|
|
3947
|
+
* static catalog is returned unchanged — conservative fallback so the UI
|
|
3948
|
+
* still renders all options rather than going blank.
|
|
3949
|
+
*/
|
|
3950
|
+
getAvailableEnginesWithDevices(availableBackends, hardware) {
|
|
3951
|
+
const allEngines = [];
|
|
3952
|
+
if (process.platform === "darwin") allEngines.push({
|
|
3895
3953
|
engine: {
|
|
3896
3954
|
runtime: "python",
|
|
3897
3955
|
backend: "coreml",
|
|
@@ -3900,7 +3958,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3900
3958
|
devices: COREML_DEVICES,
|
|
3901
3959
|
defaultDevice: "all"
|
|
3902
3960
|
});
|
|
3903
|
-
|
|
3961
|
+
allEngines.push({
|
|
3904
3962
|
engine: {
|
|
3905
3963
|
runtime: "python",
|
|
3906
3964
|
backend: "openvino",
|
|
@@ -3909,7 +3967,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3909
3967
|
devices: OPENVINO_DEVICES,
|
|
3910
3968
|
defaultDevice: "auto"
|
|
3911
3969
|
});
|
|
3912
|
-
|
|
3970
|
+
allEngines.push({
|
|
3913
3971
|
engine: {
|
|
3914
3972
|
runtime: "python",
|
|
3915
3973
|
backend: "onnx",
|
|
@@ -3918,7 +3976,19 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
3918
3976
|
devices: ONNX_PYTHON_DEVICES,
|
|
3919
3977
|
defaultDevice: "cpu"
|
|
3920
3978
|
});
|
|
3921
|
-
return
|
|
3979
|
+
if (!availableBackends) return allEngines;
|
|
3980
|
+
return allEngines.filter((e) => availableBackends.includes(e.engine.backend)).map((e) => {
|
|
3981
|
+
if (!hardware) return e;
|
|
3982
|
+
const filtered = filterDeviceOptionsByHardware(e.devices.map((d) => ({
|
|
3983
|
+
value: d.id,
|
|
3984
|
+
label: d.label
|
|
3985
|
+
})), e.engine.backend, hardware);
|
|
3986
|
+
const allowedIds = new Set(filtered.map((o) => o.value));
|
|
3987
|
+
return {
|
|
3988
|
+
...e,
|
|
3989
|
+
devices: e.devices.filter((d) => allowedIds.has(d.id))
|
|
3990
|
+
};
|
|
3991
|
+
});
|
|
3922
3992
|
}
|
|
3923
3993
|
async getDefaultSteps(engine) {
|
|
3924
3994
|
return buildDefaultStepTree(engine.format);
|
|
@@ -4010,7 +4080,8 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
4010
4080
|
};
|
|
4011
4081
|
})
|
|
4012
4082
|
}));
|
|
4013
|
-
const
|
|
4083
|
+
const { availableBackends, hardware } = await this.fetchProbeGatingData();
|
|
4084
|
+
const engines = this.getAvailableEnginesWithDevices(availableBackends, hardware);
|
|
4014
4085
|
const nodeBackends = [];
|
|
4015
4086
|
const pythonBackends = [];
|
|
4016
4087
|
for (const e of engines) if (e.engine.runtime === "node") nodeBackends.push({
|
|
@@ -5111,19 +5182,20 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5111
5182
|
*/
|
|
5112
5183
|
async loadEngine() {
|
|
5113
5184
|
const store = await this.readStore();
|
|
5114
|
-
const
|
|
5115
|
-
const
|
|
5116
|
-
if (typeof
|
|
5185
|
+
const storedRuntime = store["engineRuntime"];
|
|
5186
|
+
const storedBackend = store["engineBackend"];
|
|
5187
|
+
if (typeof storedBackend === "string" && storedBackend.length > 0) {
|
|
5188
|
+
const backend = storedBackend;
|
|
5117
5189
|
const storedDevice = typeof store["engineDevice"] === "string" ? String(store["engineDevice"]) : "";
|
|
5118
5190
|
const detected = DetectionPipelineProvider.detectBestEngine();
|
|
5119
|
-
|
|
5191
|
+
const migratedBackend = typeof storedRuntime === "string" && storedRuntime === "node" && backend === "cpu" ? "onnx" : backend;
|
|
5192
|
+
if (!DetectionPipelineProvider.isPythonBackendAvailable(migratedBackend, this.executorOptions.pythonPath ?? "")) {
|
|
5120
5193
|
this.log.warn("Stored engine backend unavailable on this node — falling back to detected best", { meta: {
|
|
5121
|
-
stored:
|
|
5122
|
-
fallback: `${detected.
|
|
5194
|
+
stored: migratedBackend,
|
|
5195
|
+
fallback: `${detected.backend}`
|
|
5123
5196
|
} });
|
|
5124
5197
|
return detected;
|
|
5125
5198
|
}
|
|
5126
|
-
const migratedBackend = runtime === "node" && backend === "cpu" ? "onnx" : backend;
|
|
5127
5199
|
const device = storedDevice || detected.device;
|
|
5128
5200
|
return {
|
|
5129
5201
|
runtime: "python",
|
|
@@ -5293,11 +5365,42 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
|
|
|
5293
5365
|
return { success: true };
|
|
5294
5366
|
}
|
|
5295
5367
|
async reprobeEngine() {
|
|
5296
|
-
const
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5368
|
+
const api = this.addonCtx?.api;
|
|
5369
|
+
let best;
|
|
5370
|
+
if (api) try {
|
|
5371
|
+
const caps = await api.platformProbe.getCapabilities.query();
|
|
5372
|
+
const bs = caps?.bestScore;
|
|
5373
|
+
if (bs && bs.runtime === "python") {
|
|
5374
|
+
const probeBackend = bs.backend;
|
|
5375
|
+
const probeDevice = (() => {
|
|
5376
|
+
const hw = caps.hardware;
|
|
5377
|
+
if (probeBackend === "coreml") return hw?.npu?.type === "apple-ane" ? "ane" : "all";
|
|
5378
|
+
if (probeBackend === "openvino") {
|
|
5379
|
+
if (hw?.npu?.type === "intel-npu") return "npu";
|
|
5380
|
+
if (hw?.gpu?.type === "intel") return "gpu";
|
|
5381
|
+
return "auto";
|
|
5382
|
+
}
|
|
5383
|
+
if (probeBackend === "onnx") return hw?.gpu?.type === "nvidia" ? "cuda" : "cpu";
|
|
5384
|
+
return "cpu";
|
|
5385
|
+
})();
|
|
5386
|
+
best = {
|
|
5387
|
+
runtime: "python",
|
|
5388
|
+
backend: probeBackend,
|
|
5389
|
+
format: backendToFormat(probeBackend),
|
|
5390
|
+
device: probeDevice
|
|
5391
|
+
};
|
|
5392
|
+
} else best = DetectionPipelineProvider.detectBestEngine();
|
|
5393
|
+
} catch {
|
|
5394
|
+
best = DetectionPipelineProvider.detectBestEngine();
|
|
5395
|
+
}
|
|
5396
|
+
else best = DetectionPipelineProvider.detectBestEngine();
|
|
5397
|
+
const probedLabel = `${best.backend}/${best.device ?? "default"}`;
|
|
5398
|
+
await this.writeStore({
|
|
5399
|
+
probedBestEngine: probedLabel,
|
|
5400
|
+
engineBackend: best.backend,
|
|
5401
|
+
engineDevice: best.device ?? "cpu"
|
|
5402
|
+
});
|
|
5403
|
+
this.log.info("Re-probed engine — wrote back engineBackend + engineDevice", { meta: {
|
|
5301
5404
|
backend: best.backend,
|
|
5302
5405
|
device: best.device ?? null,
|
|
5303
5406
|
probedBestEngine: probedLabel
|
|
@@ -5693,10 +5796,34 @@ function resolveAddonPythonDir() {
|
|
|
5693
5796
|
for (const c of candidates) if (fs.existsSync(path$1.join(c, "inference_pool.py"))) return c;
|
|
5694
5797
|
throw new Error(`addon-pipeline/detection-pipeline: python/ dir not found. Searched:\n${candidates.join("\n")}`);
|
|
5695
5798
|
}
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5799
|
+
/**
|
|
5800
|
+
* Returns true when proactive OpenVINO installation is warranted.
|
|
5801
|
+
*
|
|
5802
|
+
* Gate: Linux host + Intel iGPU or Intel NPU detected.
|
|
5803
|
+
*
|
|
5804
|
+
* Intentionally addon-local — addons are self-contained and cannot import
|
|
5805
|
+
* `@camstack/system` internals (see architecture invariant: no cross-addon
|
|
5806
|
+
* imports). This mirrors the logic in `resolveRuntimePackages` from that
|
|
5807
|
+
* package without importing it.
|
|
5808
|
+
*
|
|
5809
|
+
* darwin is never true: coremltools handles Apple Silicon + Intel Mac.
|
|
5810
|
+
* linux-amd (or any non-Intel linux GPU) is never true: the openvino
|
|
5811
|
+
* package has no AMD backend and would fail at import time.
|
|
5812
|
+
*
|
|
5813
|
+
* @internal exported only for unit tests in the same package
|
|
5814
|
+
*/
|
|
5815
|
+
function shouldInstallOpenvino(hardware) {
|
|
5816
|
+
if (hardware.platform !== "linux") return false;
|
|
5817
|
+
const hasIntelGpu = hardware.gpu?.type === "intel";
|
|
5818
|
+
const hasIntelNpu = hardware.npu?.type === "intel-npu";
|
|
5819
|
+
return hasIntelGpu || hasIntelNpu;
|
|
5820
|
+
}
|
|
5821
|
+
/**
|
|
5822
|
+
* Full catalog of execution providers. The settings UI only shows the subset
|
|
5823
|
+
* reported as available by the platform-probe cap (`getGlobalSettings` gates
|
|
5824
|
+
* options by probe scores). Kept as the static universe so the static schema
|
|
5825
|
+
* (returned before a live ctx is available) still lists all fields.
|
|
5826
|
+
*/
|
|
5700
5827
|
var BACKENDS_BY_RUNTIME = { python: [
|
|
5701
5828
|
{
|
|
5702
5829
|
value: "coreml",
|
|
@@ -5767,6 +5894,53 @@ var DEVICES_BY_BACKEND = {
|
|
|
5767
5894
|
label: "CPU"
|
|
5768
5895
|
}]
|
|
5769
5896
|
};
|
|
5897
|
+
/**
|
|
5898
|
+
* Filter the per-backend device option list by what the platform probe
|
|
5899
|
+
* reports as available hardware on this host. Rules (derived from the
|
|
5900
|
+
* confirmed target model):
|
|
5901
|
+
*
|
|
5902
|
+
* coreml:
|
|
5903
|
+
* - `ane` only when `hardware.npu?.type === 'apple-ane'`
|
|
5904
|
+
* - `gpu` and `all` always shown (CPU+GPU present on every Mac)
|
|
5905
|
+
* - `cpu` always shown
|
|
5906
|
+
*
|
|
5907
|
+
* openvino:
|
|
5908
|
+
* - `npu` only when `hardware.npu?.type === 'intel-npu'`
|
|
5909
|
+
* - `gpu` only when `hardware.gpu?.type === 'intel'`
|
|
5910
|
+
* - `auto` and `cpu` always shown
|
|
5911
|
+
*
|
|
5912
|
+
* onnx:
|
|
5913
|
+
* - `cuda` only when `hardware.gpu?.type === 'nvidia'`
|
|
5914
|
+
* - `coreml` only when `hardware.npu?.type === 'apple-ane'` (CoreML EP)
|
|
5915
|
+
* - `cpu` always shown
|
|
5916
|
+
*
|
|
5917
|
+
* When `hardware` is null (probe unreachable), the full catalog is returned
|
|
5918
|
+
* unchanged so the UI still renders all options.
|
|
5919
|
+
*/
|
|
5920
|
+
function filterDeviceOptionsByHardware(options, backend, hardware) {
|
|
5921
|
+
if (!hardware) return options;
|
|
5922
|
+
const hasAppleAne = hardware.npu?.type === "apple-ane";
|
|
5923
|
+
const hasIntelNpu = hardware.npu?.type === "intel-npu";
|
|
5924
|
+
const hasIntelGpu = hardware.gpu?.type === "intel";
|
|
5925
|
+
const hasNvidiaGpu = hardware.gpu?.type === "nvidia";
|
|
5926
|
+
switch (backend) {
|
|
5927
|
+
case "coreml": return options.filter((o) => {
|
|
5928
|
+
if (o.value === "ane") return hasAppleAne;
|
|
5929
|
+
return true;
|
|
5930
|
+
});
|
|
5931
|
+
case "openvino": return options.filter((o) => {
|
|
5932
|
+
if (o.value === "npu") return hasIntelNpu;
|
|
5933
|
+
if (o.value === "gpu") return hasIntelGpu;
|
|
5934
|
+
return true;
|
|
5935
|
+
});
|
|
5936
|
+
case "onnx": return options.filter((o) => {
|
|
5937
|
+
if (o.value === "cuda") return hasNvidiaGpu;
|
|
5938
|
+
if (o.value === "coreml") return hasAppleAne;
|
|
5939
|
+
return true;
|
|
5940
|
+
});
|
|
5941
|
+
default: return options;
|
|
5942
|
+
}
|
|
5943
|
+
}
|
|
5770
5944
|
var BACKEND_TO_FORMAT = {
|
|
5771
5945
|
cpu: "onnx",
|
|
5772
5946
|
coreml: "coreml",
|
|
@@ -5898,13 +6072,13 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
5898
6072
|
title: "Object detection",
|
|
5899
6073
|
tab: "engine",
|
|
5900
6074
|
order: 0,
|
|
5901
|
-
description: "Vision-detection
|
|
6075
|
+
description: "Vision-detection execution provider (object detection, face detection, plate OCR). Inference always runs via the embedded Python runtime. Provider and hardware options are gated by what the platform probe reports as available on this host. Changes restart the addon.",
|
|
5902
6076
|
fields: [
|
|
5903
6077
|
this.field({
|
|
5904
6078
|
type: "text",
|
|
5905
6079
|
key: "probedBestEngine",
|
|
5906
6080
|
label: "Probed best",
|
|
5907
|
-
description: "Auto-detected best engine for this host (format:
|
|
6081
|
+
description: "Auto-detected best engine for this host (format: provider/device, e.g. \"openvino/npu\"). Click the refresh icon to re-run the probe — the detected provider and hardware device are written back into the two fields below, overwriting any manual override.",
|
|
5908
6082
|
readonlyField: true,
|
|
5909
6083
|
default: "",
|
|
5910
6084
|
actions: [{
|
|
@@ -5913,19 +6087,10 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
5913
6087
|
tooltip: "Re-probe engine"
|
|
5914
6088
|
}]
|
|
5915
6089
|
}),
|
|
5916
|
-
this.field({
|
|
5917
|
-
type: "select",
|
|
5918
|
-
key: "engineRuntime",
|
|
5919
|
-
label: "Runtime",
|
|
5920
|
-
options: [...RUNTIMES],
|
|
5921
|
-
default: DEFAULT_CONFIG.engineRuntime,
|
|
5922
|
-
immediate: true,
|
|
5923
|
-
requiresRestart: true
|
|
5924
|
-
}),
|
|
5925
6090
|
this.field({
|
|
5926
6091
|
type: "select",
|
|
5927
6092
|
key: "engineBackend",
|
|
5928
|
-
label: "
|
|
6093
|
+
label: "Execution provider",
|
|
5929
6094
|
options: [...BACKENDS_BY_RUNTIME.python],
|
|
5930
6095
|
default: DEFAULT_CONFIG.engineBackend,
|
|
5931
6096
|
immediate: true,
|
|
@@ -6063,14 +6228,16 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6063
6228
|
...overlay
|
|
6064
6229
|
} : stored;
|
|
6065
6230
|
const runtime = "python";
|
|
6066
|
-
const
|
|
6231
|
+
const probeResult = await this.resolveProbeData(ctx, runtime);
|
|
6232
|
+
const availableBackends = probeResult.availableBackends;
|
|
6233
|
+
const hardware = probeResult.hardware;
|
|
6067
6234
|
const runtimeBackends = availableBackends.length > 0 ? BACKENDS_BY_RUNTIME[runtime].filter((b) => availableBackends.includes(b.value)) : BACKENDS_BY_RUNTIME[runtime];
|
|
6068
6235
|
const storedBackend = typeof merged.engineBackend === "string" ? merged.engineBackend : "";
|
|
6069
|
-
const backend = runtimeBackends.find((b) => b.value === storedBackend)?.value ?? runtimeBackends[0]?.value ?? "coreml";
|
|
6070
|
-
const deviceOptions = DEVICES_BY_BACKEND[backend] ?? [{
|
|
6236
|
+
const backend = runtimeBackends.find((b) => b.value === storedBackend)?.value ?? probeResult.bestBackend ?? runtimeBackends[0]?.value ?? "coreml";
|
|
6237
|
+
const deviceOptions = filterDeviceOptionsByHardware(DEVICES_BY_BACKEND[backend] ?? [{
|
|
6071
6238
|
value: "cpu",
|
|
6072
6239
|
label: "CPU"
|
|
6073
|
-
}];
|
|
6240
|
+
}], backend, hardware);
|
|
6074
6241
|
const storedDevice = typeof merged.engineDevice === "string" ? merged.engineDevice : "";
|
|
6075
6242
|
const device = deviceOptions.find((d) => d.value === storedDevice)?.value ?? deviceOptions[0]?.value ?? "cpu";
|
|
6076
6243
|
const raw = {
|
|
@@ -6120,28 +6287,47 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6120
6287
|
}, raw);
|
|
6121
6288
|
}
|
|
6122
6289
|
/**
|
|
6123
|
-
*
|
|
6124
|
-
*
|
|
6125
|
-
*
|
|
6126
|
-
*
|
|
6127
|
-
*
|
|
6128
|
-
*
|
|
6290
|
+
* Fetch the platform-probe capabilities and return:
|
|
6291
|
+
* - `availableBackends`: backends the probe reports as available for `runtime`
|
|
6292
|
+
* (empty → caller falls back to full catalog).
|
|
6293
|
+
* - `hardware`: the probed hardware info (null when probe not reachable).
|
|
6294
|
+
* - `bestBackend`: the backend from the probe's `bestScore` (null when unavailable).
|
|
6295
|
+
*
|
|
6296
|
+
* A single probe call is made so both backend AND device gating use the
|
|
6297
|
+
* same snapshot without doubling the cap round-trip.
|
|
6129
6298
|
*/
|
|
6130
|
-
async
|
|
6299
|
+
async resolveProbeData(ctx, runtime) {
|
|
6131
6300
|
try {
|
|
6132
6301
|
const api = ctx?.api;
|
|
6133
|
-
if (!api) return
|
|
6302
|
+
if (!api) return {
|
|
6303
|
+
availableBackends: [],
|
|
6304
|
+
hardware: null,
|
|
6305
|
+
bestBackend: null
|
|
6306
|
+
};
|
|
6134
6307
|
const caps = await api.platformProbe.getCapabilities.query();
|
|
6135
|
-
if (!caps?.scores) return
|
|
6308
|
+
if (!caps?.scores) return {
|
|
6309
|
+
availableBackends: [],
|
|
6310
|
+
hardware: null,
|
|
6311
|
+
bestBackend: null
|
|
6312
|
+
};
|
|
6136
6313
|
const out = /* @__PURE__ */ new Set();
|
|
6137
6314
|
for (const s of caps.scores) {
|
|
6138
6315
|
if (s.runtime !== runtime) continue;
|
|
6139
6316
|
if (!s.available) continue;
|
|
6140
6317
|
out.add(s.backend);
|
|
6141
6318
|
}
|
|
6142
|
-
|
|
6319
|
+
const bestBackend = caps.bestScore?.runtime === runtime ? caps.bestScore.backend ?? null : null;
|
|
6320
|
+
return {
|
|
6321
|
+
availableBackends: [...out],
|
|
6322
|
+
hardware: caps.hardware ?? null,
|
|
6323
|
+
bestBackend
|
|
6324
|
+
};
|
|
6143
6325
|
} catch {
|
|
6144
|
-
return
|
|
6326
|
+
return {
|
|
6327
|
+
availableBackends: [],
|
|
6328
|
+
hardware: null,
|
|
6329
|
+
bestBackend: null
|
|
6330
|
+
};
|
|
6145
6331
|
}
|
|
6146
6332
|
}
|
|
6147
6333
|
/**
|
|
@@ -6182,6 +6368,7 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6182
6368
|
const pythonPath = await this.ctx.deps.ensurePython();
|
|
6183
6369
|
if (pythonPath) this.pythonPath = pythonPath;
|
|
6184
6370
|
else this.ctx.logger.warn("Embedded Python unavailable — runtime=\"python\" pipelines will fail until the download succeeds.");
|
|
6371
|
+
await this.proactivelyInstallOpenvino();
|
|
6185
6372
|
const effectiveTuning = this.resolveBackendTuning();
|
|
6186
6373
|
this.provider = new DetectionPipelineProvider(this.ctx.settings, modelsDir, this.ctx.logger, this.ctx.eventBus ?? null, () => ({ sections: [] }), {
|
|
6187
6374
|
concurrency: effectiveTuning.concurrency,
|
|
@@ -6247,6 +6434,32 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6247
6434
|
getModelCatalog() {
|
|
6248
6435
|
return ALL_STEPS.flatMap((s) => [...s.models]);
|
|
6249
6436
|
}
|
|
6437
|
+
/**
|
|
6438
|
+
* Proactively install the OpenVINO Python package when Intel hardware
|
|
6439
|
+
* (iGPU or NPU) is detected. Called once from `onInitialize`, before the
|
|
6440
|
+
* provider is constructed, so the module is available when the platform
|
|
6441
|
+
* probe runs its next `import openvino.runtime` check.
|
|
6442
|
+
*
|
|
6443
|
+
* Failure is non-fatal: a warning is logged and the addon continues with
|
|
6444
|
+
* the onnx-cpu baseline. The hardware query itself is also best-effort —
|
|
6445
|
+
* if the platform-probe cap isn't wired yet the error is caught here.
|
|
6446
|
+
*/
|
|
6447
|
+
async proactivelyInstallOpenvino() {
|
|
6448
|
+
if (!this.pythonAddonDir || !this.pythonPath) return;
|
|
6449
|
+
try {
|
|
6450
|
+
const hardware = await this.ctx.api.platformProbe.getHardware.query();
|
|
6451
|
+
if (!shouldInstallOpenvino(hardware)) return;
|
|
6452
|
+
this.ctx.logger.info("Intel hardware detected — proactively installing OpenVINO Python package", { meta: {
|
|
6453
|
+
gpu: hardware.gpu?.type ?? null,
|
|
6454
|
+
npu: hardware.npu?.type ?? null
|
|
6455
|
+
} });
|
|
6456
|
+
const requirementsFile = path$1.join(this.pythonAddonDir, "requirements-openvino.txt");
|
|
6457
|
+
await this.ctx.deps.installPythonRequirements(requirementsFile);
|
|
6458
|
+
this.ctx.logger.info("Proactive OpenVINO install complete");
|
|
6459
|
+
} catch (err) {
|
|
6460
|
+
this.ctx.logger.warn("Proactive OpenVINO install failed — falling back to onnx-cpu baseline", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
6461
|
+
}
|
|
6462
|
+
}
|
|
6250
6463
|
async onShutdown() {
|
|
6251
6464
|
if (this.engineMetricsTimer) {
|
|
6252
6465
|
clearInterval(this.engineMetricsTimer);
|
|
@@ -6335,4 +6548,4 @@ var DetectionPipelineAddon = class extends BaseAddon {
|
|
|
6335
6548
|
}
|
|
6336
6549
|
};
|
|
6337
6550
|
//#endregion
|
|
6338
|
-
export { ALL_STEPS, DetectionPipelineProvider, backendToFormat, DetectionPipelineAddon as default, getDefaultModelForFormat, getStepDefinition };
|
|
6551
|
+
export { ALL_STEPS, DetectionPipelineProvider, backendToFormat, DetectionPipelineAddon as default, filterDeviceOptionsByHardware, 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) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as e, i as t, n, o as r, r as i, t as a } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.js-C9j-2lBe.mjs";
|
|
2
|
-
import { a as o, c as s, i as c, l, n as u, o as d, r as f, s as p, t as m, u as h } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-
|
|
2
|
+
import { a as o, c as s, i as c, l, n as u, o as d, r as f, s as p, t as m, u as h } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B0Z2W5UM.mjs";
|
|
3
3
|
import { n as g, r as _, t as v } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-XO0-Pyu6.mjs";
|
|
4
4
|
import { n as y, t as b } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-BO7TIbJV.mjs";
|
|
5
5
|
import { t as x } from "./_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Tf-HACFd.mjs";
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.0.
|
|
6
|
+
version: "1.0.3",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.0.
|
|
21
|
+
version: "1.0.3",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.0.
|
|
36
|
+
version: "1.0.3",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|