@camstack/addon-pipeline 1.1.45 → 1.1.47

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-BXax-C-g.mjs} +316 -101
  6. package/dist/{dist-CjxqjgEv.js → dist-CSXbgmP-.js} +316 -101
  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 +24 -8
  10. package/dist/pipeline-runner/index.mjs +24 -8
  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-D9mX0HiW.mjs} +1 -1
  14. package/dist/{remote-source-plane-CLuxyDV2.js → remote-source-plane-Rbl_xds1.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-Dz7jhO6c.mjs} +3 -3
  17. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-o4tu_xuc.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-CK4BmiTK.mjs} +1 -1
  19. package/dist/stream-broker/{hostInit-DazV2RCq.mjs → hostInit-DcMnvklS.mjs} +3 -3
  20. package/dist/stream-broker/index.js +79 -18
  21. package/dist/stream-broker/index.mjs +79 -18
  22. package/dist/stream-broker/remoteEntry.js +1 -1
  23. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-D_F4a_3H.js → MaskShapeCanvas-DI4BY7W2-BSSjCL6j.js} +1 -1
  24. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CfTBrn4G.js → MotionZonesSettings-NcxxQN8r-BDb2ziPs.js} +1 -1
  25. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BWYkeoRj.js → PrivacyMaskSettings-APgPLF7p-ARYovxqE.js} +1 -1
  26. package/embed-dist/assets/{index-_ccEdNW7.js → index-ByiLuUQZ.js} +10 -10
  27. package/embed-dist/assets/{index-CA4kv43T.css → index-JqUY2p33.css} +1 -1
  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
@@ -1,5 +1,5 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { H as createEvent, I as errMsg, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, S as hfModelUrl, U as hydrateSchema, V as EventCategory, X as sleep, a as COCO_TO_MACRO, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, i as COCO_80_LABELS, j as runtimeDevices$1, q as parseJsonUnknown, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-D04numuO.mjs";
2
+ import { H as createEvent, I as errMsg, L as BaseAddon, O as pipelineExecutorCapability, P as supportedRuntimes$1, S as hfModelUrl, U as hydrateSchema, V as EventCategory, X as sleep, a as COCO_TO_MACRO, b as detectionPipelineCapability, f as YAMNET_TO_MACRO, i as COCO_80_LABELS, j as runtimeDevices$1, q as parseJsonUnknown, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, v as defaultDeviceFor$1, x as evaluateZoneRules } from "../dist-BXax-C-g.mjs";
3
3
  import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
4
4
  import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
5
5
  import { FrameRingReaderCache } from "@camstack/shm-ring";
@@ -4544,6 +4544,12 @@ function collectUnknownAddonIssues(steps, getStepDef = getStepDefinition) {
4544
4544
  * `PipelineDefaultStep[]` (the catalog-enriched shape the executor consumes),
4545
4545
  * resolving each step's model for `format` via `resolveModelForFormat`.
4546
4546
  *
4547
+ * "Auto" model selection (ABSENT `modelId`) is hardware-aware for the
4548
+ * object-detection step when `engine` is provided: the default is resolved
4549
+ * via `resolveDefaultDetectionModel(engine.backend, engine.device, format)`.
4550
+ * A PINNED `modelId` is kept verbatim (subject to the usual format-build
4551
+ * substitution); every other step keeps its flat per-format default.
4552
+ *
4547
4553
  * Pure and side-effect-free — never throws. This is the seam behind the
4548
4554
  * LIVE per-camera dispatch path (`DetectionPipelineProvider.
4549
4555
  * inputStepsToPipelineSteps`), which runs once per decoded frame (up to
@@ -4554,7 +4560,7 @@ function collectUnknownAddonIssues(steps, getStepDef = getStepDefinition) {
4554
4560
  * `diagnostics.substitutions` instead of happening silently. The caller
4555
4561
  * (the provider) owns logging + dedup for both.
4556
4562
  */
4557
- function resolveInputSteps(steps, format) {
4563
+ function resolveInputSteps(steps, format, engine) {
4558
4564
  const resolvedSteps = [];
4559
4565
  const unknownAddonIds = [];
4560
4566
  const substitutions = [];
@@ -4567,14 +4573,14 @@ function resolveInputSteps(steps, format) {
4567
4573
  continue;
4568
4574
  }
4569
4575
  const chosenModelId = s.modelId ?? null;
4570
- const runningModelId = resolveModelForFormat(s.addonId, chosenModelId, format);
4576
+ const runningModelId = chosenModelId === null && engine !== void 0 && s.addonId === "object-detection" ? resolveDefaultDetectionModel(engine.backend, engine.device, format) : resolveModelForFormat(s.addonId, chosenModelId, format);
4571
4577
  if (chosenModelId !== null && runningModelId !== chosenModelId) substitutions.push({
4572
4578
  addonId: s.addonId,
4573
4579
  chosen: chosenModelId,
4574
4580
  running: runningModelId,
4575
4581
  format
4576
4582
  });
4577
- const childResult = s.children ? resolveInputSteps(s.children, format) : null;
4583
+ const childResult = s.children ? resolveInputSteps(s.children, format, engine) : null;
4578
4584
  if (childResult) {
4579
4585
  unknownAddonIds.push(...childResult.diagnostics.unknownAddonIds);
4580
4586
  substitutions.push(...childResult.diagnostics.substitutions);
@@ -4607,8 +4613,6 @@ function resolveInputSteps(steps, format) {
4607
4613
  * This is the main provider that consumers (DetectionWiring, Benchmark, tRPC)
4608
4614
  * interact with. It manages the engine factory, pipeline executor, and config persistence.
4609
4615
  */
4610
- var KEY_STEPS = "pipelineSteps";
4611
- var KEY_ENGINE = "pipelineEngine";
4612
4616
  var KEY_TEMPLATES = "pipelineTemplates";
4613
4617
  function pythonModuleForBackend(backend) {
4614
4618
  switch (backend) {
@@ -4691,14 +4695,6 @@ function readStored(raw, guard) {
4691
4695
  return null;
4692
4696
  }
4693
4697
  }
4694
- function isEngineChoice(v) {
4695
- if (v === null || typeof v !== "object" || Array.isArray(v)) return false;
4696
- const rec = { ...v };
4697
- return typeof rec["runtime"] === "string" && typeof rec["backend"] === "string" && typeof rec["format"] === "string";
4698
- }
4699
- function isPipelineStepArray(v) {
4700
- return Array.isArray(v);
4701
- }
4702
4698
  /**
4703
4699
  * Phase 7 (settings redesign) template migration.
4704
4700
  *
@@ -4915,13 +4911,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4915
4911
  */
4916
4912
  frameHandleReaders = null;
4917
4913
  /**
4918
- * True once the engine + models are fully ready for inference. No
4919
- * longer gates runtime dispatch (Phase 4 removed the legacy `runFrame`
4920
- * which read this flag); kept as a diagnostic the admin UI / tests
4921
- * surface via the future `isReady()` helper.
4922
- */
4923
- ready = false;
4924
- /**
4925
4914
  * Lazy detection-engine runtime provisioner (Phase 2). Owns the
4926
4915
  * idle → installing → verifying → ready state machine for the
4927
4916
  * currently-selected engine and is the SOLE authority the inference
@@ -4973,7 +4962,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
4973
4962
  writeStore;
4974
4963
  /** Read per-device settings. */
4975
4964
  readDeviceStore;
4976
- /** Delete all per-device settings for a device (used by `resetToDefault`). */
4965
+ /** Delete all per-device settings for a device (used by `clearDeviceOverrides`). */
4977
4966
  clearDeviceStore;
4978
4967
  constructor(settings, modelsDir, logger, eventBus = null, detectionConfigSchemaSource = null, executorOptions = {}) {
4979
4968
  this.modelsDir = modelsDir;
@@ -5048,9 +5037,9 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5048
5037
  }
5049
5038
  await this.ensureEngineFactory();
5050
5039
  }
5051
- /** True when the engine + model pool are fully warmed and inference-ready. */
5040
+ /** True when the engine provisioning machine reports inference-ready. */
5052
5041
  isReady() {
5053
- return this.ready;
5042
+ return this.getEngineProvisioning().state === "ready";
5054
5043
  }
5055
5044
  /** Store the addon context. ctx.api is a lazy getter resolved at call time. */
5056
5045
  async setApi(addonCtx) {
@@ -5496,46 +5485,25 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5496
5485
  getActiveModelSubstitutions() {
5497
5486
  return [...this.modelSubstitutions.values()];
5498
5487
  }
5488
+ /**
5489
+ * PURE node-default step tree — computed on demand, never persisted.
5490
+ *
5491
+ * The object-detection default is hardware-aware (this node's resolved
5492
+ * backend + device via `resolveDefaultDetectionModel`); every other step
5493
+ * keeps its flat per-format default. The result is cached in
5494
+ * `currentSteps` only as a memo — the cache is dropped whenever the
5495
+ * engine (hence model format) changes, so a re-read always reflects the
5496
+ * live engine. Nothing in the live per-camera dispatch path reads this:
5497
+ * it exists as the benchmark fallback (empty input steps), the Gate-A
5498
+ * config-issue probe, and the "effective post-reset model" probe.
5499
+ */
5499
5500
  async getGlobalSteps() {
5500
5501
  if (this.currentSteps) return this.currentSteps;
5501
- const raw = (await this.readStore())[KEY_STEPS];
5502
- if (!raw) {
5503
- const detectionModelId = resolveDefaultDetectionModel(this.currentEngine.backend, this.currentEngine.device ?? null, this.currentEngine.format);
5504
- const defaults = buildDefaultStepTree(this.currentEngine.format, detectionModelId);
5505
- if (defaults.length === 0) return null;
5506
- this.currentSteps = this.resolveStepModels(defaults);
5507
- this.writeStore({ [KEY_STEPS]: JSON.stringify(defaults) });
5508
- this.log.info("Bootstrapped default pipeline — object-detection + face + plate recognition enabled by default", { meta: { rootSteps: defaults.length } });
5509
- return this.currentSteps;
5510
- }
5511
- try {
5512
- let steps = readStored(raw, isPipelineStepArray) ?? [];
5513
- if (steps.length === 0) return null;
5514
- if (!steps.some((s) => s.slot === "audio-classifier")) {
5515
- const format = this.currentEngine.format;
5516
- const audioDef = getStepDefinition("audio-classifier");
5517
- if (audioDef.models.some((m) => m.formats[format])) {
5518
- const modelId = getDefaultModelForFormat("audio-classifier", format);
5519
- const audioStep = {
5520
- addonId: audioDef.id,
5521
- addonName: audioDef.name,
5522
- slot: audioDef.slot,
5523
- inputClasses: audioDef.inputClasses ?? [],
5524
- outputClasses: audioDef.outputClasses,
5525
- enabled: true,
5526
- modelId,
5527
- children: []
5528
- };
5529
- steps = [...steps, audioStep];
5530
- this.writeStore({ [KEY_STEPS]: JSON.stringify(steps) });
5531
- this.log.info("Migration: added audio-classifier step to persisted pipeline config");
5532
- }
5533
- }
5534
- this.currentSteps = this.resolveStepModels(steps);
5535
- return this.currentSteps;
5536
- } catch {
5537
- throw new Error(`Failed to parse persisted pipeline steps: corrupt data in key "${KEY_STEPS}"`);
5538
- }
5502
+ const detectionModelId = resolveDefaultDetectionModel(this.currentEngine.backend, this.currentEngine.device ?? null, this.currentEngine.format);
5503
+ const defaults = buildDefaultStepTree(this.currentEngine.format, detectionModelId);
5504
+ if (defaults.length === 0) return null;
5505
+ this.currentSteps = this.resolveStepModels(defaults);
5506
+ return this.currentSteps;
5539
5507
  }
5540
5508
  async getGlobalPipelineConfig() {
5541
5509
  if (!this.currentSteps) return null;
@@ -5990,7 +5958,14 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
5990
5958
  }
5991
5959
  decodeMs = performance.now() - decodeT0;
5992
5960
  const resolveFormat = input.engine?.format ?? this.currentEngine.format;
5993
- const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat);
5961
+ const resolveEngine = input.engine ? {
5962
+ backend: input.engine.backend,
5963
+ device: input.engine.device ?? null
5964
+ } : {
5965
+ backend: this.currentEngine.backend,
5966
+ device: this.currentEngine.device ?? null
5967
+ };
5968
+ const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat, resolveEngine);
5994
5969
  const stepsSignature = JSON.stringify(benchmarkSteps.map((s) => ({
5995
5970
  id: s.addonId,
5996
5971
  settings: s.settings ?? {}
@@ -6303,8 +6278,11 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6303
6278
  * would resolve models against the node's persisted format instead of the
6304
6279
  * format actually being benchmarked.
6305
6280
  */
6306
- inputStepsToPipelineSteps(steps, format = this.currentEngine.format) {
6307
- const { steps: resolvedSteps, diagnostics } = resolveInputSteps(steps, format);
6281
+ inputStepsToPipelineSteps(steps, format = this.currentEngine.format, engine = {
6282
+ backend: this.currentEngine.backend,
6283
+ device: this.currentEngine.device ?? null
6284
+ }) {
6285
+ const { steps: resolvedSteps, diagnostics } = resolveInputSteps(steps, format, engine);
6308
6286
  for (const addonId of diagnostics.unknownAddonIds) this.logLiveDispatchIssueOnce(`unknown:${addonId}`, () => this.log.warn("Live pipeline step references an unknown addon — dropping step", { meta: { addonId } }));
6309
6287
  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: {
6310
6288
  step: sub.addonId,
@@ -6422,67 +6400,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6422
6400
  height: 640
6423
6401
  };
6424
6402
  }
6425
- async detect(input) {
6426
- const { addonId, frame } = input;
6427
- const { executor, tree } = await this.ensureExecutor();
6428
- const data = Buffer.from(frame.data);
6429
- let rootInput;
6430
- let jpegProvider;
6431
- if (frame.format === "jpeg") {
6432
- rootInput = {
6433
- kind: "jpeg",
6434
- data
6435
- };
6436
- jpegProvider = async () => data;
6437
- } else if (frame.format === "rgb" || frame.format === "bgr" || frame.format === "gray") {
6438
- const channels = frame.format === "gray" ? 1 : 3;
6439
- const sharp = (await import("sharp")).default;
6440
- const jpeg = await sharp(data, { raw: {
6441
- width: frame.width,
6442
- height: frame.height,
6443
- channels
6444
- } }).jpeg({
6445
- quality: 85,
6446
- mozjpeg: false
6447
- }).toBuffer();
6448
- rootInput = {
6449
- kind: "jpeg",
6450
- data: jpeg
6451
- };
6452
- jpegProvider = async () => jpeg;
6453
- } else {
6454
- const sharp = (await import("sharp")).default;
6455
- const encoded = await sharp(data, { raw: {
6456
- width: frame.width,
6457
- height: frame.height,
6458
- channels: 3
6459
- } }).jpeg({
6460
- quality: 80,
6461
- mozjpeg: false
6462
- }).toBuffer();
6463
- rootInput = {
6464
- kind: "jpeg",
6465
- data: encoded
6466
- };
6467
- jpegProvider = async () => encoded;
6468
- }
6469
- const { result } = await executor.run(tree, rootInput, jpegProvider, frame.width, frame.height, 0);
6470
- return {
6471
- detections: result.detections.filter((d) => d.kind === "first-level").map((d) => ({
6472
- class: d.macroClass,
6473
- originalClass: d.debug?.originalClass ?? d.macroClass,
6474
- score: d.score,
6475
- bbox: {
6476
- x: d.bbox.x,
6477
- y: d.bbox.y,
6478
- w: d.bbox.width,
6479
- h: d.bbox.height
6480
- }
6481
- })),
6482
- inferenceMs: result.debug?.totalInferenceMs ?? 0,
6483
- modelId: addonId
6484
- };
6485
- }
6486
6403
  /**
6487
6404
  * Batched run — dispatches N raw frames against the same loaded
6488
6405
  * single-step model in one IPC round-trip via
@@ -6525,7 +6442,14 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6525
6442
  async runPipelineBatchImpl(input) {
6526
6443
  if (input.frames.length === 0) return { results: [] };
6527
6444
  const resolveFormat = input.engine?.format ?? this.currentEngine.format;
6528
- const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat);
6445
+ const resolveEngine = input.engine ? {
6446
+ backend: input.engine.backend,
6447
+ device: input.engine.device ?? null
6448
+ } : {
6449
+ backend: this.currentEngine.backend,
6450
+ device: this.currentEngine.device ?? null
6451
+ };
6452
+ const benchmarkSteps = this.inputStepsToPipelineSteps(input.steps, resolveFormat, resolveEngine);
6529
6453
  const enabledSteps = flattenEnabledVideoSteps(benchmarkSteps);
6530
6454
  if (enabledSteps.length === 0) throw new Error("runPipelineBatch: no enabled steps");
6531
6455
  const rootStep = enabledSteps[0];
@@ -6817,71 +6741,11 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6817
6741
  });
6818
6742
  await this.engineFactory.initialize([]);
6819
6743
  }
6820
- async ensureExecutor() {
6821
- if (this.initPromise) await this.initPromise;
6822
- if (!this.engineFactory) {
6823
- await this.assertEngineReady();
6824
- this.initPromise = this.doInitialize();
6825
- try {
6826
- await this.initPromise;
6827
- } finally {
6828
- this.initPromise = null;
6829
- }
6830
- }
6831
- if (!this.currentSteps) throw new Error("No pipeline steps configured");
6832
- const tree = buildExecutableTree(this.currentSteps, (stepId) => this.engineFactory.getEngine(stepId));
6833
- return {
6834
- executor: this.executor,
6835
- tree
6836
- };
6837
- }
6838
- /** Actual initialization — download models, create engine, load pool. Called once. */
6839
- async doInitialize() {
6840
- const steps = await this.getGlobalSteps();
6841
- if (!steps) throw new Error("No pipeline steps configured. Use setGlobalSteps() first.");
6842
- this.log.info("Pipeline initializing — frames will be dropped until ready");
6843
- const format = this.currentEngine.format;
6844
- const downloads = [];
6845
- for (const step of flattenSteps(steps)) {
6846
- const modelEntry = await this.resolveModelEntry(step.addonId, step.modelId);
6847
- if (!modelEntry) {
6848
- this.log.warn("Model not found in step catalog — skipping download", { meta: {
6849
- modelId: step.modelId,
6850
- step: step.addonId
6851
- } });
6852
- continue;
6853
- }
6854
- if (!isModelDownloaded(this.modelsDir, modelEntry, format)) this.log.info("Downloading model", { meta: {
6855
- modelId: step.modelId,
6856
- format
6857
- } });
6858
- downloads.push(ensureModel(this.modelsDir, modelEntry, format).then(() => {}));
6859
- }
6860
- await Promise.all(downloads);
6861
- await this.ensureBackendDeps(this.currentEngine);
6862
- this.engineFactory = new EngineFactory({
6863
- engine: this.currentEngine,
6864
- modelsDir: this.modelsDir,
6865
- logger: this.log.child("engine"),
6866
- pythonPath: this.executorOptions.pythonPath ?? "",
6867
- concurrency: this.executorOptions.concurrency,
6868
- tuning: this.executorOptions.tuning,
6869
- numWorkers: this.executorOptions.numWorkers
6870
- });
6871
- await this.engineFactory.initialize(steps);
6872
- this.currentSteps = steps;
6873
- const runtimeStr = `${this.currentEngine.runtime}+${this.currentEngine.backend}`;
6874
- this.executor = new PipelineExecutor({
6875
- engineRuntime: runtimeStr,
6876
- logger: this.log
6877
- });
6878
- this.ready = true;
6879
- this.log.info("Pipeline ready — accepting frames");
6880
- }
6881
6744
  /**
6882
6745
  * Phase 2b — resolve the engine from the addon's new schema-backed
6883
- * fields (`engineRuntime`, `engineBackend`, `engineDevice`). Fallback
6884
- * to the legacy `KEY_ENGINE` JSON blob for pre-migration stores.
6746
+ * fields (`engineRuntime`, `engineBackend`, `engineDevice`). The legacy
6747
+ * `pipelineEngine` JSON-blob fallback was removed with the executor seed
6748
+ * (any store predating the per-node cascade simply re-runs auto-pick).
6885
6749
  *
6886
6750
  * The `'auto'` sentinel is treated as NO override (returns null) so the
6887
6751
  * caller re-resolves LIVE via `resolveAutoEngine()` — `'auto'` is the
@@ -6924,8 +6788,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6924
6788
  ...device ? { device } : {}
6925
6789
  };
6926
6790
  }
6927
- const raw = store[KEY_ENGINE];
6928
- return readStored(raw, isEngineChoice);
6791
+ return null;
6929
6792
  }
6930
6793
  /**
6931
6794
  * Re-run the platform probe for the inference engine and persist the
@@ -6975,48 +6838,29 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
6975
6838
  return { success: true };
6976
6839
  }
6977
6840
  /**
6978
- * Reset THIS node's detection-pipeline to its factory defaults, forcing
6979
- * regeneration of the hardware-aware default object-detection model.
6841
+ * Clear THIS node's executor-side PER-DEVICE settings stores the
6842
+ * per-camera step overrides the object-detection root reads via
6843
+ * `applyDeviceOverridesToTree`.
6980
6844
  *
6981
6845
  * Node-routed (the cap's default `nodeIdMode: 'routing'`): the generated
6982
6846
  * cap-router strips `nodeId` and dispatches to the target node, so this
6983
- * method runs ON the node being reset and takes no argument.
6847
+ * method runs ON the node being cleared and takes no argument.
6984
6848
  *
6985
- * Clears three things:
6986
- * 1. the persisted GLOBAL pipeline seed (`KEY_STEPS`)nulled in the
6987
- * store AND the in-memory `currentSteps` cache, so the subsequent
6988
- * `getGlobalSteps()` re-seeds the hardware-aware default tree fresh
6989
- * (`resolveDefaultDetectionModel` against this node's live engine)
6990
- * rather than returning the stale cached blob.
6991
- * 2. the LEGACY engine blob (`KEY_ENGINE`). The per-node engine cascade
6992
- * (`engineBackend@<node>` / `engineDevice@<node>`) is intentionally
6993
- * left intact — the operator's engine selection is preserved and the
6994
- * default is regenerated against it.
6995
- * 3. every device's PER-CAMERA step overrides (the per-device store the
6996
- * object-detection root reads via `applyDeviceOverridesToTree`).
6849
+ * This is the slimmed executor leg of the orchestrator's
6850
+ * `resetNodePipelineDefaults` flow. The legacy `resetToDefault` — which
6851
+ * also reset a persisted GLOBAL step-tree seed nothing in the live
6852
+ * per-camera path read was removed together with that seed
6853
+ * (`getGlobalSteps` is pure now, so there is nothing node-global left to
6854
+ * reset here).
6997
6855
  *
6998
- * Idempotent: a second call re-seeds the identical default and clears
6999
- * already-empty per-device stores harmlessly. Returns the regenerated
7000
- * object-detection model id (null when the default tree has no detector
7001
- * for this node's format).
6856
+ * Idempotent: clearing already-empty per-device stores is a no-op.
7002
6857
  */
7003
- async resetToDefault() {
7004
- await this.writeStore({
7005
- [KEY_STEPS]: null,
7006
- [KEY_ENGINE]: null
7007
- });
7008
- this.currentSteps = null;
6858
+ async clearDeviceOverrides() {
7009
6859
  const clearedDevices = await this.clearAllDeviceOverrides();
7010
- const regeneratedModelId = ((await this.getGlobalSteps())?.find((s) => s.slot === "detector") ?? null)?.modelId ?? null;
7011
- this.log.info("pipeline reset to default", { meta: {
7012
- clearedGlobalSteps: true,
7013
- clearedEngineBlob: true,
7014
- clearedDeviceOverrides: clearedDevices,
7015
- regeneratedModelId
7016
- } });
6860
+ this.log.info("executor per-device overrides cleared", { meta: { clearedDevices } });
7017
6861
  return {
7018
6862
  success: true,
7019
- regeneratedModelId
6863
+ clearedDevices
7020
6864
  };
7021
6865
  }
7022
6866
  /**
@@ -7026,7 +6870,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7026
6870
  * enumerated via the device-manager and cleared one by one
7027
6871
  * (`clearDeviceStore` is idempotent — a device with no overrides is a
7028
6872
  * no-op). Never throws: a device-manager outage degrades to "cleared
7029
- * nothing" so the global reset still completes.
6873
+ * nothing" so the reset flow still completes.
7030
6874
  */
7031
6875
  async clearAllDeviceOverrides() {
7032
6876
  const api = this.addonCtx?.api;
@@ -7035,7 +6879,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7035
6879
  try {
7036
6880
  devices = await api.deviceManager.listAll.query({});
7037
6881
  } catch (err) {
7038
- this.log.warn("resetToDefault: device enumeration failed — skipping per-device clear", { meta: { error: errMsg(err) } });
6882
+ this.log.warn("clearDeviceOverrides: device enumeration failed — skipping per-device clear", { meta: { error: errMsg(err) } });
7039
6883
  return 0;
7040
6884
  }
7041
6885
  let cleared = 0;
@@ -7043,10 +6887,13 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
7043
6887
  await this.clearDeviceStore(device.id);
7044
6888
  cleared++;
7045
6889
  } catch (err) {
7046
- this.log.warn("resetToDefault: failed to clear per-device overrides for device", { meta: {
7047
- deviceId: device.id,
7048
- error: errMsg(err)
7049
- } });
6890
+ this.log.warn("clearDeviceOverrides: failed to clear per-device overrides for device", {
6891
+ tags: { deviceId: device.id },
6892
+ meta: {
6893
+ deviceId: device.id,
6894
+ error: errMsg(err)
6895
+ }
6896
+ });
7050
6897
  }
7051
6898
  return cleared;
7052
6899
  }