@camstack/addon-pipeline 1.1.45 → 1.1.46

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 (30) hide show
  1. package/dist/audio-analyzer/index.js +1 -1
  2. package/dist/audio-analyzer/index.mjs +1 -1
  3. package/dist/detection-pipeline/index.js +78 -231
  4. package/dist/detection-pipeline/index.mjs +78 -231
  5. package/dist/{dist-D04numuO.mjs → dist-Bglbcd7H.mjs} +57 -96
  6. package/dist/{dist-CjxqjgEv.js → dist-C3CWl8fV.js} +57 -96
  7. package/dist/motion-wasm/index.js +1 -1
  8. package/dist/motion-wasm/index.mjs +1 -1
  9. package/dist/pipeline-runner/index.js +2 -2
  10. package/dist/pipeline-runner/index.mjs +2 -2
  11. package/dist/recorder/index.js +1 -1
  12. package/dist/recorder/index.mjs +1 -1
  13. package/dist/{remote-source-plane-D31IILFN.mjs → remote-source-plane-BrFvA0nx.mjs} +1 -1
  14. package/dist/{remote-source-plane-CLuxyDV2.js → remote-source-plane-C05A2DHs.js} +1 -1
  15. package/dist/stream-broker/_stub.js +2 -2
  16. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BGKueo9D.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BGyNZqVy.mjs} +2 -2
  17. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-UM9hXKco.mjs +26 -0
  18. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-8BUVCFIR.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-iB6N_WVh.mjs} +1 -1
  19. package/dist/stream-broker/{hostInit-DazV2RCq.mjs → hostInit-uMl2Tcss.mjs} +2 -2
  20. package/dist/stream-broker/index.js +49 -3
  21. package/dist/stream-broker/index.mjs +49 -3
  22. package/dist/stream-broker/remoteEntry.js +1 -1
  23. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-D_F4a_3H.js → MaskShapeCanvas-DI4BY7W2-DvRngVr4.js} +1 -1
  24. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CfTBrn4G.js → MotionZonesSettings-NcxxQN8r-ByQeOu3_.js} +1 -1
  25. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BWYkeoRj.js → PrivacyMaskSettings-APgPLF7p-Cs5XlrlU.js} +1 -1
  26. package/embed-dist/assets/{index-CA4kv43T.css → index-JqUY2p33.css} +1 -1
  27. package/embed-dist/assets/{index-_ccEdNW7.js → index-RqzZkNA8.js} +10 -10
  28. package/embed-dist/index.html +2 -2
  29. package/package.json +1 -1
  30. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D0sKyXiy.mjs +0 -26
@@ -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-CjxqjgEv.js");
6
+ const require_dist = require("../dist-C3CWl8fV.js");
7
7
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
8
8
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BLXzxpRB.js");
9
9
  let node_fs = require("node:fs");
@@ -1,5 +1,5 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { C as mapAudioLabelToMacro, I as errMsg, L as BaseAddon, U as hydrateSchema, h as audioAnalyzerCapability, l as HF_BASE_URL, m as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG } from "../dist-D04numuO.mjs";
2
+ import { C as mapAudioLabelToMacro, I as errMsg, L as BaseAddon, U as hydrateSchema, h as audioAnalyzerCapability, l as HF_BASE_URL, m as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG } from "../dist-Bglbcd7H.mjs";
3
3
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
4
4
  import { r as downloadFile } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
5
5
  import * as fs from "node:fs";
@@ -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-CjxqjgEv.js");
6
+ const require_dist = require("../dist-C3CWl8fV.js");
7
7
  const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
8
8
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BLXzxpRB.js");
9
9
  let _camstack_shm_ring = require("@camstack/shm-ring");
@@ -4552,6 +4552,12 @@ function collectUnknownAddonIssues(steps, getStepDef = getStepDefinition) {
4552
4552
  * `PipelineDefaultStep[]` (the catalog-enriched shape the executor consumes),
4553
4553
  * resolving each step's model for `format` via `resolveModelForFormat`.
4554
4554
  *
4555
+ * "Auto" model selection (ABSENT `modelId`) is hardware-aware for the
4556
+ * object-detection step when `engine` is provided: the default is resolved
4557
+ * via `resolveDefaultDetectionModel(engine.backend, engine.device, format)`.
4558
+ * A PINNED `modelId` is kept verbatim (subject to the usual format-build
4559
+ * substitution); every other step keeps its flat per-format default.
4560
+ *
4555
4561
  * Pure and side-effect-free — never throws. This is the seam behind the
4556
4562
  * LIVE per-camera dispatch path (`DetectionPipelineProvider.
4557
4563
  * inputStepsToPipelineSteps`), which runs once per decoded frame (up to
@@ -4562,7 +4568,7 @@ function collectUnknownAddonIssues(steps, getStepDef = getStepDefinition) {
4562
4568
  * `diagnostics.substitutions` instead of happening silently. The caller
4563
4569
  * (the provider) owns logging + dedup for both.
4564
4570
  */
4565
- function resolveInputSteps(steps, format) {
4571
+ function resolveInputSteps(steps, format, engine) {
4566
4572
  const resolvedSteps = [];
4567
4573
  const unknownAddonIds = [];
4568
4574
  const substitutions = [];
@@ -4575,14 +4581,14 @@ function resolveInputSteps(steps, format) {
4575
4581
  continue;
4576
4582
  }
4577
4583
  const chosenModelId = s.modelId ?? null;
4578
- const runningModelId = resolveModelForFormat(s.addonId, chosenModelId, format);
4584
+ const runningModelId = chosenModelId === null && engine !== void 0 && s.addonId === "object-detection" ? resolveDefaultDetectionModel(engine.backend, engine.device, format) : resolveModelForFormat(s.addonId, chosenModelId, format);
4579
4585
  if (chosenModelId !== null && runningModelId !== chosenModelId) substitutions.push({
4580
4586
  addonId: s.addonId,
4581
4587
  chosen: chosenModelId,
4582
4588
  running: runningModelId,
4583
4589
  format
4584
4590
  });
4585
- const childResult = s.children ? resolveInputSteps(s.children, format) : null;
4591
+ const childResult = s.children ? resolveInputSteps(s.children, format, engine) : null;
4586
4592
  if (childResult) {
4587
4593
  unknownAddonIds.push(...childResult.diagnostics.unknownAddonIds);
4588
4594
  substitutions.push(...childResult.diagnostics.substitutions);
@@ -4615,8 +4621,6 @@ function resolveInputSteps(steps, format) {
4615
4621
  * This is the main provider that consumers (DetectionWiring, Benchmark, tRPC)
4616
4622
  * interact with. It manages the engine factory, pipeline executor, and config persistence.
4617
4623
  */
4618
- var KEY_STEPS = "pipelineSteps";
4619
- var KEY_ENGINE = "pipelineEngine";
4620
4624
  var KEY_TEMPLATES = "pipelineTemplates";
4621
4625
  function pythonModuleForBackend(backend) {
4622
4626
  switch (backend) {
@@ -4699,14 +4703,6 @@ function readStored(raw, guard) {
4699
4703
  return null;
4700
4704
  }
4701
4705
  }
4702
- function isEngineChoice(v) {
4703
- if (v === null || typeof v !== "object" || Array.isArray(v)) return false;
4704
- const rec = { ...v };
4705
- return typeof rec["runtime"] === "string" && typeof rec["backend"] === "string" && typeof rec["format"] === "string";
4706
- }
4707
- function isPipelineStepArray(v) {
4708
- return Array.isArray(v);
4709
- }
4710
4706
  /**
4711
4707
  * Phase 7 (settings redesign) template migration.
4712
4708
  *
@@ -4923,13 +4919,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4923
4919
  */
4924
4920
  frameHandleReaders = null;
4925
4921
  /**
4926
- * True once the engine + models are fully ready for inference. No
4927
- * longer gates runtime dispatch (Phase 4 removed the legacy `runFrame`
4928
- * which read this flag); kept as a diagnostic the admin UI / tests
4929
- * surface via the future `isReady()` helper.
4930
- */
4931
- ready = false;
4932
- /**
4933
4922
  * Lazy detection-engine runtime provisioner (Phase 2). Owns the
4934
4923
  * idle → installing → verifying → ready state machine for the
4935
4924
  * currently-selected engine and is the SOLE authority the inference
@@ -4981,7 +4970,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4981
4970
  writeStore;
4982
4971
  /** Read per-device settings. */
4983
4972
  readDeviceStore;
4984
- /** Delete all per-device settings for a device (used by `resetToDefault`). */
4973
+ /** Delete all per-device settings for a device (used by `clearDeviceOverrides`). */
4985
4974
  clearDeviceStore;
4986
4975
  constructor(settings, modelsDir, logger, eventBus = null, detectionConfigSchemaSource = null, executorOptions = {}) {
4987
4976
  this.modelsDir = modelsDir;
@@ -5056,9 +5045,9 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5056
5045
  }
5057
5046
  await this.ensureEngineFactory();
5058
5047
  }
5059
- /** True when the engine + model pool are fully warmed and inference-ready. */
5048
+ /** True when the engine provisioning machine reports inference-ready. */
5060
5049
  isReady() {
5061
- return this.ready;
5050
+ return this.getEngineProvisioning().state === "ready";
5062
5051
  }
5063
5052
  /** Store the addon context. ctx.api is a lazy getter resolved at call time. */
5064
5053
  async setApi(addonCtx) {
@@ -5504,46 +5493,25 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5504
5493
  getActiveModelSubstitutions() {
5505
5494
  return [...this.modelSubstitutions.values()];
5506
5495
  }
5496
+ /**
5497
+ * PURE node-default step tree — computed on demand, never persisted.
5498
+ *
5499
+ * The object-detection default is hardware-aware (this node's resolved
5500
+ * backend + device via `resolveDefaultDetectionModel`); every other step
5501
+ * keeps its flat per-format default. The result is cached in
5502
+ * `currentSteps` only as a memo — the cache is dropped whenever the
5503
+ * engine (hence model format) changes, so a re-read always reflects the
5504
+ * live engine. Nothing in the live per-camera dispatch path reads this:
5505
+ * it exists as the benchmark fallback (empty input steps), the Gate-A
5506
+ * config-issue probe, and the "effective post-reset model" probe.
5507
+ */
5507
5508
  async getGlobalSteps() {
5508
5509
  if (this.currentSteps) return this.currentSteps;
5509
- const raw = (await this.readStore())[KEY_STEPS];
5510
- if (!raw) {
5511
- const detectionModelId = resolveDefaultDetectionModel(this.currentEngine.backend, this.currentEngine.device ?? null, this.currentEngine.format);
5512
- const defaults = buildDefaultStepTree(this.currentEngine.format, detectionModelId);
5513
- if (defaults.length === 0) return null;
5514
- this.currentSteps = this.resolveStepModels(defaults);
5515
- this.writeStore({ [KEY_STEPS]: JSON.stringify(defaults) });
5516
- this.log.info("Bootstrapped default pipeline — object-detection + face + plate recognition enabled by default", { meta: { rootSteps: defaults.length } });
5517
- return this.currentSteps;
5518
- }
5519
- try {
5520
- let steps = readStored(raw, isPipelineStepArray) ?? [];
5521
- if (steps.length === 0) return null;
5522
- if (!steps.some((s) => s.slot === "audio-classifier")) {
5523
- const format = this.currentEngine.format;
5524
- const audioDef = getStepDefinition("audio-classifier");
5525
- if (audioDef.models.some((m) => m.formats[format])) {
5526
- const modelId = getDefaultModelForFormat("audio-classifier", format);
5527
- const audioStep = {
5528
- addonId: audioDef.id,
5529
- addonName: audioDef.name,
5530
- slot: audioDef.slot,
5531
- inputClasses: audioDef.inputClasses ?? [],
5532
- outputClasses: audioDef.outputClasses,
5533
- enabled: true,
5534
- modelId,
5535
- children: []
5536
- };
5537
- steps = [...steps, audioStep];
5538
- this.writeStore({ [KEY_STEPS]: JSON.stringify(steps) });
5539
- this.log.info("Migration: added audio-classifier step to persisted pipeline config");
5540
- }
5541
- }
5542
- this.currentSteps = this.resolveStepModels(steps);
5543
- return this.currentSteps;
5544
- } catch {
5545
- throw new Error(`Failed to parse persisted pipeline steps: corrupt data in key "${KEY_STEPS}"`);
5546
- }
5510
+ const detectionModelId = resolveDefaultDetectionModel(this.currentEngine.backend, this.currentEngine.device ?? null, this.currentEngine.format);
5511
+ const defaults = buildDefaultStepTree(this.currentEngine.format, detectionModelId);
5512
+ if (defaults.length === 0) return null;
5513
+ this.currentSteps = this.resolveStepModels(defaults);
5514
+ return this.currentSteps;
5547
5515
  }
5548
5516
  async getGlobalPipelineConfig() {
5549
5517
  if (!this.currentSteps) return null;
@@ -5998,7 +5966,14 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5998
5966
  }
5999
5967
  decodeMs = performance.now() - decodeT0;
6000
5968
  const resolveFormat = input.engine?.format ?? this.currentEngine.format;
6001
- const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat);
5969
+ const resolveEngine = input.engine ? {
5970
+ backend: input.engine.backend,
5971
+ device: input.engine.device ?? null
5972
+ } : {
5973
+ backend: this.currentEngine.backend,
5974
+ device: this.currentEngine.device ?? null
5975
+ };
5976
+ const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat, resolveEngine);
6002
5977
  const stepsSignature = JSON.stringify(benchmarkSteps.map((s) => ({
6003
5978
  id: s.addonId,
6004
5979
  settings: s.settings ?? {}
@@ -6311,8 +6286,11 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6311
6286
  * would resolve models against the node's persisted format instead of the
6312
6287
  * format actually being benchmarked.
6313
6288
  */
6314
- inputStepsToPipelineSteps(steps, format = this.currentEngine.format) {
6315
- const { steps: resolvedSteps, diagnostics } = resolveInputSteps(steps, format);
6289
+ inputStepsToPipelineSteps(steps, format = this.currentEngine.format, engine = {
6290
+ backend: this.currentEngine.backend,
6291
+ device: this.currentEngine.device ?? null
6292
+ }) {
6293
+ const { steps: resolvedSteps, diagnostics } = resolveInputSteps(steps, format, engine);
6316
6294
  for (const addonId of diagnostics.unknownAddonIds) this.logLiveDispatchIssueOnce(`unknown:${addonId}`, () => this.log.warn("Live pipeline step references an unknown addon — dropping step", { meta: { addonId } }));
6317
6295
  for (const sub of diagnostics.substitutions) this.logLiveDispatchIssueOnce(`${sub.addonId}|${sub.chosen}|${sub.running}|${sub.format}`, () => this.log.info("Live pipeline step model substituted for engine format (node-local)", { meta: {
6318
6296
  step: sub.addonId,
@@ -6430,67 +6408,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6430
6408
  height: 640
6431
6409
  };
6432
6410
  }
6433
- async detect(input) {
6434
- const { addonId, frame } = input;
6435
- const { executor, tree } = await this.ensureExecutor();
6436
- const data = Buffer.from(frame.data);
6437
- let rootInput;
6438
- let jpegProvider;
6439
- if (frame.format === "jpeg") {
6440
- rootInput = {
6441
- kind: "jpeg",
6442
- data
6443
- };
6444
- jpegProvider = async () => data;
6445
- } else if (frame.format === "rgb" || frame.format === "bgr" || frame.format === "gray") {
6446
- const channels = frame.format === "gray" ? 1 : 3;
6447
- const sharp$6 = (await import("sharp")).default;
6448
- const jpeg = await sharp$6(data, { raw: {
6449
- width: frame.width,
6450
- height: frame.height,
6451
- channels
6452
- } }).jpeg({
6453
- quality: 85,
6454
- mozjpeg: false
6455
- }).toBuffer();
6456
- rootInput = {
6457
- kind: "jpeg",
6458
- data: jpeg
6459
- };
6460
- jpegProvider = async () => jpeg;
6461
- } else {
6462
- const sharp$7 = (await import("sharp")).default;
6463
- const encoded = await sharp$7(data, { raw: {
6464
- width: frame.width,
6465
- height: frame.height,
6466
- channels: 3
6467
- } }).jpeg({
6468
- quality: 80,
6469
- mozjpeg: false
6470
- }).toBuffer();
6471
- rootInput = {
6472
- kind: "jpeg",
6473
- data: encoded
6474
- };
6475
- jpegProvider = async () => encoded;
6476
- }
6477
- const { result } = await executor.run(tree, rootInput, jpegProvider, frame.width, frame.height, 0);
6478
- return {
6479
- detections: result.detections.filter((d) => d.kind === "first-level").map((d) => ({
6480
- class: d.macroClass,
6481
- originalClass: d.debug?.originalClass ?? d.macroClass,
6482
- score: d.score,
6483
- bbox: {
6484
- x: d.bbox.x,
6485
- y: d.bbox.y,
6486
- w: d.bbox.width,
6487
- h: d.bbox.height
6488
- }
6489
- })),
6490
- inferenceMs: result.debug?.totalInferenceMs ?? 0,
6491
- modelId: addonId
6492
- };
6493
- }
6494
6411
  /**
6495
6412
  * Batched run — dispatches N raw frames against the same loaded
6496
6413
  * single-step model in one IPC round-trip via
@@ -6533,7 +6450,14 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6533
6450
  async runPipelineBatchImpl(input) {
6534
6451
  if (input.frames.length === 0) return { results: [] };
6535
6452
  const resolveFormat = input.engine?.format ?? this.currentEngine.format;
6536
- const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat);
6453
+ const resolveEngine = input.engine ? {
6454
+ backend: input.engine.backend,
6455
+ device: input.engine.device ?? null
6456
+ } : {
6457
+ backend: this.currentEngine.backend,
6458
+ device: this.currentEngine.device ?? null
6459
+ };
6460
+ const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat, resolveEngine);
6537
6461
  const enabledSteps = flattenEnabledVideoSteps(benchmarkSteps);
6538
6462
  if (enabledSteps.length === 0) throw new Error("runPipelineBatch: no enabled steps");
6539
6463
  const rootStep = enabledSteps[0];
@@ -6825,71 +6749,11 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6825
6749
  });
6826
6750
  await this.engineFactory.initialize([]);
6827
6751
  }
6828
- async ensureExecutor() {
6829
- if (this.initPromise) await this.initPromise;
6830
- if (!this.engineFactory) {
6831
- await this.assertEngineReady();
6832
- this.initPromise = this.doInitialize();
6833
- try {
6834
- await this.initPromise;
6835
- } finally {
6836
- this.initPromise = null;
6837
- }
6838
- }
6839
- if (!this.currentSteps) throw new Error("No pipeline steps configured");
6840
- const tree = buildExecutableTree(this.currentSteps, (stepId) => this.engineFactory.getEngine(stepId));
6841
- return {
6842
- executor: this.executor,
6843
- tree
6844
- };
6845
- }
6846
- /** Actual initialization — download models, create engine, load pool. Called once. */
6847
- async doInitialize() {
6848
- const steps = await this.getGlobalSteps();
6849
- if (!steps) throw new Error("No pipeline steps configured. Use setGlobalSteps() first.");
6850
- this.log.info("Pipeline initializing — frames will be dropped until ready");
6851
- const format = this.currentEngine.format;
6852
- const downloads = [];
6853
- for (const step of flattenSteps(steps)) {
6854
- const modelEntry = await this.resolveModelEntry(step.addonId, step.modelId);
6855
- if (!modelEntry) {
6856
- this.log.warn("Model not found in step catalog — skipping download", { meta: {
6857
- modelId: step.modelId,
6858
- step: step.addonId
6859
- } });
6860
- continue;
6861
- }
6862
- if (!require_model_download_service_C_IHWnXx.isModelDownloaded(this.modelsDir, modelEntry, format)) this.log.info("Downloading model", { meta: {
6863
- modelId: step.modelId,
6864
- format
6865
- } });
6866
- downloads.push(require_model_download_service_C_IHWnXx.ensureModel(this.modelsDir, modelEntry, format).then(() => {}));
6867
- }
6868
- await Promise.all(downloads);
6869
- await this.ensureBackendDeps(this.currentEngine);
6870
- this.engineFactory = new EngineFactory({
6871
- engine: this.currentEngine,
6872
- modelsDir: this.modelsDir,
6873
- logger: this.log.child("engine"),
6874
- pythonPath: this.executorOptions.pythonPath ?? "",
6875
- concurrency: this.executorOptions.concurrency,
6876
- tuning: this.executorOptions.tuning,
6877
- numWorkers: this.executorOptions.numWorkers
6878
- });
6879
- await this.engineFactory.initialize(steps);
6880
- this.currentSteps = steps;
6881
- const runtimeStr = `${this.currentEngine.runtime}+${this.currentEngine.backend}`;
6882
- this.executor = new PipelineExecutor({
6883
- engineRuntime: runtimeStr,
6884
- logger: this.log
6885
- });
6886
- this.ready = true;
6887
- this.log.info("Pipeline ready — accepting frames");
6888
- }
6889
6752
  /**
6890
6753
  * Phase 2b — resolve the engine from the addon's new schema-backed
6891
- * fields (`engineRuntime`, `engineBackend`, `engineDevice`). Fallback
6892
- * to the legacy `KEY_ENGINE` JSON blob for pre-migration stores.
6754
+ * fields (`engineRuntime`, `engineBackend`, `engineDevice`). The legacy
6755
+ * `pipelineEngine` JSON-blob fallback was removed with the executor seed
6756
+ * (any store predating the per-node cascade simply re-runs auto-pick).
6893
6757
  *
6894
6758
  * The `'auto'` sentinel is treated as NO override (returns null) so the
6895
6759
  * caller re-resolves LIVE via `resolveAutoEngine()` — `'auto'` is the
@@ -6932,8 +6796,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6932
6796
  ...device ? { device } : {}
6933
6797
  };
6934
6798
  }
6935
- const raw = store[KEY_ENGINE];
6936
- return readStored(raw, isEngineChoice);
6799
+ return null;
6937
6800
  }
6938
6801
  /**
6939
6802
  * Re-run the platform probe for the inference engine and persist the
@@ -6983,48 +6846,29 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6983
6846
  return { success: true };
6984
6847
  }
6985
6848
  /**
6986
- * Reset THIS node's detection-pipeline to its factory defaults, forcing
6987
- * regeneration of the hardware-aware default object-detection model.
6849
+ * Clear THIS node's executor-side PER-DEVICE settings stores the
6850
+ * per-camera step overrides the object-detection root reads via
6851
+ * `applyDeviceOverridesToTree`.
6988
6852
  *
6989
6853
  * Node-routed (the cap's default `nodeIdMode: 'routing'`): the generated
6990
6854
  * cap-router strips `nodeId` and dispatches to the target node, so this
6991
- * method runs ON the node being reset and takes no argument.
6855
+ * method runs ON the node being cleared and takes no argument.
6992
6856
  *
6993
- * Clears three things:
6994
- * 1. the persisted GLOBAL pipeline seed (`KEY_STEPS`)nulled in the
6995
- * store AND the in-memory `currentSteps` cache, so the subsequent
6996
- * `getGlobalSteps()` re-seeds the hardware-aware default tree fresh
6997
- * (`resolveDefaultDetectionModel` against this node's live engine)
6998
- * rather than returning the stale cached blob.
6999
- * 2. the LEGACY engine blob (`KEY_ENGINE`). The per-node engine cascade
7000
- * (`engineBackend@<node>` / `engineDevice@<node>`) is intentionally
7001
- * left intact — the operator's engine selection is preserved and the
7002
- * default is regenerated against it.
7003
- * 3. every device's PER-CAMERA step overrides (the per-device store the
7004
- * object-detection root reads via `applyDeviceOverridesToTree`).
6857
+ * This is the slimmed executor leg of the orchestrator's
6858
+ * `resetNodePipelineDefaults` flow. The legacy `resetToDefault` — which
6859
+ * also reset a persisted GLOBAL step-tree seed nothing in the live
6860
+ * per-camera path read was removed together with that seed
6861
+ * (`getGlobalSteps` is pure now, so there is nothing node-global left to
6862
+ * reset here).
7005
6863
  *
7006
- * Idempotent: a second call re-seeds the identical default and clears
7007
- * already-empty per-device stores harmlessly. Returns the regenerated
7008
- * object-detection model id (null when the default tree has no detector
7009
- * for this node's format).
6864
+ * Idempotent: clearing already-empty per-device stores is a no-op.
7010
6865
  */
7011
- async resetToDefault() {
7012
- await this.writeStore({
7013
- [KEY_STEPS]: null,
7014
- [KEY_ENGINE]: null
7015
- });
7016
- this.currentSteps = null;
6866
+ async clearDeviceOverrides() {
7017
6867
  const clearedDevices = await this.clearAllDeviceOverrides();
7018
- const regeneratedModelId = ((await this.getGlobalSteps())?.find((s) => s.slot === "detector") ?? null)?.modelId ?? null;
7019
- this.log.info("pipeline reset to default", { meta: {
7020
- clearedGlobalSteps: true,
7021
- clearedEngineBlob: true,
7022
- clearedDeviceOverrides: clearedDevices,
7023
- regeneratedModelId
7024
- } });
6868
+ this.log.info("executor per-device overrides cleared", { meta: { clearedDevices } });
7025
6869
  return {
7026
6870
  success: true,
7027
- regeneratedModelId
6871
+ clearedDevices
7028
6872
  };
7029
6873
  }
7030
6874
  /**
@@ -7034,7 +6878,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7034
6878
  * enumerated via the device-manager and cleared one by one
7035
6879
  * (`clearDeviceStore` is idempotent — a device with no overrides is a
7036
6880
  * no-op). Never throws: a device-manager outage degrades to "cleared
7037
- * nothing" so the global reset still completes.
6881
+ * nothing" so the reset flow still completes.
7038
6882
  */
7039
6883
  async clearAllDeviceOverrides() {
7040
6884
  const api = this.addonCtx?.api;
@@ -7043,7 +6887,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7043
6887
  try {
7044
6888
  devices = await api.deviceManager.listAll.query({});
7045
6889
  } catch (err) {
7046
- this.log.warn("resetToDefault: device enumeration failed — skipping per-device clear", { meta: { error: require_dist.errMsg(err) } });
6890
+ this.log.warn("clearDeviceOverrides: device enumeration failed — skipping per-device clear", { meta: { error: require_dist.errMsg(err) } });
7047
6891
  return 0;
7048
6892
  }
7049
6893
  let cleared = 0;
@@ -7051,10 +6895,13 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7051
6895
  await this.clearDeviceStore(device.id);
7052
6896
  cleared++;
7053
6897
  } catch (err) {
7054
- this.log.warn("resetToDefault: failed to clear per-device overrides for device", { meta: {
7055
- deviceId: device.id,
7056
- error: require_dist.errMsg(err)
7057
- } });
6898
+ this.log.warn("clearDeviceOverrides: failed to clear per-device overrides for device", {
6899
+ tags: { deviceId: device.id },
6900
+ meta: {
6901
+ deviceId: device.id,
6902
+ error: require_dist.errMsg(err)
6903
+ }
6904
+ });
7058
6905
  }
7059
6906
  return cleared;
7060
6907
  }