@camstack/addon-pipeline 1.2.621 → 1.2.622

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 (43) hide show
  1. package/dist/audio-analyzer/index.js +3 -3
  2. package/dist/audio-analyzer/index.mjs +3 -3
  3. package/dist/{custom-model-catalog-Il8UY4D4.js → custom-model-catalog-CKCK-QcT.js} +7 -7
  4. package/dist/{custom-model-catalog-0_SnSXzN.mjs → custom-model-catalog-wpMi2U7e.mjs} +7 -7
  5. package/dist/detection-pipeline/index.js +55 -414
  6. package/dist/detection-pipeline/index.mjs +79 -438
  7. package/dist/{dist-DHqkQhTQ.mjs → dist-BF60SjmI.mjs} +76 -226
  8. package/dist/{dist-ClkumZgv.js → dist-DUFGDd_2.js} +75 -231
  9. package/dist/{model-catalogs-BagalaYp.js → model-catalogs-CjTm_0O-.js} +1 -1
  10. package/dist/{model-catalogs-Z1GZAhSb.mjs → model-catalogs-CqFDhb0B.mjs} +1 -1
  11. package/dist/motion-wasm/index.js +1 -1
  12. package/dist/motion-wasm/index.mjs +1 -1
  13. package/dist/{node-CkJLxlWI.mjs → node-DkphOOM2.mjs} +1 -1
  14. package/dist/{node-0O_61WVW.js → node-DzGVn7bD.js} +1 -1
  15. package/dist/pipeline-runner/index.js +18 -4
  16. package/dist/pipeline-runner/index.mjs +18 -4
  17. package/dist/{process-memory-DdIOhjYB.js → process-memory-8kKexHYR.js} +1 -1
  18. package/dist/{process-memory-Dj3UgL1e.mjs → process-memory-CBzfdSvC.mjs} +1 -1
  19. package/dist/recorder/index.js +2 -2
  20. package/dist/recorder/index.mjs +2 -2
  21. package/dist/{segment-demux-js-Bv0t0-tQ.mjs → segment-demux-js-DQNoNSJt.mjs} +1 -1
  22. package/dist/{segment-demux-js-BePzacki.js → segment-demux-js-DRLQb1pc.js} +1 -1
  23. package/dist/session-decode/decode-worker-main.js +12 -21
  24. package/dist/session-decode/decode-worker-main.mjs +12 -21
  25. package/dist/stream-broker/_stub.js +2 -2
  26. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-dNk74ahz.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BmANAxAe.mjs} +2 -2
  27. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-H6RKsaiZ.mjs +26 -0
  28. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CNoWeZHH.mjs +26 -0
  29. package/dist/stream-broker/demux-worker-child.js +1 -1
  30. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  31. package/dist/stream-broker/{hostInit-CH5g78CJ.mjs → hostInit-B3hXAfr1.mjs} +2 -2
  32. package/dist/stream-broker/index.js +3 -3
  33. package/dist/stream-broker/index.mjs +3 -3
  34. package/dist/stream-broker/remoteEntry.js +1 -1
  35. package/dist/{worker-protocol-D_NzPcnh.mjs → worker-protocol-DngGEAT2.js} +102 -2
  36. package/dist/{worker-protocol-C-G8qmye.js → worker-protocol-_avq7y8O.mjs} +67 -25
  37. package/package.json +1 -1
  38. package/python/coreml_load_probe.py +105 -15
  39. package/python/openvino_compile_probe.py +72 -18
  40. package/python/test_coreml_load_probe.py +83 -0
  41. package/python/test_openvino_compile_probe.py +114 -0
  42. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-2KkGoQ55.mjs +0 -26
  43. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Dx-WrMx0.mjs +0 -26
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { $t as pipelineExecutorCapability, Ct as enumerateInferenceDevices, F as PoolMemoryWatchdog, Hn as createEvent, In as BaseAddon, It as linkedLabelStepId, Jn as hydrateSchema, Jt as overlayClusterStepSettings, Kt as modelBindingKey, O as LABEL_SUPPLY_MACRO, Pn as errMsg$1, Rt as loadContributionCapability, Sn as supportedRuntimes$1, X as applyModelBoundSettings, Xt as pickClusterStepSettings, _n as stepModelRunsOnFormat, _r as EventCategory, _t as detectionPipelineCapability, bt as edgetpuDelegateDevice, ct as containingParentIndex, d as CLUSTER_MODEL_SCOPED_STEPS, dn as resolvePoolMemoryPolicy, er as nodePin, fr as object, ft as defaultDeviceFor$1, g as DEFAULT_CLUSTER_STEP_SETTINGS, gr as union, hn as runtimeDevices$1, hr as string, mn as rootSuppliesOf, n as APPLE_SA_TO_MACRO, on as resolveClusterStepModelId, or as array, q as YAMNET_TO_MACRO, qn as hfModelUrl, rr as sleep, st as collectModelBoundKeys, wt as evaluateZoneRules } from "../dist-DHqkQhTQ.mjs";
3
- import { c as readProcessCost } from "../node-CkJLxlWI.mjs";
4
- import { C as resolveModelDefaultConfidence, S as landmarkPrecisionVerdict, _ as ALL_STEPS, b as getStepDefinition, f as localFrameRegistry, g as ALL_PIPELINE_STEPS, l as resolveDefaultDetectionModel, n as mergeCustomModels, o as deviceKeyOf, r as buildSubtreeCanRun, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, v as getDefaultModelForFormat, x as resolveModelForFormat, y as getStep } from "../custom-model-catalog-0_SnSXzN.mjs";
2
+ import { $n as nodePin, Ct as enumerateInferenceDevices, F as PoolMemoryWatchdog, Fn as BaseAddon, It as linkedLabelStepId, Kn as hfModelUrl, Nn as errMsg, O as LABEL_SUPPLY_MACRO, Qt as pipelineExecutorCapability, Rt as loadContributionCapability, Vn as createEvent, X as applyModelBoundSettings, Yt as pickClusterStepSettings, _t as detectionPipelineCapability, an as resolveClusterStepModelId, ar as array, bt as edgetpuDelegateDevice, ct as containingParentIndex, d as CLUSTER_MODEL_SCOPED_STEPS, dr as object, ft as defaultDeviceFor$1, g as DEFAULT_CLUSTER_STEP_SETTINGS, gn as stepModelRunsOnFormat, gr as EventCategory, hr as union, mn as runtimeDevices$1, mr as string, n as APPLE_SA_TO_MACRO, nr as sleep, pn as rootSuppliesOf, q as YAMNET_TO_MACRO, qn as hydrateSchema, qt as overlayClusterStepSettings, st as collectModelBoundKeys, un as resolvePoolMemoryPolicy, wt as evaluateZoneRules, xn as supportedRuntimes$1 } from "../dist-BF60SjmI.mjs";
3
+ import { c as readProcessCost } from "../node-DkphOOM2.mjs";
4
+ import { C as resolveModelDefaultConfidence, S as landmarkPrecisionVerdict, _ as ALL_STEPS, b as getStepDefinition, f as localFrameRegistry, g as ALL_PIPELINE_STEPS, l as resolveDefaultDetectionModel, n as mergeCustomModels, o as deviceKeyOf, r as buildSubtreeCanRun, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, v as getDefaultModelForFormat, x as resolveModelForFormat, y as getStep } from "../custom-model-catalog-wpMi2U7e.mjs";
5
5
  import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
6
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Dj3UgL1e.mjs";
6
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-CBzfdSvC.mjs";
7
7
  import * as os$1 from "node:os";
8
8
  import * as fs from "node:fs";
9
9
  import * as path$1 from "node:path";
@@ -350,84 +350,6 @@ function normalizeEngineNodeId(rawNodeId) {
350
350
  return raw.includes("/") ? raw.split("/")[0] ?? "hub" : raw;
351
351
  }
352
352
  //#endregion
353
- //#region src/detection-pipeline/model-bound-device-overrides.ts
354
- /**
355
- * Auto tune (D745), the executor leg: list — and optionally remove — the
356
- * MODEL-BOUND thresholds stored in this addon's per-camera settings (the
357
- * object-detection root's `bindsToModel` keys and their binding keys, D738).
358
- * Every other key of a camera's store is kept.
359
- *
360
- * The device store only MERGES on write, so a removal is clear + write of the
361
- * kept keys — the idiom `migrate-hardware-state.ts` uses. Both run in this
362
- * process, serialized per camera; a write that fails after the clear restores
363
- * the original row, and the camera is reported `refused` rather than clean. A
364
- * store that cannot be read is `refused` too: a failed read is never "nothing
365
- * to clear" (D393).
366
- */
367
- function errMsg(err) {
368
- return err instanceof Error ? err.message : String(err);
369
- }
370
- /** The stored keys among `boundKeys` (values and bindings), sorted. */
371
- function presentBoundKeys(row, boundKeys) {
372
- return boundKeys.flatMap((k) => [k, modelBindingKey(k)]).filter((k) => k in row).toSorted();
373
- }
374
- async function clearModelBoundDeviceOverrides(deps, input) {
375
- const ids = input.deviceIds ?? await deps.listDeviceIds();
376
- const entries = [];
377
- const refused = [];
378
- for (const deviceId of [...ids].toSorted((a, b) => a - b)) {
379
- let row;
380
- try {
381
- row = await deps.readDeviceStore(deviceId);
382
- } catch (err) {
383
- refused.push({
384
- deviceId,
385
- reason: `read failed: ${errMsg(err)}`
386
- });
387
- continue;
388
- }
389
- const keys = presentBoundKeys(row, deps.boundKeys);
390
- if (keys.length === 0) continue;
391
- if (input.dryRun) {
392
- entries.push({
393
- deviceId,
394
- keys
395
- });
396
- continue;
397
- }
398
- const kept = { ...row };
399
- for (const k of keys) delete kept[k];
400
- try {
401
- await deps.clearDeviceStore(deviceId);
402
- } catch (err) {
403
- refused.push({
404
- deviceId,
405
- reason: `clear failed: ${errMsg(err)}`
406
- });
407
- continue;
408
- }
409
- try {
410
- if (Object.keys(kept).length > 0) await deps.writeDeviceStore(deviceId, kept);
411
- entries.push({
412
- deviceId,
413
- keys
414
- });
415
- } catch (err) {
416
- await deps.writeDeviceStore(deviceId, row).catch(() => void 0);
417
- refused.push({
418
- deviceId,
419
- reason: `write failed, row restored: ${errMsg(err)}`
420
- });
421
- } finally {
422
- deps.invalidate(deviceId);
423
- }
424
- }
425
- return {
426
- entries,
427
- refused
428
- };
429
- }
430
- //#endregion
431
353
  //#region src/detection-pipeline/model-format-facts.ts
432
354
  /**
433
355
  * Two per-format facts `getSchema` reports beside `downloaded`, for Model
@@ -762,122 +684,6 @@ var ClusterUnknownRefusalLog = class {
762
684
  }
763
685
  };
764
686
  //#endregion
765
- //#region src/detection-pipeline/device-override-mirror.ts
766
- /**
767
- * The per-device detection overrides, kept fresh OFF the frame path.
768
- *
769
- * ## The read this replaces
770
- *
771
- * `runPipeline` resolved a device's overrides by calling
772
- * `settings.readDeviceStore(deviceId)` on **every inference frame**. Measured
773
- * on the live hub 2026-08-25: `get detection-pipeline:addon-devices`, 1 143
774
- * calls a minute at 0.44 rows per call — the disk asked, nineteen times a
775
- * second, whether an operator has ever changed a threshold.
776
- *
777
- * ## Why this is not "a cache in the consumer" (D224)
778
- *
779
- * D224 forbids a SECOND authority over a fact that belongs to somebody else:
780
- * the failure it records is a consumer caching a value whose write path does
781
- * not run through that consumer, so an operator's own change is the one read
782
- * the cache gets wrong.
783
- *
784
- * This addon OWNS the row. `<addonId>:addon-devices` is detection-pipeline's
785
- * own store, and the only writers are this addon's `updateDeviceSettings` and
786
- * its `clearDeviceOverrides` — both of which call {@link invalidate}. A write
787
- * is therefore its own invalidation, exactly as D224 requires, and the window
788
- * below governs only the case nobody writes through this process.
789
- *
790
- * ## The window, declared
791
- *
792
- * {@link DEVICE_OVERRIDE_STALE_MS} is what an operator's change costs on a node
793
- * that did NOT serve the write — this addon runs per node, and a settings write
794
- * lands on one of them. Thirty seconds is the trade: it removes 99.9% of the
795
- * reads (one per device per window instead of one per frame) and it is short
796
- * enough that "I moved the threshold and nothing happened" is not a support
797
- * question. Ten minutes — {@link OPERATOR_WRITTEN_STALE_MS}, the constant for a
798
- * cap whose value only an operator changes — is right for a POLLED reader that
799
- * costs a camera round trip; this read costs one local SQLite `get`, and the
800
- * cheap read buys a short window.
801
- *
802
- * A stale entry is SERVED and revalidated behind the caller, never awaited: a
803
- * frame that waits for the settings store is a frame the pipeline dropped, and
804
- * the reader is by definition about to ask again.
805
- */
806
- /**
807
- * How long a mirrored entry is served before a refresh is started behind the
808
- * next reader. See the module doc for why it is 30 s and not ten minutes.
809
- */
810
- var DEVICE_OVERRIDE_STALE_MS = 3e4;
811
- /**
812
- * How long a FAILED refresh is not retried.
813
- *
814
- * A refresh that throws leaves `fetchedAt` where it was, so without a cooldown
815
- * every subsequent frame would start another one — a broken settings store
816
- * would be hammered at frame rate by the very mechanism built to stop that.
817
- */
818
- var DEVICE_OVERRIDE_MISS_COOLDOWN_MS = 5e3;
819
- var DeviceOverrideMirror = class {
820
- deps;
821
- staleMs;
822
- missCooldownMs;
823
- entries = /* @__PURE__ */ new Map();
824
- /** In-flight reads, so a burst of frames on a cold device costs ONE read and
825
- * not one per frame — the exact failure this class exists to remove. */
826
- inFlight = /* @__PURE__ */ new Map();
827
- now;
828
- constructor(deps, staleMs = DEVICE_OVERRIDE_STALE_MS, missCooldownMs = DEVICE_OVERRIDE_MISS_COOLDOWN_MS) {
829
- this.deps = deps;
830
- this.staleMs = staleMs;
831
- this.missCooldownMs = missCooldownMs;
832
- this.now = deps.now ?? (() => Date.now());
833
- }
834
- /**
835
- * The device's overrides.
836
- *
837
- * COLD awaits — the first frame on a camera has to get the real answer, and a
838
- * default is exactly what "the operator lowered this threshold" looks like.
839
- * WARM returns immediately, stale or not, and starts the refresh behind the
840
- * caller.
841
- */
842
- async resolve(deviceId) {
843
- const entry = this.entries.get(deviceId);
844
- if (entry === void 0) return this.load(deviceId);
845
- if (this.now() - entry.fetchedAt >= this.staleMs) this.load(deviceId);
846
- return entry.value;
847
- }
848
- /** Drop a device's entry. Called by every writer in this process, so an
849
- * operator's own change is never served from the mirror. */
850
- invalidate(deviceId) {
851
- this.entries.delete(deviceId);
852
- }
853
- invalidateAll() {
854
- this.entries.clear();
855
- }
856
- async load(deviceId) {
857
- const pending = this.inFlight.get(deviceId);
858
- if (pending !== void 0) return pending;
859
- const run = this.deps.read(deviceId).then((value) => {
860
- this.entries.set(deviceId, {
861
- value,
862
- fetchedAt: this.now()
863
- });
864
- return value;
865
- }).catch((err) => {
866
- this.deps.onRefreshFailed?.(deviceId, err);
867
- const existing = this.entries.get(deviceId);
868
- if (existing !== void 0) {
869
- existing.fetchedAt = this.now() - this.staleMs + this.missCooldownMs;
870
- return existing.value;
871
- }
872
- return {};
873
- }).finally(() => {
874
- this.inFlight.delete(deviceId);
875
- });
876
- this.inFlight.set(deviceId, run);
877
- return run;
878
- }
879
- };
880
- //#endregion
881
687
  //#region src/detection-pipeline/engine/pool-worker-health.ts
882
688
  /**
883
689
  * The one table of load bounds (D653, fix round 1).
@@ -4222,6 +4028,29 @@ function benchmarkKeyOf(deviceKey) {
4222
4028
  function isBenchmarkRun(input) {
4223
4029
  return input.frame === void 0 && input.frameRef === void 0 && input.deviceId === void 0 && input.replay !== true;
4224
4030
  }
4031
+ /**
4032
+ * Backends whose device opens in ONE process at a time. libedgetpu holds an
4033
+ * Edge TPU exclusively for the process that opened it, so a second pool on a
4034
+ * Coral the cameras' pool already holds cannot open it at all — every
4035
+ * benchmark and auto-benchmark (D913) of an in-use Coral failed that way on
4036
+ * the dev hub (1.2.619). Every other backend this node builds (OpenVINO,
4037
+ * CoreML, CUDA, ONNX, CPU) shares its device between processes.
4038
+ */
4039
+ var EXCLUSIVE_BACKENDS = new Set(["edgetpu"]);
4040
+ /** True when the device behind `deviceKey` (`<backend>:<device>`) cannot be opened by a second pool. */
4041
+ function isExclusiveDevice(deviceKey) {
4042
+ const colon = deviceKey.indexOf(":");
4043
+ const backend = colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
4044
+ return EXCLUSIVE_BACKENDS.has(backend);
4045
+ }
4046
+ /**
4047
+ * A benchmark on an EXCLUSIVE device is the one benchmark that goes to the
4048
+ * live pool: the separate pool could not open the device, so the choice is
4049
+ * between measuring through the cameras' pool and not measuring at all.
4050
+ */
4051
+ function benchmarkPlacementOf(benchmark, deviceKey) {
4052
+ return benchmark && !isExclusiveDevice(deviceKey) ? "benchmark-pool" : "live-pool";
4053
+ }
4225
4054
  var BenchmarkPools = class {
4226
4055
  options;
4227
4056
  pools = /* @__PURE__ */ new Map();
@@ -4802,14 +4631,15 @@ var PRIMARY_ROOT_STEP = "object-detection";
4802
4631
  /**
4803
4632
  * The same rule over an EXECUTABLE tree's roots (D658): their model ids are the
4804
4633
  * pool variants that will run — after resolution, per-step loads and drops —
4805
- * so this is what a live `runPipeline` stamps. The tree holds only enabled
4806
- * video roots already.
4807
- */
4808
- function resolveTreeRootModelId(roots) {
4809
- return primaryRootModelId(roots);
4810
- }
4811
- function primaryRootModelId(roots) {
4812
- return (roots.find((s) => s.stepId === PRIMARY_ROOT_STEP) ?? roots[0])?.modelId;
4634
+ * so this is what a live `runPipeline` stamps, with the root's step id beside
4635
+ * the model (D925). The tree holds only enabled video roots already.
4636
+ */
4637
+ function resolveTreeRoot(roots) {
4638
+ const root = roots.find((s) => s.stepId === PRIMARY_ROOT_STEP) ?? roots[0];
4639
+ return root === void 0 ? void 0 : {
4640
+ stepId: root.stepId,
4641
+ modelId: root.modelId
4642
+ };
4813
4643
  }
4814
4644
  //#endregion
4815
4645
  //#region src/detection-pipeline/engine-provisioner.ts
@@ -7189,7 +7019,7 @@ var PipelineExecutor = class {
7189
7019
  rootStepId: rootStep.stepId,
7190
7020
  parentClass: mutable.macroClass,
7191
7021
  parentScore: mutable.score,
7192
- error: errMsg$1(err)
7022
+ error: errMsg(err)
7193
7023
  }
7194
7024
  });
7195
7025
  }
@@ -7320,7 +7150,7 @@ var PipelineExecutor = class {
7320
7150
  rootStepId: rootStep.stepId,
7321
7151
  parentClass: mutable.macroClass,
7322
7152
  parentScore: mutable.score,
7323
- error: errMsg$1(err)
7153
+ error: errMsg(err)
7324
7154
  }
7325
7155
  });
7326
7156
  }
@@ -7419,7 +7249,7 @@ var PipelineExecutor = class {
7419
7249
  ]
7420
7250
  };
7421
7251
  } catch (err) {
7422
- this.throttledWarn(`crop-zone-prep:${deviceId}`, 3e4, "crop-zone frame preparation failed — running package-detection full-frame", { error: errMsg$1(err) }, deviceId);
7252
+ this.throttledWarn(`crop-zone-prep:${deviceId}`, 3e4, "crop-zone frame preparation failed — running package-detection full-frame", { error: errMsg(err) }, deviceId);
7423
7253
  return null;
7424
7254
  }
7425
7255
  }
@@ -7431,7 +7261,7 @@ var PipelineExecutor = class {
7431
7261
  try {
7432
7262
  engineOutput = await step.engine.infer(input);
7433
7263
  } catch (err) {
7434
- const errorMsg = errMsg$1(err);
7264
+ const errorMsg = errMsg(err);
7435
7265
  const errorOutput = {
7436
7266
  kind: "detections",
7437
7267
  detections: []
@@ -7718,7 +7548,7 @@ var PipelineExecutor = class {
7718
7548
  this.throttledWarn(`child-fail:${child.stepId}:${deviceId}`, 15e3, "pipeline child step failed", {
7719
7549
  step: child.stepId,
7720
7550
  model: child.modelId,
7721
- error: errMsg$1(err)
7551
+ error: errMsg(err)
7722
7552
  }, deviceId);
7723
7553
  }
7724
7554
  }
@@ -7865,16 +7695,6 @@ function collectSchemaDefaults(schema) {
7865
7695
  walkFieldsForDefaults(schema, out);
7866
7696
  return out;
7867
7697
  }
7868
- /**
7869
- * The operator settings of `stepId` as the model that RUNS sees them (D738):
7870
- * a model-bound value made for another model is dropped and binding keys are
7871
- * stripped. For a settings layer merged AFTER the tree is built (the
7872
- * executor's per-device store, `applyDeviceOverridesToTree`), so it obeys the
7873
- * same binding as the layers `buildNode` merges.
7874
- */
7875
- function resolveOperatorSettingsForModel(stepId, settings, runningModelId) {
7876
- return applyModelBoundSettings(settings, collectModelBoundKeys(getStep(stepId).getConfigSchema()), runningModelId) ?? {};
7877
- }
7878
7698
  function walkFieldsForDefaults(fields, out) {
7879
7699
  for (const field of fields) {
7880
7700
  if ("type" in field && field.type === "group" && "fields" in field) {
@@ -8563,7 +8383,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
8563
8383
  * node-default tree against `this.currentEngine.format`. Recomputed
8564
8384
  * EAGERLY by {@link recomputeConfigIssues} whenever the engine actually
8565
8385
  * changes (see `onEngineSelectionChanged`), rather than relying on a
8566
- * `getGlobalSteps()` call that may never happen on a camera-only node.
8386
+ * `nodeDefaultSteps()` call that may never happen on a camera-only node.
8567
8387
  * Merged into {@link getEngineProvisioning}'s snapshot; never consulted by
8568
8388
  * `assertEngineReady` — this gate SURFACES, it does not block inference.
8569
8389
  */
@@ -8665,20 +8485,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
8665
8485
  readStore;
8666
8486
  /** Write a patch to the addon settings store. */
8667
8487
  writeStore;
8668
- /** Read per-device settings. */
8669
- readDeviceStore;
8670
- /** Delete all per-device settings for a device (used by `clearDeviceOverrides`). */
8671
- clearDeviceStore;
8672
- /** Merge a patch into one device's settings (Auto tune' keep-the-rest rewrite, D745). */
8673
- writeDeviceStore;
8674
- /**
8675
- * The per-device overrides the FRAME path reads, kept fresh off that path.
8676
- *
8677
- * Public so the addon class can drop a device on its own
8678
- * `updateDeviceSettings` — the write and the mirror have to be the same
8679
- * process's, or the mirror becomes the second authority D224 forbids.
8680
- */
8681
- deviceOverrides;
8682
8488
  constructor(settings, modelsDir, logger, eventBus = null, detectionConfigSchemaSource = null, executorOptions = {}) {
8683
8489
  this.modelsDir = modelsDir;
8684
8490
  this.eventBus = eventBus;
@@ -8687,18 +8493,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
8687
8493
  this.log = logger;
8688
8494
  this.readStore = () => settings.readAddonStore();
8689
8495
  this.writeStore = (patch) => settings.writeAddonStore(patch);
8690
- this.readDeviceStore = settings.readDeviceStore ?? (async () => ({}));
8691
- const clearDeviceStore = settings.clearDeviceStore;
8692
- this.clearDeviceStore = clearDeviceStore ? (deviceId) => clearDeviceStore.call(settings, deviceId) : async () => void 0;
8693
- const writeDeviceStore = settings.writeDeviceStore;
8694
- this.writeDeviceStore = writeDeviceStore ? (deviceId, patch) => writeDeviceStore.call(settings, deviceId, patch) : async () => void 0;
8695
- this.deviceOverrides = new DeviceOverrideMirror({
8696
- read: (deviceId) => this.readDeviceStore(deviceId),
8697
- onRefreshFailed: (deviceId, err) => this.log.warn("per-device detection overrides refresh failed — serving the last value", {
8698
- tags: { deviceId },
8699
- meta: { error: errMsg$1(err) }
8700
- })
8701
- });
8702
8496
  this.currentEngine = ONNX_FLOOR;
8703
8497
  this.log.info("Engine pick pending (placeholder until probe / persisted selection)", { meta: {
8704
8498
  runtime: this.currentEngine.runtime,
@@ -8722,7 +8516,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
8722
8516
  stale: report.stale
8723
8517
  } });
8724
8518
  }, (err) => {
8725
- this.log.warn("Model revision check failed — copies are proven on their next download", { meta: { error: errMsg$1(err) } });
8519
+ this.log.warn("Model revision check failed — copies are proven on their next download", { meta: { error: errMsg(err) } });
8726
8520
  });
8727
8521
  }
8728
8522
  /**
@@ -8832,14 +8626,14 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
8832
8626
  else this.log.warn("platform-probe readiness gate timed out — conservative engine pick (floor is not persisted)", { meta: {
8833
8627
  nodeId,
8834
8628
  timeoutMs: PROBE_READY_TIMEOUT_MS,
8835
- error: errMsg$1(err)
8629
+ error: errMsg(err)
8836
8630
  } });
8837
8631
  }
8838
8632
  await this.resolveAutoEngine();
8839
8633
  this.needsAutoPick = false;
8840
8634
  this.startProvisioningForCurrentEngine();
8841
8635
  await this.recomputeConfigIssues().catch((err) => {
8842
- this.log.warn("config-issue recompute failed after node-default derive", { meta: { error: errMsg$1(err) } });
8636
+ this.log.warn("config-issue recompute failed after node-default derive", { meta: { error: errMsg(err) } });
8843
8637
  });
8844
8638
  }
8845
8639
  /**
@@ -9001,7 +8795,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9001
8795
  * the node-default step tree for `this.currentEngine.format` and compute
9002
8796
  * human-readable config issues from the result:
9003
8797
  * - model substitutions (`getActiveModelSubstitutions()`, populated as a
9004
- * side effect of the `getGlobalSteps()` re-resolve below) — a step's
8798
+ * side effect of the `nodeDefaultSteps()` re-resolve below) — a step's
9005
8799
  * chosen model lacks a build for this format, so the format default
9006
8800
  * runs instead (degraded but loadable).
9007
8801
  * - zero-build steps (`collectZeroBuildIssues`) — a step whose FULL
@@ -9016,7 +8810,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9016
8810
  async recomputeConfigIssues() {
9017
8811
  this.configIssues = [];
9018
8812
  try {
9019
- const steps = await this.getGlobalSteps();
8813
+ const steps = await this.nodeDefaultSteps();
9020
8814
  if (!steps) return;
9021
8815
  const format = this.currentEngine.format;
9022
8816
  const substitutionIssues = this.getActiveModelSubstitutions().map((s) => `${s.addonId}: chose ${s.chosen}, running ${s.running} (${s.format})`);
@@ -9024,7 +8818,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9024
8818
  this.configIssues = [...substitutionIssues, ...zeroBuildIssues];
9025
8819
  } catch (err) {
9026
8820
  this.configIssues = [];
9027
- this.log.warn("engine-change config gate failed — no config issues surfaced", { meta: { error: errMsg$1(err) } });
8821
+ this.log.warn("engine-change config gate failed — no config issues surfaced", { meta: { error: errMsg(err) } });
9028
8822
  }
9029
8823
  }
9030
8824
  /**
@@ -9064,7 +8858,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9064
8858
  * `format` for the download fan-out.
9065
8859
  */
9066
8860
  async ensureModelsForCurrentSteps(format) {
9067
- const steps = await this.getGlobalSteps();
8861
+ const steps = await this.nodeDefaultSteps();
9068
8862
  if (!steps || steps.length === 0) return;
9069
8863
  for (const step of flattenSteps(steps)) {
9070
8864
  if (!step.enabled) continue;
@@ -9237,10 +9031,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9237
9031
  defaultDevice: e.engine.device
9238
9032
  };
9239
9033
  }
9240
- async getDefaultSteps(engine) {
9241
- const detectionModelId = resolveDefaultDetectionModel(engine.backend, engine.device ?? null, engine.format);
9242
- return buildDefaultStepTree(engine.format, detectionModelId);
9243
- }
9244
9034
  /**
9245
9035
  * Resolve every step's model for this node's engine format via the shared
9246
9036
  * `resolveModelForFormat`, and surface any substitution. `step.engine?.format`
@@ -9283,18 +9073,19 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9283
9073
  return [...this.modelSubstitutions.values()];
9284
9074
  }
9285
9075
  /**
9286
- * PURE node-default step tree — computed on demand, never persisted.
9076
+ * PURE node-default step tree — computed on demand, never persisted, and
9077
+ * PRIVATE (D927): it is not the model any camera ran, so no caller outside
9078
+ * this provider may read it. It serves Gate A's config-issue probe and the
9079
+ * engine provisioning's model download.
9287
9080
  *
9288
9081
  * The object-detection default is hardware-aware (this node's resolved
9289
9082
  * backend + device via `resolveDefaultDetectionModel`); every other step
9290
9083
  * keeps its flat per-format default. The result is cached in
9291
9084
  * `currentSteps` only as a memo — the cache is dropped whenever the
9292
9085
  * engine (hence model format) changes, so a re-read always reflects the
9293
- * live engine. Nothing in the live per-camera dispatch path reads this:
9294
- * it exists as the benchmark fallback (empty input steps), the Gate-A
9295
- * config-issue probe, and the "effective post-reset model" probe.
9086
+ * live engine.
9296
9087
  */
9297
- async getGlobalSteps() {
9088
+ async nodeDefaultSteps() {
9298
9089
  if (this.currentSteps) return this.currentSteps;
9299
9090
  const detectionModelId = resolveDefaultDetectionModel(this.currentEngine.backend, this.currentEngine.device ?? null, this.currentEngine.format);
9300
9091
  const defaults = buildDefaultStepTree(this.currentEngine.format, detectionModelId);
@@ -9302,10 +9093,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9302
9093
  this.currentSteps = this.resolveStepModels(defaults);
9303
9094
  return this.currentSteps;
9304
9095
  }
9305
- async getGlobalPipelineConfig() {
9306
- if (!this.currentSteps) return null;
9307
- return stepsToPipelineConfig(this.currentSteps, this.currentEngine);
9308
- }
9309
9096
  /**
9310
9097
  * Task G5 (Gate B) — pre-init config-correctness gate. PURE COMPUTE
9311
9098
  * against `this.currentEngine.format`: resolves `steps` the same way the
@@ -9349,7 +9136,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9349
9136
  issues: [{
9350
9137
  addonId: "*",
9351
9138
  kind: "unknown-device",
9352
- detail: errMsg$1(err)
9139
+ detail: errMsg(err)
9353
9140
  }],
9354
9141
  substitutions: [],
9355
9142
  format
@@ -9376,7 +9163,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9376
9163
  format
9377
9164
  };
9378
9165
  } catch (err) {
9379
- this.log.warn("validatePipeline failed — reporting a clean result", { meta: { error: errMsg$1(err) } });
9166
+ this.log.warn("validatePipeline failed — reporting a clean result", { meta: { error: errMsg(err) } });
9380
9167
  return {
9381
9168
  ok: true,
9382
9169
  issues: [],
@@ -9568,7 +9355,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9568
9355
  durationMs
9569
9356
  };
9570
9357
  } catch (err) {
9571
- const msg = errMsg$1(err);
9358
+ const msg = errMsg(err);
9572
9359
  this.log.error("Model download failed", { meta: {
9573
9360
  error: msg,
9574
9361
  modelId,
@@ -9888,7 +9675,9 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9888
9675
  this.executor = executor;
9889
9676
  const dispatchEngine = dispatchDeviceKey ? resolveDeviceEngine(dispatchDeviceKey) : runEngine;
9890
9677
  const benchmark = isBenchmarkRun(input);
9891
- const dispatchFactory = benchmark ? await this.benchmarkPools.acquire(deviceKeyOf(dispatchEngine), dispatchEngine) : dispatchDeviceKey ? await this.resolveDeviceFactory(dispatchDeviceKey) : this.engineFactory;
9678
+ const placement = benchmarkPlacementOf(benchmark, deviceKeyOf(dispatchEngine));
9679
+ if (benchmark && placement === "live-pool") this.log.info("Benchmark on an exclusive device — served by the live pool", { meta: { deviceKey: deviceKeyOf(dispatchEngine) } });
9680
+ const dispatchFactory = placement === "benchmark-pool" ? await this.benchmarkPools.acquire(deviceKeyOf(dispatchEngine), dispatchEngine) : dispatchDeviceKey ? await this.resolveDeviceFactory(dispatchDeviceKey) : this.engineFactory;
9892
9681
  const needed = enabledSteps.filter((s) => dispatchFactory.needsPoolUpdate(s));
9893
9682
  let runSteps = benchmarkSteps;
9894
9683
  const loadPolicy = dispatchLoadPolicyOf(input);
@@ -9926,24 +9715,24 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
9926
9715
  ...input.deviceId !== void 0 ? { deviceId: input.deviceId } : {},
9927
9716
  deviceKey: dispatchDeviceKeyLabel,
9928
9717
  outcome: "step-dropped"
9929
- }, dispatchDeviceKeyLabel, [model], model, "not-warm", errMsg$1(failure.error));
9718
+ }, dispatchDeviceKeyLabel, [model], model, "not-warm", errMsg(failure.error));
9930
9719
  }
9931
9720
  }
9932
- const rootModelId = resolveTreeRootModelId(tree.roots);
9721
+ const treeRoot = resolveTreeRoot(tree.roots);
9933
9722
  const rootDeviceKey = deviceKeyOf(dispatchEngine);
9934
- const stampRoot = (r) => rootModelId === void 0 ? {
9723
+ const stampRoot = (r) => treeRoot === void 0 ? {
9935
9724
  ...r,
9936
9725
  rootDeviceKey
9937
9726
  } : {
9938
9727
  ...r,
9939
- rootModelId,
9728
+ rootModelId: treeRoot.modelId,
9729
+ rootStepId: treeRoot.stepId,
9940
9730
  rootDeviceKey
9941
9731
  };
9942
9732
  if (input.replay !== true) this.clusterModelSwitchLog.note(input.deviceId ?? 0, tree);
9943
9733
  setupMs = performance.now() - wallT0 - decodeMs;
9944
9734
  const effectiveDeviceId = input.deviceId ?? 0;
9945
- const deviceOverrides = effectiveDeviceId > 0 ? await this.deviceOverrides.resolve(effectiveDeviceId) : {};
9946
- const effectiveTree = Object.keys(deviceOverrides).length > 0 ? applyDeviceOverridesToTree(tree, "object-detection", deviceOverrides) : tree;
9735
+ const effectiveTree = tree;
9947
9736
  const nativeCropProvider = this.buildNativeCropProviderFromRef(input.nativeCropRef) ?? this.buildNativeFaceCropProvider(input.frameHandle);
9948
9737
  let cropZoneBbox;
9949
9738
  if (appliesCameraGates && effectiveDeviceId > 0 && effectiveTree.roots.some((r) => r.definition.extractMode === "crop-zone")) {
@@ -10339,7 +10128,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10339
10128
  ...tags,
10340
10129
  meta: {
10341
10130
  deviceKey,
10342
- error: errMsg$1(err)
10131
+ error: errMsg(err)
10343
10132
  }
10344
10133
  });
10345
10134
  });
@@ -10376,7 +10165,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10376
10165
  throw err;
10377
10166
  }
10378
10167
  const failed = failedModelOf(err) ?? models[0] ?? "";
10379
- this.reportDispatchLoadLoss(context, deviceKey, models, failed, `failed:${flight.generation ?? "unknown"}`, errMsg$1(err));
10168
+ this.reportDispatchLoadLoss(context, deviceKey, models, failed, `failed:${flight.generation ?? "unknown"}`, errMsg(err));
10380
10169
  throw err;
10381
10170
  }
10382
10171
  }
@@ -10473,13 +10262,13 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10473
10262
  const poolModel = err instanceof StepVariantLoadError ? err.poolModel : null;
10474
10263
  let generation = 0;
10475
10264
  for (const model of failedModels) {
10476
- const outcome = this.loadGovernor.recordFailure(pool, deviceKey, model, errMsg$1(err), compileTimeout, Date.now(), poolModel, err instanceof StepVariantLoadError ? err.reason : null);
10265
+ const outcome = this.loadGovernor.recordFailure(pool, deviceKey, model, errMsg(err), compileTimeout, Date.now(), poolModel, err instanceof StepVariantLoadError ? err.reason : null);
10477
10266
  generation = outcome.generation;
10478
10267
  if (outcome.refusedNow) this.log.error("model REFUSED on this device — its compile timed out repeatedly", { meta: {
10479
10268
  deviceKey,
10480
10269
  model,
10481
10270
  compileTimeouts: outcome.compileTimeouts,
10482
- error: errMsg$1(err),
10271
+ error: errMsg(err),
10483
10272
  device: "keeps serving every other model",
10484
10273
  rearm: "pipelineExecutor.rearmInferenceDevice"
10485
10274
  } });
@@ -10540,7 +10329,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10540
10329
  this.log.info("Model downloaded successfully", { meta: { modelId: entry.id } });
10541
10330
  return;
10542
10331
  } catch (err) {
10543
- const msg = errMsg$1(err);
10332
+ const msg = errMsg(err);
10544
10333
  if (attempt < maxRetries) {
10545
10334
  const delayMs = 2e3 * Math.pow(2, attempt - 1);
10546
10335
  this.log.warn("Model download failed — retrying", { meta: {
@@ -10616,7 +10405,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10616
10405
  try {
10617
10406
  return await this.runPipelineBatchImpl(input);
10618
10407
  } catch (err) {
10619
- const msg = errMsg$1(err);
10408
+ const msg = errMsg(err);
10620
10409
  const stack = err instanceof Error ? err.stack : void 0;
10621
10410
  this.log.error("runPipelineBatch failed", { meta: {
10622
10411
  phase: "batch",
@@ -10901,9 +10690,9 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
10901
10690
  deviceKey: defaultDeviceKey,
10902
10691
  backend: this.currentEngine.backend,
10903
10692
  device: this.currentEngine.device ?? null,
10904
- error: errMsg$1(err)
10693
+ error: errMsg(err)
10905
10694
  } });
10906
- this.noteDeviceDeath(defaultDeviceKey, errMsg$1(err));
10695
+ this.noteDeviceDeath(defaultDeviceKey, errMsg(err));
10907
10696
  throw err;
10908
10697
  }
10909
10698
  this.engineFactory = factory;
@@ -11165,7 +10954,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
11165
10954
  await factory.dispose().catch(() => void 0);
11166
10955
  this.log.error("Benchmark pool failed to initialize", { meta: {
11167
10956
  deviceKey,
11168
- error: errMsg$1(err)
10957
+ error: errMsg(err)
11169
10958
  } });
11170
10959
  throw err;
11171
10960
  }
@@ -11212,7 +11001,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
11212
11001
  error: err instanceof Error ? err.message : String(err)
11213
11002
  } });
11214
11003
  await factory.dispose().catch(() => void 0);
11215
- this.noteDeviceDeath(deviceKey, errMsg$1(err));
11004
+ this.noteDeviceDeath(deviceKey, errMsg(err));
11216
11005
  throw err;
11217
11006
  }
11218
11007
  this.factoriesByDevice.set(deviceKey, factory);
@@ -11278,102 +11067,6 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
11278
11067
  this.log.info("videoPipelineSteps updated", { meta: { addons: Object.keys(sanitized).length } });
11279
11068
  return { success: true };
11280
11069
  }
11281
- /**
11282
- * Clear THIS node's executor-side PER-DEVICE settings stores — the
11283
- * per-camera step overrides the object-detection root reads via
11284
- * `applyDeviceOverridesToTree`.
11285
- *
11286
- * Node-routed (the cap's default `nodeIdMode: 'routing'`): the generated
11287
- * cap-router strips `nodeId` and dispatches to the target node, so this
11288
- * method runs ON the node being cleared and takes no argument.
11289
- *
11290
- * This is the slimmed executor leg of the orchestrator's
11291
- * `resetNodePipelineDefaults` flow. The legacy `resetToDefault` — which
11292
- * also reset a persisted GLOBAL step-tree seed nothing in the live
11293
- * per-camera path read — was removed together with that seed
11294
- * (`getGlobalSteps` is pure now, so there is nothing node-global left to
11295
- * reset here).
11296
- *
11297
- * Idempotent: clearing already-empty per-device stores is a no-op.
11298
- */
11299
- async clearDeviceOverrides() {
11300
- const clearedDevices = await this.clearAllDeviceOverrides();
11301
- this.log.info("executor per-device overrides cleared", { meta: { clearedDevices } });
11302
- return {
11303
- success: true,
11304
- clearedDevices
11305
- };
11306
- }
11307
- /**
11308
- * Auto tune (D745): list — or, unless `dryRun`, remove — the model-bound
11309
- * thresholds of the per-camera detector store. See
11310
- * `model-bound-device-overrides.ts`.
11311
- */
11312
- async clearModelBoundDeviceOverrides(input) {
11313
- const result = await clearModelBoundDeviceOverrides({
11314
- listDeviceIds: async () => {
11315
- const api = this.addonCtx?.api;
11316
- if (!api) throw new Error("clearModelBoundDeviceOverrides: ctx.api unavailable");
11317
- return (await api.deviceManager.listAll.query({ projection: "slim" })).map((d) => d.id);
11318
- },
11319
- readDeviceStore: (deviceId) => this.readDeviceStore(deviceId),
11320
- clearDeviceStore: (deviceId) => this.clearDeviceStore(deviceId),
11321
- writeDeviceStore: (deviceId, patch) => this.writeDeviceStore(deviceId, patch),
11322
- invalidate: (deviceId) => this.deviceOverrides.invalidate(deviceId),
11323
- boundKeys: collectModelBoundKeys(getStep("object-detection").getConfigSchema())
11324
- }, input);
11325
- if (!input.dryRun) for (const entry of result.entries) this.log.info("auto tune: per-camera detector thresholds cleared", {
11326
- tags: { deviceId: entry.deviceId },
11327
- meta: {
11328
- deviceId: entry.deviceId,
11329
- keys: entry.keys
11330
- }
11331
- });
11332
- for (const r of result.refused) this.log.warn("auto tune: per-camera detector thresholds not cleared", {
11333
- tags: { deviceId: r.deviceId },
11334
- meta: {
11335
- deviceId: r.deviceId,
11336
- reason: r.reason,
11337
- dryRun: input.dryRun
11338
- }
11339
- });
11340
- return result;
11341
- }
11342
- /**
11343
- * Clear the per-device pipeline-step overrides for every known device.
11344
- * Returns the count of devices whose store was cleared. There is no
11345
- * bulk-list primitive over the per-device store, so devices are
11346
- * enumerated via the device-manager and cleared one by one
11347
- * (`clearDeviceStore` is idempotent — a device with no overrides is a
11348
- * no-op). Never throws: a device-manager outage degrades to "cleared
11349
- * nothing" so the reset flow still completes.
11350
- */
11351
- async clearAllDeviceOverrides() {
11352
- const api = this.addonCtx?.api;
11353
- if (!api) return 0;
11354
- let devices = [];
11355
- try {
11356
- devices = await api.deviceManager.listAll.query({ projection: "slim" });
11357
- } catch (err) {
11358
- this.log.warn("clearDeviceOverrides: device enumeration failed — skipping per-device clear", { meta: { error: errMsg$1(err) } });
11359
- return 0;
11360
- }
11361
- let cleared = 0;
11362
- for (const device of devices) try {
11363
- await this.clearDeviceStore(device.id);
11364
- this.deviceOverrides.invalidate(device.id);
11365
- cleared++;
11366
- } catch (err) {
11367
- this.log.warn("clearDeviceOverrides: failed to clear per-device overrides for device", {
11368
- tags: { deviceId: device.id },
11369
- meta: {
11370
- deviceId: device.id,
11371
- error: errMsg$1(err)
11372
- }
11373
- });
11374
- }
11375
- return cleared;
11376
- }
11377
11070
  async listLoadedEngines() {
11378
11071
  const out = [];
11379
11072
  if (this.engineFactory) {
@@ -11560,7 +11253,7 @@ var DetectionPipelineProvider = class DetectionPipelineProvider {
11560
11253
  frame
11561
11254
  };
11562
11255
  } catch (err) {
11563
- const msg = errMsg$1(err);
11256
+ const msg = errMsg(err);
11564
11257
  this.log.error("failed", { meta: {
11565
11258
  phase: "audio-test",
11566
11259
  error: msg
@@ -11620,7 +11313,6 @@ function buildSchemaSlots(formats, modelsDir, customByStep) {
11620
11313
  defaultModelId: step.defaultModelId,
11621
11314
  ...step.defaultModelIdByFormat ? { defaultModelIdByFormat: { ...step.defaultModelIdByFormat } } : {},
11622
11315
  ...step.enabledByDefault !== void 0 ? { enabledByDefault: step.enabledByDefault } : {},
11623
- ...step.backfillIntoExistingOverrides !== void 0 ? { backfillIntoExistingOverrides: step.backfillIntoExistingOverrides } : {},
11624
11316
  defaultConfidence: step.defaultConfidence,
11625
11317
  ...step.group ? { group: step.group } : {},
11626
11318
  ...configSchemaWithRoots.length > 0 ? { configSchema: configSchemaWithRoots } : {}
@@ -11668,7 +11360,7 @@ function resolveChildSlots(slot) {
11668
11360
  }
11669
11361
  /**
11670
11362
  * V2 default: the node-default step tree (never persisted — see
11671
- * `getGlobalSteps`). The core detection + recognition steps are enabled; every
11363
+ * `nodeDefaultSteps`). The core detection + recognition steps are enabled; every
11672
11364
  * optional step is present with its catalog `enabledByDefault` (the animal and
11673
11365
  * vehicle classifiers on — their answer comes from the root model when it
11674
11366
  * declares them, D736 — the bird classifier and segmentation off).
@@ -11710,27 +11402,6 @@ function buildDefaultStepTree(format, objectDetectionModelId) {
11710
11402
  if (audioStep) steps.push(audioStep);
11711
11403
  return steps;
11712
11404
  }
11713
- function stepsToPipelineConfig(steps, engine) {
11714
- const toNode = (step) => ({
11715
- step: step.addonId,
11716
- addon: step.addonId,
11717
- configOverride: {
11718
- modelId: step.modelId,
11719
- ...step.settings
11720
- },
11721
- children: step.children.map(toNode)
11722
- });
11723
- const videoSteps = steps.filter((s) => s.slot !== "audio-classifier");
11724
- const audioStep = steps.find((s) => s.slot === "audio-classifier" && s.enabled);
11725
- return {
11726
- engine,
11727
- video: videoSteps.map(toNode),
11728
- ...audioStep ? {
11729
- audio: toNode(audioStep),
11730
- audioEngine: engine
11731
- } : {}
11732
- };
11733
- }
11734
11405
  /** Flatten a step tree into a flat list (DFS) — delegates to shared utility. */
11735
11406
  function flattenSteps(steps) {
11736
11407
  return flattenEnabledVideoSteps(steps);
@@ -11791,22 +11462,6 @@ function availableFormatsForStep(addonId) {
11791
11462
  return [];
11792
11463
  }
11793
11464
  }
11794
- /**
11795
- * Return a shallow-cloned executable tree with `rootStepId`'s `settings`
11796
- * merged with `overrides` (per-device values win). Non-matching root steps
11797
- * pass through unchanged. Used by `runFrame` to apply per-device detection
11798
- * settings without rebuilding the tree per frame. A model-bound value (D738)
11799
- * applies only while the model it was made for is the one the root RUNS.
11800
- */
11801
- function applyDeviceOverridesToTree(tree, rootStepId, overrides) {
11802
- return { roots: tree.roots.map((root) => root.stepId === rootStepId ? {
11803
- ...root,
11804
- settings: {
11805
- ...root.settings,
11806
- ...resolveOperatorSettingsForModel(rootStepId, overrides, root.modelId)
11807
- }
11808
- } : root) };
11809
- }
11810
11465
  //#endregion
11811
11466
  //#region src/detection-pipeline/python-readiness.ts
11812
11467
  /**
@@ -11921,20 +11576,6 @@ function isProfileSliderKey(key) {
11921
11576
  }
11922
11577
  var DetectionPipelineAddon = class extends BaseAddon {
11923
11578
  provider = null;
11924
- /**
11925
- * An operator's own write drops the mirror the frame path reads.
11926
- *
11927
- * This override is the half of `device-override-mirror.ts` that keeps it from
11928
- * being the second authority D224 forbids: `BaseAddon.updateDeviceSettings`
11929
- * writes THIS addon's `<addonId>:addon-devices` row, so the write and the
11930
- * mirror are in one process and the write invalidates. Without it the
11931
- * operator's own change would be the one read the mirror got wrong, which is
11932
- * the exact failure D224 records.
11933
- */
11934
- async updateDeviceSettings(deviceId, patch) {
11935
- await super.updateDeviceSettings(deviceId, patch);
11936
- this.provider?.deviceOverrides.invalidate(deviceId);
11937
- }
11938
11579
  /** Last non-null probed hardware PER NODE — reused when the probe transiently
11939
11580
  * returns null so offered backends / device lists don't collapse. Keyed by
11940
11581
  * node because the hub addon probes other nodes when serving their config.