@camstack/addon-pipeline-orchestrator 1.1.42 → 1.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-D0Ou9G9F.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DWO6Xr0a.mjs} +2 -2
- package/dist/{hostInit-DanmsltL.mjs → hostInit-DJrBygJm.mjs} +2 -2
- package/dist/index.js +100 -8
- package/dist/index.mjs +100 -8
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.1.
|
|
21
|
+
version: "1.1.41",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_pipeline_orchestrator_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.1.
|
|
36
|
+
version: "1.1.33",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_pipeline_orchestrator_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.1.
|
|
39
|
+
version: "1.1.41",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -99,7 +99,7 @@ async function r() {
|
|
|
99
99
|
}
|
|
100
100
|
},
|
|
101
101
|
"@camstack/ui-library": {
|
|
102
|
-
version: "1.1.
|
|
102
|
+
version: "1.1.33",
|
|
103
103
|
scope: "default",
|
|
104
104
|
shareConfig: {
|
|
105
105
|
singleton: !0,
|
package/dist/index.js
CHANGED
|
@@ -11001,6 +11001,7 @@ var PipelineAddonSchemaSchema = object({
|
|
|
11001
11001
|
defaultModelId: string(),
|
|
11002
11002
|
defaultModelIdByFormat: record(string(), string()).optional(),
|
|
11003
11003
|
enabledByDefault: boolean().optional(),
|
|
11004
|
+
backfillIntoExistingOverrides: boolean().optional(),
|
|
11004
11005
|
defaultConfidence: number(),
|
|
11005
11006
|
group: string().optional(),
|
|
11006
11007
|
configSchema: array(ConfigFieldBridge).readonly().optional()
|
|
@@ -28914,7 +28915,7 @@ function resolvePipeline(agentSettings, cameraSettings, agentNodeId, catalog) {
|
|
|
28914
28915
|
const cam = cameraSettings ?? {};
|
|
28915
28916
|
const wholesale = cam.pipelineByAgent?.[agentNodeId];
|
|
28916
28917
|
if (wholesale) return {
|
|
28917
|
-
steps: wholesale.steps,
|
|
28918
|
+
steps: mergeEnabledByDefaultSteps(wholesale.steps, catalog),
|
|
28918
28919
|
audio: wholesale.audio ? {
|
|
28919
28920
|
modelId: wholesale.audio.modelId,
|
|
28920
28921
|
enabled: wholesale.audio.enabled
|
|
@@ -29021,6 +29022,94 @@ function buildTreeFromAddons(enabled, catalog) {
|
|
|
29021
29022
|
}
|
|
29022
29023
|
return roots;
|
|
29023
29024
|
}
|
|
29025
|
+
/**
|
|
29026
|
+
* Back-fill catalog steps EXPLICITLY flagged `backfillIntoExistingOverrides`
|
|
29027
|
+
* but ENTIRELY ABSENT from an existing step tree — the wholesale-override
|
|
29028
|
+
* analogue of {@link seedAgentAddonDefaults}, which already grows per-agent
|
|
29029
|
+
* `addonDefaults` when the catalog adds a new addon.
|
|
29030
|
+
*
|
|
29031
|
+
* Why it's needed: a `pipelineByAgent` wholesale override SNAPSHOTS the full
|
|
29032
|
+
* tree. A step introduced AFTER the snapshot (e.g. `clip-embedding` for object
|
|
29033
|
+
* semantic search) would otherwise never reach that camera.
|
|
29034
|
+
*
|
|
29035
|
+
* Why the flag (not `enabledByDefault`): absence-from-a-snapshot is ambiguous —
|
|
29036
|
+
* it can mean "predates this step" OR "operator deliberately pruned it". A
|
|
29037
|
+
* broad "back-fill every default-on step" would resurrect deliberate removals
|
|
29038
|
+
* of long-existing steps (face-detection, etc.), an operator-intent
|
|
29039
|
+
* regression. Only a step that opts in via `backfillIntoExistingOverrides`
|
|
29040
|
+
* (set on genuinely-new default steps ONLY) re-enters existing overrides.
|
|
29041
|
+
*
|
|
29042
|
+
* Non-destructive by design:
|
|
29043
|
+
* - Only steps whose id is absent from the WHOLE tree are added. A step the
|
|
29044
|
+
* operator has already seen — present anywhere, even `enabled: false` —
|
|
29045
|
+
* is left exactly as-is (its enabled flag is honoured).
|
|
29046
|
+
* - Only `backfillIntoExistingOverrides === true` addons are candidates.
|
|
29047
|
+
* Every other step (including long-standing default-on members) is left
|
|
29048
|
+
* untouched, so a deliberately-pruned override stays pruned.
|
|
29049
|
+
* - Audio-classifier addons are skipped — audio lives in
|
|
29050
|
+
* `CameraPipelineConfig.audio`, never in the video `steps` tree.
|
|
29051
|
+
* - A candidate attaches by catalog compat (its `inputClasses` overlap a
|
|
29052
|
+
* present node's `outputClasses`), mirroring {@link buildTreeFromAddons}.
|
|
29053
|
+
* A candidate with non-empty `inputClasses` and NO compatible parent is
|
|
29054
|
+
* dropped (never re-rooted) so a crop-scoped embedder never regresses to
|
|
29055
|
+
* running on the full frame. Empty `inputClasses` ⇒ a genuine root step.
|
|
29056
|
+
*/
|
|
29057
|
+
function mergeEnabledByDefaultSteps(steps, catalog) {
|
|
29058
|
+
if (steps.length === 0) return steps;
|
|
29059
|
+
const present = /* @__PURE__ */ new Set();
|
|
29060
|
+
const collect = (nodes) => {
|
|
29061
|
+
for (const n of nodes) {
|
|
29062
|
+
present.add(n.addonId);
|
|
29063
|
+
if (n.children?.length) collect(n.children);
|
|
29064
|
+
}
|
|
29065
|
+
};
|
|
29066
|
+
collect(steps);
|
|
29067
|
+
const catalogById = /* @__PURE__ */ new Map();
|
|
29068
|
+
for (const slot of catalog.slots) for (const addon of slot.addons) catalogById.set(addon.id, addon);
|
|
29069
|
+
const newRoots = [];
|
|
29070
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
29071
|
+
for (const slot of catalog.slots) {
|
|
29072
|
+
if (slot.id === "audio-classifier") continue;
|
|
29073
|
+
for (const addon of slot.addons) {
|
|
29074
|
+
if (addon.backfillIntoExistingOverrides !== true) continue;
|
|
29075
|
+
if (present.has(addon.id)) continue;
|
|
29076
|
+
const node = {
|
|
29077
|
+
addonId: addon.id,
|
|
29078
|
+
enabled: true,
|
|
29079
|
+
children: []
|
|
29080
|
+
};
|
|
29081
|
+
const inputs = addon.inputClasses;
|
|
29082
|
+
if (!inputs || inputs.length === 0) {
|
|
29083
|
+
newRoots.push(node);
|
|
29084
|
+
continue;
|
|
29085
|
+
}
|
|
29086
|
+
let parentId = null;
|
|
29087
|
+
for (const presentId of present) {
|
|
29088
|
+
const meta = catalogById.get(presentId);
|
|
29089
|
+
if (!meta) continue;
|
|
29090
|
+
if (meta.outputClasses.some((c) => inputs.includes(c))) {
|
|
29091
|
+
parentId = presentId;
|
|
29092
|
+
break;
|
|
29093
|
+
}
|
|
29094
|
+
}
|
|
29095
|
+
if (!parentId) continue;
|
|
29096
|
+
const list = childrenByParent.get(parentId) ?? [];
|
|
29097
|
+
list.push(node);
|
|
29098
|
+
childrenByParent.set(parentId, list);
|
|
29099
|
+
}
|
|
29100
|
+
}
|
|
29101
|
+
if (childrenByParent.size === 0 && newRoots.length === 0) return steps;
|
|
29102
|
+
const attach = (nodes) => nodes.map((n) => {
|
|
29103
|
+
const rebuiltChildren = attach(n.children ?? []);
|
|
29104
|
+
const extra = childrenByParent.get(n.addonId) ?? [];
|
|
29105
|
+
const mergedChildren = [...rebuiltChildren, ...extra];
|
|
29106
|
+
return mergedChildren.length > 0 ? {
|
|
29107
|
+
...n,
|
|
29108
|
+
children: mergedChildren
|
|
29109
|
+
} : n;
|
|
29110
|
+
});
|
|
29111
|
+
return [...attach(steps), ...newRoots];
|
|
29112
|
+
}
|
|
29024
29113
|
//#endregion
|
|
29025
29114
|
//#region src/orchestrator-store-schemas.ts
|
|
29026
29115
|
/**
|
|
@@ -29463,13 +29552,16 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
29463
29552
|
}
|
|
29464
29553
|
const cam = (await this.readCameraSettingsMap())[String(deviceId)] ?? null;
|
|
29465
29554
|
const wholesale = cam?.pipelineByAgent?.[agentNodeId];
|
|
29466
|
-
if (wholesale)
|
|
29467
|
-
|
|
29468
|
-
|
|
29469
|
-
|
|
29470
|
-
|
|
29471
|
-
|
|
29472
|
-
|
|
29555
|
+
if (wholesale) {
|
|
29556
|
+
const catalog = await this.getCatalogForAgent(agentNodeId);
|
|
29557
|
+
return {
|
|
29558
|
+
steps: catalog ? mergeEnabledByDefaultSteps(wholesale.steps, catalog) : wholesale.steps,
|
|
29559
|
+
audio: wholesale.audio ? {
|
|
29560
|
+
modelId: wholesale.audio.modelId,
|
|
29561
|
+
enabled: wholesale.audio.enabled
|
|
29562
|
+
} : null
|
|
29563
|
+
};
|
|
29564
|
+
}
|
|
29473
29565
|
const { agent, catalog } = await this.waitForAgentAndCatalog(agentNodeId);
|
|
29474
29566
|
const resolved = resolvePipeline(agent, cam, agentNodeId, catalog);
|
|
29475
29567
|
if (resolved.steps.length === 0) this.deps.logger.info("resolvePipelineForDevice → empty (all addons disabled)", {
|
package/dist/index.mjs
CHANGED
|
@@ -10973,6 +10973,7 @@ var PipelineAddonSchemaSchema = object({
|
|
|
10973
10973
|
defaultModelId: string(),
|
|
10974
10974
|
defaultModelIdByFormat: record(string(), string()).optional(),
|
|
10975
10975
|
enabledByDefault: boolean().optional(),
|
|
10976
|
+
backfillIntoExistingOverrides: boolean().optional(),
|
|
10976
10977
|
defaultConfidence: number(),
|
|
10977
10978
|
group: string().optional(),
|
|
10978
10979
|
configSchema: array(ConfigFieldBridge).readonly().optional()
|
|
@@ -28886,7 +28887,7 @@ function resolvePipeline(agentSettings, cameraSettings, agentNodeId, catalog) {
|
|
|
28886
28887
|
const cam = cameraSettings ?? {};
|
|
28887
28888
|
const wholesale = cam.pipelineByAgent?.[agentNodeId];
|
|
28888
28889
|
if (wholesale) return {
|
|
28889
|
-
steps: wholesale.steps,
|
|
28890
|
+
steps: mergeEnabledByDefaultSteps(wholesale.steps, catalog),
|
|
28890
28891
|
audio: wholesale.audio ? {
|
|
28891
28892
|
modelId: wholesale.audio.modelId,
|
|
28892
28893
|
enabled: wholesale.audio.enabled
|
|
@@ -28993,6 +28994,94 @@ function buildTreeFromAddons(enabled, catalog) {
|
|
|
28993
28994
|
}
|
|
28994
28995
|
return roots;
|
|
28995
28996
|
}
|
|
28997
|
+
/**
|
|
28998
|
+
* Back-fill catalog steps EXPLICITLY flagged `backfillIntoExistingOverrides`
|
|
28999
|
+
* but ENTIRELY ABSENT from an existing step tree — the wholesale-override
|
|
29000
|
+
* analogue of {@link seedAgentAddonDefaults}, which already grows per-agent
|
|
29001
|
+
* `addonDefaults` when the catalog adds a new addon.
|
|
29002
|
+
*
|
|
29003
|
+
* Why it's needed: a `pipelineByAgent` wholesale override SNAPSHOTS the full
|
|
29004
|
+
* tree. A step introduced AFTER the snapshot (e.g. `clip-embedding` for object
|
|
29005
|
+
* semantic search) would otherwise never reach that camera.
|
|
29006
|
+
*
|
|
29007
|
+
* Why the flag (not `enabledByDefault`): absence-from-a-snapshot is ambiguous —
|
|
29008
|
+
* it can mean "predates this step" OR "operator deliberately pruned it". A
|
|
29009
|
+
* broad "back-fill every default-on step" would resurrect deliberate removals
|
|
29010
|
+
* of long-existing steps (face-detection, etc.), an operator-intent
|
|
29011
|
+
* regression. Only a step that opts in via `backfillIntoExistingOverrides`
|
|
29012
|
+
* (set on genuinely-new default steps ONLY) re-enters existing overrides.
|
|
29013
|
+
*
|
|
29014
|
+
* Non-destructive by design:
|
|
29015
|
+
* - Only steps whose id is absent from the WHOLE tree are added. A step the
|
|
29016
|
+
* operator has already seen — present anywhere, even `enabled: false` —
|
|
29017
|
+
* is left exactly as-is (its enabled flag is honoured).
|
|
29018
|
+
* - Only `backfillIntoExistingOverrides === true` addons are candidates.
|
|
29019
|
+
* Every other step (including long-standing default-on members) is left
|
|
29020
|
+
* untouched, so a deliberately-pruned override stays pruned.
|
|
29021
|
+
* - Audio-classifier addons are skipped — audio lives in
|
|
29022
|
+
* `CameraPipelineConfig.audio`, never in the video `steps` tree.
|
|
29023
|
+
* - A candidate attaches by catalog compat (its `inputClasses` overlap a
|
|
29024
|
+
* present node's `outputClasses`), mirroring {@link buildTreeFromAddons}.
|
|
29025
|
+
* A candidate with non-empty `inputClasses` and NO compatible parent is
|
|
29026
|
+
* dropped (never re-rooted) so a crop-scoped embedder never regresses to
|
|
29027
|
+
* running on the full frame. Empty `inputClasses` ⇒ a genuine root step.
|
|
29028
|
+
*/
|
|
29029
|
+
function mergeEnabledByDefaultSteps(steps, catalog) {
|
|
29030
|
+
if (steps.length === 0) return steps;
|
|
29031
|
+
const present = /* @__PURE__ */ new Set();
|
|
29032
|
+
const collect = (nodes) => {
|
|
29033
|
+
for (const n of nodes) {
|
|
29034
|
+
present.add(n.addonId);
|
|
29035
|
+
if (n.children?.length) collect(n.children);
|
|
29036
|
+
}
|
|
29037
|
+
};
|
|
29038
|
+
collect(steps);
|
|
29039
|
+
const catalogById = /* @__PURE__ */ new Map();
|
|
29040
|
+
for (const slot of catalog.slots) for (const addon of slot.addons) catalogById.set(addon.id, addon);
|
|
29041
|
+
const newRoots = [];
|
|
29042
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
29043
|
+
for (const slot of catalog.slots) {
|
|
29044
|
+
if (slot.id === "audio-classifier") continue;
|
|
29045
|
+
for (const addon of slot.addons) {
|
|
29046
|
+
if (addon.backfillIntoExistingOverrides !== true) continue;
|
|
29047
|
+
if (present.has(addon.id)) continue;
|
|
29048
|
+
const node = {
|
|
29049
|
+
addonId: addon.id,
|
|
29050
|
+
enabled: true,
|
|
29051
|
+
children: []
|
|
29052
|
+
};
|
|
29053
|
+
const inputs = addon.inputClasses;
|
|
29054
|
+
if (!inputs || inputs.length === 0) {
|
|
29055
|
+
newRoots.push(node);
|
|
29056
|
+
continue;
|
|
29057
|
+
}
|
|
29058
|
+
let parentId = null;
|
|
29059
|
+
for (const presentId of present) {
|
|
29060
|
+
const meta = catalogById.get(presentId);
|
|
29061
|
+
if (!meta) continue;
|
|
29062
|
+
if (meta.outputClasses.some((c) => inputs.includes(c))) {
|
|
29063
|
+
parentId = presentId;
|
|
29064
|
+
break;
|
|
29065
|
+
}
|
|
29066
|
+
}
|
|
29067
|
+
if (!parentId) continue;
|
|
29068
|
+
const list = childrenByParent.get(parentId) ?? [];
|
|
29069
|
+
list.push(node);
|
|
29070
|
+
childrenByParent.set(parentId, list);
|
|
29071
|
+
}
|
|
29072
|
+
}
|
|
29073
|
+
if (childrenByParent.size === 0 && newRoots.length === 0) return steps;
|
|
29074
|
+
const attach = (nodes) => nodes.map((n) => {
|
|
29075
|
+
const rebuiltChildren = attach(n.children ?? []);
|
|
29076
|
+
const extra = childrenByParent.get(n.addonId) ?? [];
|
|
29077
|
+
const mergedChildren = [...rebuiltChildren, ...extra];
|
|
29078
|
+
return mergedChildren.length > 0 ? {
|
|
29079
|
+
...n,
|
|
29080
|
+
children: mergedChildren
|
|
29081
|
+
} : n;
|
|
29082
|
+
});
|
|
29083
|
+
return [...attach(steps), ...newRoots];
|
|
29084
|
+
}
|
|
28996
29085
|
//#endregion
|
|
28997
29086
|
//#region src/orchestrator-store-schemas.ts
|
|
28998
29087
|
/**
|
|
@@ -29435,13 +29524,16 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
29435
29524
|
}
|
|
29436
29525
|
const cam = (await this.readCameraSettingsMap())[String(deviceId)] ?? null;
|
|
29437
29526
|
const wholesale = cam?.pipelineByAgent?.[agentNodeId];
|
|
29438
|
-
if (wholesale)
|
|
29439
|
-
|
|
29440
|
-
|
|
29441
|
-
|
|
29442
|
-
|
|
29443
|
-
|
|
29444
|
-
|
|
29527
|
+
if (wholesale) {
|
|
29528
|
+
const catalog = await this.getCatalogForAgent(agentNodeId);
|
|
29529
|
+
return {
|
|
29530
|
+
steps: catalog ? mergeEnabledByDefaultSteps(wholesale.steps, catalog) : wholesale.steps,
|
|
29531
|
+
audio: wholesale.audio ? {
|
|
29532
|
+
modelId: wholesale.audio.modelId,
|
|
29533
|
+
enabled: wholesale.audio.enabled
|
|
29534
|
+
} : null
|
|
29535
|
+
};
|
|
29536
|
+
}
|
|
29445
29537
|
const { agent, catalog } = await this.waitForAgentAndCatalog(agentNodeId);
|
|
29446
29538
|
const resolved = resolvePipeline(agent, cam, agentNodeId, catalog);
|
|
29447
29539
|
if (resolved.steps.length === 0) this.deps.logger.info("resolvePipelineForDevice → empty (all addons disabled)", {
|
package/dist/remoteEntry.js
CHANGED
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DWO6Xr0a.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline-orchestrator",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.43",
|
|
4
4
|
"description": "Hub-side camera-to-agent load balancer — tracks runner capacity and dispatches attachCamera calls to the optimal pipeline-runner instance",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|