@camstack/addon-pipeline 1.2.118 → 1.2.120

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 (36) hide show
  1. package/dist/{addon-utils-DJSN5h8c.js → addon-utils-MH-YN_oH.js} +1 -1
  2. package/dist/audio-analyzer/index.js +3 -3
  3. package/dist/audio-analyzer/index.mjs +2 -2
  4. package/dist/detection-pipeline/index.js +171 -167
  5. package/dist/detection-pipeline/index.mjs +169 -165
  6. package/dist/{dist-B763E61Y.mjs → dist-CmqBKO-v.mjs} +100 -4
  7. package/dist/{dist-BkO76jAp.js → dist-CvpyuIHg.js} +105 -3
  8. package/dist/{event-loop-stall-monitor-28f4R0JN.js → event-loop-stall-monitor-BOHxP7W6.js} +1 -1
  9. package/dist/{event-loop-stall-monitor-CYEvvp2Z.mjs → event-loop-stall-monitor-kh4gmJ-6.mjs} +1 -1
  10. package/dist/{lazy-sharp-BaPl5mRa.js → lazy-sharp-BzJLgOw9.js} +1 -1
  11. package/dist/motion-wasm/index.js +2 -2
  12. package/dist/motion-wasm/index.mjs +1 -1
  13. package/dist/pipeline-runner/index.js +12 -14
  14. package/dist/pipeline-runner/index.mjs +11 -13
  15. package/dist/{process-memory-CK3FnKyZ.mjs → process-memory-C2vefk7-.mjs} +1 -1
  16. package/dist/{process-memory-BCQJFZZg.js → process-memory-U6kkHBR7.js} +1 -1
  17. package/dist/recorder/index.js +2 -2
  18. package/dist/recorder/index.mjs +1 -1
  19. package/dist/segment-demux-js-CTgNaQTI.js +7310 -0
  20. package/dist/segment-demux-js-xjK1LW_t.mjs +7288 -0
  21. package/dist/session-decode/decode-worker-child.js +2 -2
  22. package/dist/session-decode/decode-worker-child.mjs +1 -1
  23. package/dist/stream-broker/_stub.js +2 -2
  24. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CxgvfkxP.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BdP-MWLF.mjs} +2 -2
  25. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Cs8bmrWP.mjs +26 -0
  26. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BAMyzCWw.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-D-NFPV_g.mjs} +1 -1
  27. package/dist/stream-broker/demux-worker-child.js +46 -0
  28. package/dist/stream-broker/demux-worker-child.mjs +47 -0
  29. package/dist/stream-broker/{hostInit-CTkpxp3w.mjs → hostInit-zKdlTmuo.mjs} +2 -2
  30. package/dist/stream-broker/index.js +381 -7405
  31. package/dist/stream-broker/index.mjs +382 -7403
  32. package/dist/stream-broker/remoteEntry.js +1 -1
  33. package/dist/{worker-protocol-D_2QaXYr.mjs → worker-protocol-CElzXfEW.mjs} +1 -1
  34. package/dist/{worker-protocol-owR7WMRP.js → worker-protocol-DGYGCx9K.js} +1 -1
  35. package/package.json +1 -1
  36. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CL6Lgzdj.mjs +0 -26
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-BkO76jAp.js");
1
+ const require_dist = require("./dist-CvpyuIHg.js");
2
2
  require("node:crypto");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_dist.__toESM(node_path, 1);
@@ -2,9 +2,9 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-BkO76jAp.js");
6
- const require_process_memory = require("../process-memory-BCQJFZZg.js");
7
- const require_addon_utils = require("../addon-utils-DJSN5h8c.js");
5
+ const require_dist = require("../dist-CvpyuIHg.js");
6
+ const require_process_memory = require("../process-memory-U6kkHBR7.js");
7
+ const require_addon_utils = require("../addon-utils-MH-YN_oH.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_dist.__toESM(node_path);
10
10
  let node_fs = require("node:fs");
@@ -1,6 +1,6 @@
1
1
  import { n as __require } from "../chunk-DnnnRqeS.mjs";
2
- import { A as audioAnalyzerCapability, Et as hydrateSchema, _ as HF_BASE_URL, ct as resolvePoolMemoryPolicy, ht as errMsg, k as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, q as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, x as PoolMemoryWatchdog, xt as BaseAddon } from "../dist-B763E61Y.mjs";
3
- import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-CK3FnKyZ.mjs";
2
+ import { A as audioAnalyzerCapability, Dt as hydrateSchema, J as mapAudioLabelToMacro, St as BaseAddon, _ as HF_BASE_URL, gt as errMsg, k as audioAnalysisCapability, lt as resolvePoolMemoryPolicy, n as AUDIO_BACKEND_CHOICES, s as DEFAULT_AUDIO_ANALYZER_CONFIG, x as PoolMemoryWatchdog } from "../dist-CmqBKO-v.mjs";
3
+ import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-C2vefk7-.mjs";
4
4
  import { i as downloadFile } from "../addon-utils-CgBCF-mE.mjs";
5
5
  import * as path$1 from "node:path";
6
6
  import * as fs from "node:fs";
@@ -2,11 +2,11 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_dist = require("../dist-BkO76jAp.js");
6
- const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-28f4R0JN.js");
7
- const require_lazy_sharp = require("../lazy-sharp-BaPl5mRa.js");
8
- const require_process_memory = require("../process-memory-BCQJFZZg.js");
9
- const require_addon_utils = require("../addon-utils-DJSN5h8c.js");
5
+ const require_dist = require("../dist-CvpyuIHg.js");
6
+ const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-BOHxP7W6.js");
7
+ const require_lazy_sharp = require("../lazy-sharp-BzJLgOw9.js");
8
+ const require_process_memory = require("../process-memory-U6kkHBR7.js");
9
+ const require_addon_utils = require("../addon-utils-MH-YN_oH.js");
10
10
  let sharp = require("sharp");
11
11
  sharp = require_dist.__toESM(sharp);
12
12
  let node_child_process = require("node:child_process");
@@ -256,6 +256,113 @@ function normalizeEngineNodeId(rawNodeId) {
256
256
  return raw.includes("/") ? raw.split("/")[0] ?? "hub" : raw;
257
257
  }
258
258
  //#endregion
259
+ //#region src/shared/cluster-model-source.ts
260
+ /**
261
+ * Where the runner gets the ONE cluster model choice per cluster-scoped step.
262
+ *
263
+ * The sibling of `crop-convention-source.ts`, and deliberately built the same
264
+ * way, because it answers the neighbouring half of the same question: the crop
265
+ * convention decides WHAT pixels the encoder sees, this decides WHICH encoder
266
+ * sees them. Both are cluster-wide, both are read by the runner from the
267
+ * `pipeline-orchestrator` global settings over the hub-routed `addon-settings`
268
+ * cap, both pass NO `nodeId`.
269
+ *
270
+ * ## Deliberately NOT node-scoped, and not on the attach config
271
+ *
272
+ * With a `nodeId` the settings cap would project that node's scoped value and
273
+ * two nodes could embed into one index with two encoders — the original defect,
274
+ * relocated to the transport. And the attach config is the wrong carrier for
275
+ * the same reason it was wrong for the crop: eleven builders construct a
276
+ * `RunnerCameraConfig`, a cluster-wide constant threaded through eleven
277
+ * builders eventually reaches ten of them, and the cameras attached by the
278
+ * forgotten one quietly write a foreign feature space into the shared index.
279
+ *
280
+ * ## Why the failure mode keeps the last value
281
+ *
282
+ * A failed read must never revert to the registry default MID-PASS: that would
283
+ * silently change what every remaining vector of that dispatch means, which is
284
+ * the exact class of harm the scope exists to prevent. So a failure keeps the
285
+ * last known row and says so, loudly, once per failure.
286
+ */
287
+ /**
288
+ * The addon whose GLOBAL settings own the cluster row. Same owner as the crop
289
+ * convention and the native-frame lease: hub-resident and neutral between the
290
+ * addons that read it (post-analysis pins it for a re-embed pass, the runner
291
+ * enforces it live — neither should own a value the other depends on).
292
+ */
293
+ var CLUSTER_MODEL_OWNER_ADDON_ID = "pipeline-orchestrator";
294
+ /** TTL-cached read of the cluster model row. */
295
+ var ClusterModelSource = class {
296
+ models = require_dist.DEFAULT_CLUSTER_STEP_MODELS;
297
+ settings = require_dist.DEFAULT_CLUSTER_STEP_SETTINGS;
298
+ lastReadAtMs = Number.NEGATIVE_INFINITY;
299
+ inFlight = null;
300
+ logger;
301
+ now;
302
+ ttlMs;
303
+ constructor(options) {
304
+ this.logger = options.logger;
305
+ this.now = options.now ?? (() => Date.now());
306
+ this.ttlMs = options.ttlMs ?? 6e4;
307
+ }
308
+ /** The row in force right now — the registry defaults until a read lands. */
309
+ current() {
310
+ return this.models;
311
+ }
312
+ /** Cluster-scoped step knobs in force right now (admission floors, …). */
313
+ currentSettings() {
314
+ return this.settings;
315
+ }
316
+ /**
317
+ * Re-read if the cached row has expired. Concurrent callers share one
318
+ * in-flight read; a failure keeps the LAST KNOWN row.
319
+ */
320
+ async refresh(api) {
321
+ if (api === void 0) return this.models;
322
+ if (this.now() - this.lastReadAtMs < this.ttlMs) return this.models;
323
+ this.inFlight ??= this.read(api).finally(() => {
324
+ this.inFlight = null;
325
+ });
326
+ await this.inFlight;
327
+ return this.models;
328
+ }
329
+ async read(api) {
330
+ try {
331
+ const view = await api.addonSettings.getGlobalSettings.query({ addonId: CLUSTER_MODEL_OWNER_ADDON_ID });
332
+ const next = require_dist.pickClusterStepModels(view);
333
+ const nextSettings = require_dist.pickClusterStepSettings(view);
334
+ this.lastReadAtMs = this.now();
335
+ const changed = Object.keys(next).filter((stepId) => next[stepId] !== this.models[stepId]);
336
+ const settingsChanged = Object.keys(nextSettings).some((stepId) => {
337
+ const from = this.settings[stepId] ?? {};
338
+ const to = nextSettings[stepId] ?? {};
339
+ return [...new Set([...Object.keys(from), ...Object.keys(to)])].some((key) => from[key] !== to[key]);
340
+ });
341
+ if (changed.length > 0) {
342
+ this.logger.info("cluster step model changed — vectors already stored by the previous model need a re-embed pass", { meta: { changed: changed.map((stepId) => ({
343
+ stepId,
344
+ from: this.models[stepId],
345
+ to: next[stepId]
346
+ })) } });
347
+ this.models = next;
348
+ }
349
+ if (settingsChanged) {
350
+ this.logger.info("cluster step settings changed", { meta: {
351
+ from: { ...this.settings },
352
+ to: { ...nextSettings }
353
+ } });
354
+ this.settings = nextSettings;
355
+ }
356
+ } catch (err) {
357
+ this.logger.warn("cluster step model read failed — keeping the last known row", { meta: {
358
+ owner: CLUSTER_MODEL_OWNER_ADDON_ID,
359
+ inUse: { ...this.models },
360
+ error: err instanceof Error ? err.message : String(err)
361
+ } });
362
+ }
363
+ }
364
+ };
365
+ //#endregion
259
366
  //#region src/detection-pipeline/default-detection-model.ts
260
367
  /** The object-detection step id — the only slot this resolver applies to. */
261
368
  var OBJECT_DETECTION_STEP_ID = "object-detection";
@@ -2601,6 +2708,59 @@ var EngineProvisioner = class {
2601
2708
  }
2602
2709
  };
2603
2710
  //#endregion
2711
+ //#region src/session-decode/frame-view-payload.ts
2712
+ var FRAME_VIEW_PAYLOAD_POLICY = "jpeg";
2713
+ //#endregion
2714
+ //#region src/detection-pipeline/root-frame-view.ts
2715
+ /** Resolve the pre-padding content requested from the decode worker for one root. */
2716
+ function resolveRootFrameViewSpec(model, source, crop, format = FRAME_VIEW_PAYLOAD_POLICY) {
2717
+ const sourceWidth = crop?.width ?? source.width;
2718
+ const sourceHeight = crop?.height ?? source.height;
2719
+ if (model.preprocessMode !== "letterbox") return {
2720
+ ...crop ? { crop } : {},
2721
+ content: {
2722
+ width: model.inputSize.width,
2723
+ height: model.inputSize.height
2724
+ },
2725
+ fit: "stretch",
2726
+ format
2727
+ };
2728
+ const scale = Math.min(model.inputSize.width / sourceWidth, model.inputSize.height / sourceHeight);
2729
+ return {
2730
+ ...crop ? { crop } : {},
2731
+ content: {
2732
+ width: Math.max(1, Math.round(sourceWidth * scale)),
2733
+ height: Math.max(1, Math.round(sourceHeight * scale))
2734
+ },
2735
+ fit: "contain",
2736
+ format
2737
+ };
2738
+ }
2739
+ //#endregion
2740
+ //#region src/detection-pipeline/frame-ref-view-provider.ts
2741
+ var LocalFrameRefMissError = class extends Error {
2742
+ reason;
2743
+ constructor(reason) {
2744
+ super(`local frameRef miss: ${reason}`);
2745
+ this.reason = reason;
2746
+ this.name = "LocalFrameRefMissError";
2747
+ }
2748
+ };
2749
+ /** Bind one registry lease for all heterogeneous roots of a pipeline invocation. */
2750
+ function createRootFrameViewResolver(registry, ref) {
2751
+ const lease = registry.acquire(ref);
2752
+ if (!lease) throw new LocalFrameRefMissError(ref.registryId === registry.registryId ? "stale-ref" : "foreign-registry");
2753
+ const resolve = async (root, crop) => {
2754
+ const model = root.definition.models.find((candidate) => candidate.id === root.modelId);
2755
+ if (!model) throw new Error(`frame view model not found: ${root.modelId}`);
2756
+ const spec = resolveRootFrameViewSpec(model, ref, crop);
2757
+ const result = await lease.resolve(spec);
2758
+ if (result.kind === "miss") throw new LocalFrameRefMissError(result.reason);
2759
+ return result;
2760
+ };
2761
+ return Object.assign(resolve, { release: (reason) => lease.release(reason) });
2762
+ }
2763
+ //#endregion
2604
2764
  //#region src/detection-pipeline/pipeline/crop-utils.ts
2605
2765
  /**
2606
2766
  * Crop utilities — ROI extraction and bbox coordinate transforms.
@@ -5186,59 +5346,6 @@ function capitalize(s) {
5186
5346
  return s.charAt(0).toUpperCase() + s.slice(1);
5187
5347
  }
5188
5348
  //#endregion
5189
- //#region src/session-decode/frame-view-payload.ts
5190
- var FRAME_VIEW_PAYLOAD_POLICY = "jpeg";
5191
- //#endregion
5192
- //#region src/detection-pipeline/root-frame-view.ts
5193
- /** Resolve the pre-padding content requested from the decode worker for one root. */
5194
- function resolveRootFrameViewSpec(model, source, crop, format = FRAME_VIEW_PAYLOAD_POLICY) {
5195
- const sourceWidth = crop?.width ?? source.width;
5196
- const sourceHeight = crop?.height ?? source.height;
5197
- if (model.preprocessMode !== "letterbox") return {
5198
- ...crop ? { crop } : {},
5199
- content: {
5200
- width: model.inputSize.width,
5201
- height: model.inputSize.height
5202
- },
5203
- fit: "stretch",
5204
- format
5205
- };
5206
- const scale = Math.min(model.inputSize.width / sourceWidth, model.inputSize.height / sourceHeight);
5207
- return {
5208
- ...crop ? { crop } : {},
5209
- content: {
5210
- width: Math.max(1, Math.round(sourceWidth * scale)),
5211
- height: Math.max(1, Math.round(sourceHeight * scale))
5212
- },
5213
- fit: "contain",
5214
- format
5215
- };
5216
- }
5217
- //#endregion
5218
- //#region src/detection-pipeline/frame-ref-view-provider.ts
5219
- var LocalFrameRefMissError = class extends Error {
5220
- reason;
5221
- constructor(reason) {
5222
- super(`local frameRef miss: ${reason}`);
5223
- this.reason = reason;
5224
- this.name = "LocalFrameRefMissError";
5225
- }
5226
- };
5227
- /** Bind one registry lease for all heterogeneous roots of a pipeline invocation. */
5228
- function createRootFrameViewResolver(registry, ref) {
5229
- const lease = registry.acquire(ref);
5230
- if (!lease) throw new LocalFrameRefMissError(ref.registryId === registry.registryId ? "stale-ref" : "foreign-registry");
5231
- const resolve = async (root, crop) => {
5232
- const model = root.definition.models.find((candidate) => candidate.id === root.modelId);
5233
- if (!model) throw new Error(`frame view model not found: ${root.modelId}`);
5234
- const spec = resolveRootFrameViewSpec(model, ref, crop);
5235
- const result = await lease.resolve(spec);
5236
- if (result.kind === "miss") throw new LocalFrameRefMissError(result.reason);
5237
- return result;
5238
- };
5239
- return Object.assign(resolve, { release: (reason) => lease.release(reason) });
5240
- }
5241
- //#endregion
5242
5349
  //#region src/detection-pipeline/pipeline/native-crop-compose.ts
5243
5350
  /** Clamp `v` into `[lo, hi]`. */
5244
5351
  function clamp(v, lo, hi) {
@@ -5367,7 +5474,10 @@ function mergeCustomModels(staticModels, customModels) {
5367
5474
  for (const m of customModels) {
5368
5475
  if (seen.has(m.id)) continue;
5369
5476
  seen.add(m.id);
5370
- merged.push(m);
5477
+ merged.push({
5478
+ ...m,
5479
+ provider: require_dist.inferModelProvider(m)
5480
+ });
5371
5481
  }
5372
5482
  return merged;
5373
5483
  }
@@ -5666,113 +5776,6 @@ function applyZoneRuleGate(result, zones, rules) {
5666
5776
  };
5667
5777
  }
5668
5778
  //#endregion
5669
- //#region src/shared/cluster-model-source.ts
5670
- /**
5671
- * Where the runner gets the ONE cluster model choice per cluster-scoped step.
5672
- *
5673
- * The sibling of `crop-convention-source.ts`, and deliberately built the same
5674
- * way, because it answers the neighbouring half of the same question: the crop
5675
- * convention decides WHAT pixels the encoder sees, this decides WHICH encoder
5676
- * sees them. Both are cluster-wide, both are read by the runner from the
5677
- * `pipeline-orchestrator` global settings over the hub-routed `addon-settings`
5678
- * cap, both pass NO `nodeId`.
5679
- *
5680
- * ## Deliberately NOT node-scoped, and not on the attach config
5681
- *
5682
- * With a `nodeId` the settings cap would project that node's scoped value and
5683
- * two nodes could embed into one index with two encoders — the original defect,
5684
- * relocated to the transport. And the attach config is the wrong carrier for
5685
- * the same reason it was wrong for the crop: eleven builders construct a
5686
- * `RunnerCameraConfig`, a cluster-wide constant threaded through eleven
5687
- * builders eventually reaches ten of them, and the cameras attached by the
5688
- * forgotten one quietly write a foreign feature space into the shared index.
5689
- *
5690
- * ## Why the failure mode keeps the last value
5691
- *
5692
- * A failed read must never revert to the registry default MID-PASS: that would
5693
- * silently change what every remaining vector of that dispatch means, which is
5694
- * the exact class of harm the scope exists to prevent. So a failure keeps the
5695
- * last known row and says so, loudly, once per failure.
5696
- */
5697
- /**
5698
- * The addon whose GLOBAL settings own the cluster row. Same owner as the crop
5699
- * convention and the native-frame lease: hub-resident and neutral between the
5700
- * addons that read it (post-analysis pins it for a re-embed pass, the runner
5701
- * enforces it live — neither should own a value the other depends on).
5702
- */
5703
- var CLUSTER_MODEL_OWNER_ADDON_ID = "pipeline-orchestrator";
5704
- /** TTL-cached read of the cluster model row. */
5705
- var ClusterModelSource = class {
5706
- models = require_dist.DEFAULT_CLUSTER_STEP_MODELS;
5707
- settings = require_dist.DEFAULT_CLUSTER_STEP_SETTINGS;
5708
- lastReadAtMs = Number.NEGATIVE_INFINITY;
5709
- inFlight = null;
5710
- logger;
5711
- now;
5712
- ttlMs;
5713
- constructor(options) {
5714
- this.logger = options.logger;
5715
- this.now = options.now ?? (() => Date.now());
5716
- this.ttlMs = options.ttlMs ?? 6e4;
5717
- }
5718
- /** The row in force right now — the registry defaults until a read lands. */
5719
- current() {
5720
- return this.models;
5721
- }
5722
- /** Cluster-scoped step knobs in force right now (admission floors, …). */
5723
- currentSettings() {
5724
- return this.settings;
5725
- }
5726
- /**
5727
- * Re-read if the cached row has expired. Concurrent callers share one
5728
- * in-flight read; a failure keeps the LAST KNOWN row.
5729
- */
5730
- async refresh(api) {
5731
- if (api === void 0) return this.models;
5732
- if (this.now() - this.lastReadAtMs < this.ttlMs) return this.models;
5733
- this.inFlight ??= this.read(api).finally(() => {
5734
- this.inFlight = null;
5735
- });
5736
- await this.inFlight;
5737
- return this.models;
5738
- }
5739
- async read(api) {
5740
- try {
5741
- const view = await api.addonSettings.getGlobalSettings.query({ addonId: CLUSTER_MODEL_OWNER_ADDON_ID });
5742
- const next = require_dist.pickClusterStepModels(view);
5743
- const nextSettings = require_dist.pickClusterStepSettings(view);
5744
- this.lastReadAtMs = this.now();
5745
- const changed = Object.keys(next).filter((stepId) => next[stepId] !== this.models[stepId]);
5746
- const settingsChanged = Object.keys(nextSettings).some((stepId) => {
5747
- const from = this.settings[stepId] ?? {};
5748
- const to = nextSettings[stepId] ?? {};
5749
- return [...new Set([...Object.keys(from), ...Object.keys(to)])].some((key) => from[key] !== to[key]);
5750
- });
5751
- if (changed.length > 0) {
5752
- this.logger.info("cluster step model changed — vectors already stored by the previous model need a re-embed pass", { meta: { changed: changed.map((stepId) => ({
5753
- stepId,
5754
- from: this.models[stepId],
5755
- to: next[stepId]
5756
- })) } });
5757
- this.models = next;
5758
- }
5759
- if (settingsChanged) {
5760
- this.logger.info("cluster step settings changed", { meta: {
5761
- from: { ...this.settings },
5762
- to: { ...nextSettings }
5763
- } });
5764
- this.settings = nextSettings;
5765
- }
5766
- } catch (err) {
5767
- this.logger.warn("cluster step model read failed — keeping the last known row", { meta: {
5768
- owner: CLUSTER_MODEL_OWNER_ADDON_ID,
5769
- inUse: { ...this.models },
5770
- error: err instanceof Error ? err.message : String(err)
5771
- } });
5772
- }
5773
- }
5774
- };
5775
- //#endregion
5776
5779
  //#region src/detection-pipeline/provider.ts
5777
5780
  /**
5778
5781
  * DetectionPipelineProvider — implements IPipelineExecutorProvider.
@@ -8763,7 +8766,8 @@ function buildSchemaSlots(formats, modelsDir, customByStep) {
8763
8766
  sizeMB: entry.sizeMB
8764
8767
  }])),
8765
8768
  ...m.group ? { group: m.group } : {},
8766
- ...m.legacy !== void 0 ? { legacy: m.legacy } : {}
8769
+ ...m.legacy !== void 0 ? { legacy: m.legacy } : {},
8770
+ provider: m.provider ?? "camstack"
8767
8771
  })),
8768
8772
  defaultModelId: step.defaultModelId,
8769
8773
  ...step.defaultModelIdByFormat ? { defaultModelIdByFormat: { ...step.defaultModelIdByFormat } } : {},