camstack 1.2.44 → 1.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
|
|
|
23633
23633
|
}
|
|
23634
23634
|
});
|
|
23635
23635
|
|
|
23636
|
-
// ../system/dist/dist-
|
|
23637
|
-
var
|
|
23638
|
-
"../system/dist/dist-
|
|
23636
|
+
// ../system/dist/dist-jRSrzoXr.js
|
|
23637
|
+
var require_dist_jRSrzoXr = __commonJS({
|
|
23638
|
+
"../system/dist/dist-jRSrzoXr.js"(exports) {
|
|
23639
23639
|
"use strict";
|
|
23640
23640
|
var zod = require_zod();
|
|
23641
23641
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
@@ -34136,7 +34136,23 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
34136
34136
|
updatedAt: zod.z.number(),
|
|
34137
34137
|
/** Failure detail — present on a `dead` row. */
|
|
34138
34138
|
error: zod.z.string().optional(),
|
|
34139
|
-
subject: NcHistorySubjectSchema
|
|
34139
|
+
subject: NcHistorySubjectSchema,
|
|
34140
|
+
/**
|
|
34141
|
+
* Ids of the artefacts (still, then gif, then clip) this row's successful
|
|
34142
|
+
* delivery indexed in the artefact library — a REFERENCE, never the bytes
|
|
34143
|
+
* (an artefact is often megabytes; this row is durable JSON rewritten on
|
|
34144
|
+
* every delivery attempt). Absent on a row still pending/dead, a row
|
|
34145
|
+
* delivered before this field shipped, or a wiring with no artefact index.
|
|
34146
|
+
*
|
|
34147
|
+
* Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
|
|
34148
|
+
* outlives any one URL's TTL, so a caller mints a fresh link on demand
|
|
34149
|
+
* rather than trusting one frozen at delivery time. `resolveArtifactUrl`
|
|
34150
|
+
* also answers `null` for an id whose artefact has since expired past the
|
|
34151
|
+
* retained shelf's own age bound — the degrade a caller (the Home
|
|
34152
|
+
* Assistant export) must render as "no image right now", never as a
|
|
34153
|
+
* broken link.
|
|
34154
|
+
*/
|
|
34155
|
+
artifactIds: zod.z.array(zod.z.string().min(1)).optional()
|
|
34140
34156
|
});
|
|
34141
34157
|
var NcHistoryFilterSchema = zod.z.object({
|
|
34142
34158
|
ruleId: zod.z.string().optional(),
|
|
@@ -34382,6 +34398,20 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
34382
34398
|
*/
|
|
34383
34399
|
getHistory: method(zod.z.object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), zod.z.object({ entries: zod.z.array(NcHistoryEntrySchema) }), { auth: "admin" }),
|
|
34384
34400
|
/**
|
|
34401
|
+
* Mint a fresh, externally-reachable URL for one artefact a history row
|
|
34402
|
+
* named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
|
|
34403
|
+
* signed-link mechanism the dispatcher uses to attach media to an
|
|
34404
|
+
* outgoing notification (one derivation; this never re-implements it).
|
|
34405
|
+
*
|
|
34406
|
+
* `url: null` on THREE causes a caller must treat identically ("no image
|
|
34407
|
+
* right now", never a broken link): the id is unknown, its artefact has
|
|
34408
|
+
* expired past the retained shelf's own age bound, or this install has no
|
|
34409
|
+
* externally-reachable base URL. A caller that received a URL on a
|
|
34410
|
+
* previous call and now gets `null` must stop showing it — a link that
|
|
34411
|
+
* worked five minutes ago is not proof it works now.
|
|
34412
|
+
*/
|
|
34413
|
+
resolveArtifactUrl: method(zod.z.object({ artifactId: zod.z.string().min(1) }), zod.z.object({ url: zod.z.string().nullable() }), { auth: "admin" }),
|
|
34414
|
+
/**
|
|
34385
34415
|
* Snooze windows currently in effect, plus any whose digest has not yet
|
|
34386
34416
|
* gone out. `caller: 'required'`: a user sees their OWN windows and the
|
|
34387
34417
|
* global ones that silence them, never another person's private silence.
|
|
@@ -34621,6 +34651,726 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
34621
34651
|
getDescriptor: method(zod.z.void(), OauthIntegrationDescriptorSchema, { auth: "admin" })
|
|
34622
34652
|
}
|
|
34623
34653
|
};
|
|
34654
|
+
var NativeCropRefSchema = zod.z.object({
|
|
34655
|
+
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
34656
|
+
handle: FrameHandleSchema,
|
|
34657
|
+
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
34658
|
+
cropFrameSpace: zod.z.object({
|
|
34659
|
+
x: zod.z.number(),
|
|
34660
|
+
y: zod.z.number(),
|
|
34661
|
+
w: zod.z.number(),
|
|
34662
|
+
h: zod.z.number()
|
|
34663
|
+
})
|
|
34664
|
+
});
|
|
34665
|
+
zod.z.object({
|
|
34666
|
+
crop: zod.z.object({
|
|
34667
|
+
left: zod.z.number(),
|
|
34668
|
+
top: zod.z.number(),
|
|
34669
|
+
width: zod.z.number().positive(),
|
|
34670
|
+
height: zod.z.number().positive()
|
|
34671
|
+
}).optional(),
|
|
34672
|
+
content: zod.z.object({
|
|
34673
|
+
width: zod.z.number().int().positive(),
|
|
34674
|
+
height: zod.z.number().int().positive()
|
|
34675
|
+
}),
|
|
34676
|
+
fit: zod.z.enum(["stretch", "contain"]),
|
|
34677
|
+
format: zod.z.enum([
|
|
34678
|
+
"rgb",
|
|
34679
|
+
"gray",
|
|
34680
|
+
"jpeg"
|
|
34681
|
+
])
|
|
34682
|
+
});
|
|
34683
|
+
var FrameRefSchema = zod.z.object({
|
|
34684
|
+
registryId: zod.z.string().min(1),
|
|
34685
|
+
id: zod.z.string().min(1),
|
|
34686
|
+
width: zod.z.number().int().positive(),
|
|
34687
|
+
height: zod.z.number().int().positive(),
|
|
34688
|
+
format: zod.z.enum(["rgb", "gray"]),
|
|
34689
|
+
timestamp: zod.z.number(),
|
|
34690
|
+
capturedAt: zod.z.number().optional()
|
|
34691
|
+
});
|
|
34692
|
+
var ModelFormatSchema$1 = zod.z.enum([
|
|
34693
|
+
"onnx",
|
|
34694
|
+
"coreml",
|
|
34695
|
+
"openvino",
|
|
34696
|
+
"tflite",
|
|
34697
|
+
"pt",
|
|
34698
|
+
"gguf"
|
|
34699
|
+
]);
|
|
34700
|
+
var PipelineSlotSchema = zod.z.enum([
|
|
34701
|
+
"detector",
|
|
34702
|
+
"cropper",
|
|
34703
|
+
"classifier",
|
|
34704
|
+
"refiner",
|
|
34705
|
+
"audio-classifier"
|
|
34706
|
+
]);
|
|
34707
|
+
var PipelineEngineChoiceSchema = zod.z.object({
|
|
34708
|
+
runtime: zod.z.enum(["node", "python"]),
|
|
34709
|
+
backend: zod.z.string(),
|
|
34710
|
+
format: ModelFormatSchema$1,
|
|
34711
|
+
device: zod.z.string().optional()
|
|
34712
|
+
});
|
|
34713
|
+
var EngineDeviceInfoSchema = zod.z.object({
|
|
34714
|
+
id: zod.z.string(),
|
|
34715
|
+
label: zod.z.string(),
|
|
34716
|
+
description: zod.z.string().optional()
|
|
34717
|
+
});
|
|
34718
|
+
var AvailableEngineSchema = zod.z.object({
|
|
34719
|
+
engine: PipelineEngineChoiceSchema,
|
|
34720
|
+
devices: zod.z.array(EngineDeviceInfoSchema).readonly(),
|
|
34721
|
+
defaultDevice: zod.z.string()
|
|
34722
|
+
});
|
|
34723
|
+
var PipelineDefaultStepSchema = zod.z.lazy(() => zod.z.object({
|
|
34724
|
+
addonId: zod.z.string(),
|
|
34725
|
+
addonName: zod.z.string(),
|
|
34726
|
+
slot: PipelineSlotSchema,
|
|
34727
|
+
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
34728
|
+
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
34729
|
+
enabled: zod.z.boolean(),
|
|
34730
|
+
modelId: zod.z.string(),
|
|
34731
|
+
children: zod.z.array(PipelineDefaultStepSchema).readonly(),
|
|
34732
|
+
group: zod.z.string().optional(),
|
|
34733
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
34734
|
+
}));
|
|
34735
|
+
var PipelineTemplateStepSchema = zod.z.lazy(() => zod.z.object({
|
|
34736
|
+
addonId: zod.z.string(),
|
|
34737
|
+
enabled: zod.z.boolean(),
|
|
34738
|
+
modelId: zod.z.string(),
|
|
34739
|
+
children: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
34740
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
34741
|
+
}));
|
|
34742
|
+
var PipelineTemplateSchema$1 = zod.z.object({
|
|
34743
|
+
id: zod.z.string(),
|
|
34744
|
+
name: zod.z.string(),
|
|
34745
|
+
createdAt: zod.z.string(),
|
|
34746
|
+
updatedAt: zod.z.string(),
|
|
34747
|
+
engine: PipelineEngineChoiceSchema,
|
|
34748
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly()
|
|
34749
|
+
});
|
|
34750
|
+
var PipelineModelOptionSchema = zod.z.object({
|
|
34751
|
+
id: zod.z.string(),
|
|
34752
|
+
name: zod.z.string(),
|
|
34753
|
+
formats: zod.z.record(zod.z.string(), zod.z.object({
|
|
34754
|
+
downloaded: zod.z.boolean(),
|
|
34755
|
+
sizeMB: zod.z.number()
|
|
34756
|
+
})),
|
|
34757
|
+
group: ModelVariantGroupSchema.optional(),
|
|
34758
|
+
legacy: zod.z.boolean().optional(),
|
|
34759
|
+
provider: ModelProviderIdSchema.optional()
|
|
34760
|
+
});
|
|
34761
|
+
var ConfigFieldBridge = zod.z.custom();
|
|
34762
|
+
var PipelineAddonSchemaSchema = zod.z.object({
|
|
34763
|
+
id: zod.z.string(),
|
|
34764
|
+
name: zod.z.string(),
|
|
34765
|
+
slot: PipelineSlotSchema,
|
|
34766
|
+
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
34767
|
+
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
34768
|
+
childSlots: zod.z.array(PipelineSlotSchema).readonly(),
|
|
34769
|
+
models: zod.z.array(PipelineModelOptionSchema).readonly(),
|
|
34770
|
+
defaultModelId: zod.z.string(),
|
|
34771
|
+
defaultModelIdByFormat: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
34772
|
+
enabledByDefault: zod.z.boolean().optional(),
|
|
34773
|
+
backfillIntoExistingOverrides: zod.z.boolean().optional(),
|
|
34774
|
+
defaultConfidence: zod.z.number(),
|
|
34775
|
+
group: zod.z.string().optional(),
|
|
34776
|
+
configSchema: zod.z.array(ConfigFieldBridge).readonly().optional()
|
|
34777
|
+
});
|
|
34778
|
+
var PipelineSlotSchemaSchema = zod.z.object({
|
|
34779
|
+
id: PipelineSlotSchema,
|
|
34780
|
+
label: zod.z.string(),
|
|
34781
|
+
priority: zod.z.number(),
|
|
34782
|
+
parentSlot: PipelineSlotSchema.nullable(),
|
|
34783
|
+
addons: zod.z.array(PipelineAddonSchemaSchema).readonly()
|
|
34784
|
+
});
|
|
34785
|
+
var PipelineSchemaSchema = zod.z.object({
|
|
34786
|
+
availableEngines: zod.z.array(AvailableEngineSchema).readonly(),
|
|
34787
|
+
selectedEngine: PipelineEngineChoiceSchema,
|
|
34788
|
+
slots: zod.z.array(PipelineSlotSchemaSchema).readonly()
|
|
34789
|
+
});
|
|
34790
|
+
var EngineProvisioningSchema = zod.z.object({
|
|
34791
|
+
runtimeId: zod.z.enum([
|
|
34792
|
+
"onnx",
|
|
34793
|
+
"openvino",
|
|
34794
|
+
"coreml",
|
|
34795
|
+
"edgetpu"
|
|
34796
|
+
]).nullable(),
|
|
34797
|
+
device: zod.z.string().nullable(),
|
|
34798
|
+
state: zod.z.enum([
|
|
34799
|
+
"idle",
|
|
34800
|
+
"installing",
|
|
34801
|
+
"verifying",
|
|
34802
|
+
"ready",
|
|
34803
|
+
"failed"
|
|
34804
|
+
]),
|
|
34805
|
+
progress: zod.z.number().optional(),
|
|
34806
|
+
error: zod.z.string().optional(),
|
|
34807
|
+
nextRetryAt: zod.z.number().optional(),
|
|
34808
|
+
/**
|
|
34809
|
+
* Gate A (config-correctness gate at engine change): human-readable
|
|
34810
|
+
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
34811
|
+
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
34812
|
+
* has a <format> build"). Additive/optional: informational only, never
|
|
34813
|
+
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
34814
|
+
* Absent/empty when the node-default tree resolves cleanly.
|
|
34815
|
+
*/
|
|
34816
|
+
configIssues: zod.z.array(zod.z.string()).optional()
|
|
34817
|
+
});
|
|
34818
|
+
var PipelineStepInputSchema = zod.z.lazy(() => zod.z.object({
|
|
34819
|
+
addonId: zod.z.string(),
|
|
34820
|
+
modelId: zod.z.string().optional(),
|
|
34821
|
+
enabled: zod.z.boolean().default(true),
|
|
34822
|
+
children: zod.z.array(PipelineStepInputSchema).optional(),
|
|
34823
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
34824
|
+
jumpDeviceKey: zod.z.string().optional()
|
|
34825
|
+
}));
|
|
34826
|
+
var ModelSubstitutionSchema = zod.z.object({
|
|
34827
|
+
addonId: zod.z.string(),
|
|
34828
|
+
chosen: zod.z.string(),
|
|
34829
|
+
running: zod.z.string(),
|
|
34830
|
+
format: zod.z.string()
|
|
34831
|
+
});
|
|
34832
|
+
var PipelineValidationIssueSchema = zod.z.object({
|
|
34833
|
+
addonId: zod.z.string(),
|
|
34834
|
+
kind: zod.z.enum(["unknown-addon", "no-format-build"]),
|
|
34835
|
+
detail: zod.z.string()
|
|
34836
|
+
});
|
|
34837
|
+
var PipelineValidationResultSchema = zod.z.object({
|
|
34838
|
+
ok: zod.z.boolean(),
|
|
34839
|
+
issues: zod.z.array(PipelineValidationIssueSchema).readonly(),
|
|
34840
|
+
substitutions: zod.z.array(ModelSubstitutionSchema).readonly(),
|
|
34841
|
+
/** The node's `currentEngine.format` this validation ran against. */
|
|
34842
|
+
format: zod.z.string()
|
|
34843
|
+
});
|
|
34844
|
+
var ReferenceImageEntrySchema = zod.z.object({
|
|
34845
|
+
filename: zod.z.string(),
|
|
34846
|
+
stepIds: zod.z.array(zod.z.string()).readonly().optional()
|
|
34847
|
+
});
|
|
34848
|
+
var ReferenceImageBodySchema = zod.z.object({
|
|
34849
|
+
base64: zod.z.string(),
|
|
34850
|
+
filename: zod.z.string()
|
|
34851
|
+
});
|
|
34852
|
+
var ReferenceAudioEntrySchema = zod.z.object({
|
|
34853
|
+
filename: zod.z.string(),
|
|
34854
|
+
sizeKb: zod.z.number()
|
|
34855
|
+
});
|
|
34856
|
+
var ReferenceAudioBodySchema = zod.z.object({ base64: zod.z.string() });
|
|
34857
|
+
var AudioBackendSchema = zod.z.object({
|
|
34858
|
+
id: zod.z.string(),
|
|
34859
|
+
name: zod.z.string(),
|
|
34860
|
+
description: zod.z.string(),
|
|
34861
|
+
available: zod.z.boolean(),
|
|
34862
|
+
/**
|
|
34863
|
+
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
34864
|
+
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
34865
|
+
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
34866
|
+
* specific to the selected backend without a separate fetch.
|
|
34867
|
+
*/
|
|
34868
|
+
rawLabels: zod.z.array(zod.z.string()).readonly().optional()
|
|
34869
|
+
});
|
|
34870
|
+
var AudioCapabilitiesSchema = zod.z.object({
|
|
34871
|
+
activeBackend: zod.z.string(),
|
|
34872
|
+
availableBackends: zod.z.array(AudioBackendSchema).readonly(),
|
|
34873
|
+
sampleRate: zod.z.number(),
|
|
34874
|
+
chunkDurationMs: zod.z.number()
|
|
34875
|
+
});
|
|
34876
|
+
var DownloadModelResultSchema = zod.z.object({
|
|
34877
|
+
filePath: zod.z.string(),
|
|
34878
|
+
sizeMB: zod.z.number(),
|
|
34879
|
+
durationMs: zod.z.number()
|
|
34880
|
+
});
|
|
34881
|
+
var AudioTestResultSchema = zod.z.object({
|
|
34882
|
+
success: zod.z.boolean(),
|
|
34883
|
+
error: zod.z.string().optional(),
|
|
34884
|
+
frame: zod.z.custom().optional()
|
|
34885
|
+
});
|
|
34886
|
+
var PipelineConfigBridge = zod.z.custom();
|
|
34887
|
+
var ConfigUISchemaBridge = zod.z.custom();
|
|
34888
|
+
var ConfigUISchemaNullableBridge = zod.z.custom();
|
|
34889
|
+
var InferenceCapabilitiesBridge = zod.z.custom();
|
|
34890
|
+
var ModelAvailabilityListBridge = zod.z.custom();
|
|
34891
|
+
var PipelineRunResultBridge = zod.z.custom();
|
|
34892
|
+
var pipelineExecutorCapability = {
|
|
34893
|
+
name: "pipeline-executor",
|
|
34894
|
+
scope: "system",
|
|
34895
|
+
mode: "singleton",
|
|
34896
|
+
methods: {
|
|
34897
|
+
getAvailableEngines: method(zod.z.void(), zod.z.array(PipelineEngineChoiceSchema)),
|
|
34898
|
+
getSelectedEngine: method(zod.z.void(), PipelineEngineChoiceSchema),
|
|
34899
|
+
getDefaultSteps: method(PipelineEngineChoiceSchema, zod.z.array(PipelineDefaultStepSchema)),
|
|
34900
|
+
/**
|
|
34901
|
+
* Per-node detection-engine provisioning snapshot. Returns the live
|
|
34902
|
+
* state of the lazy runtime-provisioning machine on `nodeId`
|
|
34903
|
+
* (idle / installing / verifying / ready / failed). The UI pairs this
|
|
34904
|
+
* one-shot query with the `pipeline.engine-provisioning` live event
|
|
34905
|
+
* (emitted on every transition) to drive a per-node "engine ready?"
|
|
34906
|
+
* indicator without polling. Phase 2.
|
|
34907
|
+
*/
|
|
34908
|
+
getEngineProvisioning: method(zod.z.object({ nodeId: zod.z.string() }), EngineProvisioningSchema),
|
|
34909
|
+
getVideoPipelineSteps: method(zod.z.void(), zod.z.record(zod.z.string(), zod.z.object({
|
|
34910
|
+
modelId: zod.z.string(),
|
|
34911
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
34912
|
+
}))),
|
|
34913
|
+
setVideoPipelineSteps: method(zod.z.object({ steps: zod.z.record(zod.z.string(), zod.z.object({
|
|
34914
|
+
modelId: zod.z.string(),
|
|
34915
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
34916
|
+
})) }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
34917
|
+
kind: "mutation",
|
|
34918
|
+
auth: "admin"
|
|
34919
|
+
}),
|
|
34920
|
+
/**
|
|
34921
|
+
* Clear THIS node's executor-side PER-DEVICE settings stores (the
|
|
34922
|
+
* per-camera step overrides the object-detection root reads via
|
|
34923
|
+
* `applyDeviceOverridesToTree`). `nodeId` is the ROUTING key — the
|
|
34924
|
+
* generated cap-router strips it (default `nodeIdMode: 'routing'`) and
|
|
34925
|
+
* dispatches to that node, so the provider method runs ON the target
|
|
34926
|
+
* node and receives no `nodeId`.
|
|
34927
|
+
*
|
|
34928
|
+
* This is the slimmed executor leg of the orchestrator's
|
|
34929
|
+
* `resetNodePipelineDefaults` flow (which owns the real reset: node
|
|
34930
|
+
* addonDefaults pins + per-camera orchestrator overrides). The legacy
|
|
34931
|
+
* `resetToDefault` — which reset a persisted global step-tree seed
|
|
34932
|
+
* nothing in the live per-camera path read — was removed together with
|
|
34933
|
+
* that seed.
|
|
34934
|
+
*/
|
|
34935
|
+
clearDeviceOverrides: method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({
|
|
34936
|
+
success: zod.z.literal(true),
|
|
34937
|
+
clearedDevices: zod.z.number()
|
|
34938
|
+
}), {
|
|
34939
|
+
kind: "mutation",
|
|
34940
|
+
auth: "admin"
|
|
34941
|
+
}),
|
|
34942
|
+
/**
|
|
34943
|
+
* Which of THIS node's inference devices the executor currently refuses,
|
|
34944
|
+
* and why. `nodeId` is the ROUTING key (stripped by the generated router).
|
|
34945
|
+
*
|
|
34946
|
+
* The channel that did not exist. Pool health was known only inside the
|
|
34947
|
+
* detection addon and was an input to no routing decision anywhere: the
|
|
34948
|
+
* per-dispatch capability gate is keyed on model FORMAT and so can never
|
|
34949
|
+
* separate `openvino:gpu` from `openvino:npu`, and the orchestrator's live
|
|
34950
|
+
* eligibility probe (`platformProbe.getCapabilities`) answers about
|
|
34951
|
+
* HARDWARE — which was present throughout. So when the hub's `openvino:gpu`
|
|
34952
|
+
* Python worker was SIGABRT'd by the Intel GPU plugin on 2026-08-25, the
|
|
34953
|
+
* balancer went on handing that dead pool cameras by rotation for 31 hours:
|
|
34954
|
+
* ~370 000 `PoolWorker[w0]: not initialized` lines, every frame lost.
|
|
34955
|
+
*
|
|
34956
|
+
* Read semantics the caller depends on, and which the provider guarantees:
|
|
34957
|
+
* this is a synchronous read of in-memory state. It never probes hardware,
|
|
34958
|
+
* never spawns a pool and never throws — an EMPTY `unhealthy` means "asked,
|
|
34959
|
+
* nothing is refused", which is what re-admits a device. A read that FAILS
|
|
34960
|
+
* (node offline, version skew) must therefore be distinguishable from an
|
|
34961
|
+
* empty answer, and it is: it rejects.
|
|
34962
|
+
*/
|
|
34963
|
+
getInferenceDeviceHealth: method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({ unhealthy: zod.z.array(zod.z.object({
|
|
34964
|
+
/** `<backend>:<device>`, e.g. `openvino:gpu`. */
|
|
34965
|
+
deviceKey: zod.z.string(),
|
|
34966
|
+
/**
|
|
34967
|
+
* `failed` — the per-device restart budget is exhausted; no pool
|
|
34968
|
+
* will be spawned until an operator re-arms it or the runner
|
|
34969
|
+
* respawns. `backoff` — under budget, waiting out the backoff (or
|
|
34970
|
+
* a cached pool observed dead and not yet condemned).
|
|
34971
|
+
*/
|
|
34972
|
+
state: zod.z.enum(["failed", "backoff"]),
|
|
34973
|
+
/** Epoch ms of the death that produced this state. */
|
|
34974
|
+
since: zod.z.number(),
|
|
34975
|
+
/** Pool deaths inside the current window. */
|
|
34976
|
+
deaths: zod.z.number(),
|
|
34977
|
+
/** The last death's message. */
|
|
34978
|
+
lastError: zod.z.string()
|
|
34979
|
+
})).readonly() })),
|
|
34980
|
+
/**
|
|
34981
|
+
* Re-arm a terminally `failed` inference device on `nodeId`: forget its
|
|
34982
|
+
* restart budget so the next dispatch builds a fresh pool.
|
|
34983
|
+
*
|
|
34984
|
+
* The terminal state is deliberate (the abort it bounds is deterministic —
|
|
34985
|
+
* an automatic probation would just respawn Python forever, more slowly),
|
|
34986
|
+
* and a terminal state an operator cannot leave is a silent fault. This is
|
|
34987
|
+
* the way out. `rearmed:false` means there was nothing to forget.
|
|
34988
|
+
*/
|
|
34989
|
+
rearmInferenceDevice: method(zod.z.object({
|
|
34990
|
+
nodeId: zod.z.string(),
|
|
34991
|
+
deviceKey: zod.z.string()
|
|
34992
|
+
}), zod.z.object({ rearmed: zod.z.boolean() }), {
|
|
34993
|
+
kind: "mutation",
|
|
34994
|
+
auth: "admin"
|
|
34995
|
+
}),
|
|
34996
|
+
getSchema: method(zod.z.void(), PipelineSchemaSchema),
|
|
34997
|
+
getGlobalSteps: method(zod.z.void(), zod.z.array(PipelineDefaultStepSchema).readonly().nullable()),
|
|
34998
|
+
getGlobalPipelineConfig: method(zod.z.void(), PipelineConfigBridge),
|
|
34999
|
+
getOrchestratorConfigSchema: method(zod.z.void(), ConfigUISchemaBridge),
|
|
35000
|
+
/**
|
|
35001
|
+
* Gate B (pre-init config-correctness gate). PURE COMPUTE against this
|
|
35002
|
+
* node's `currentEngine.format` — resolves `steps` the same way the
|
|
35003
|
+
* runtime dispatch path would, and reports what WOULD happen without
|
|
35004
|
+
* touching any node-global state. Called by the orchestrator at attach
|
|
35005
|
+
* time (`attachOn`), node-pinned to the TARGET node, so config problems
|
|
35006
|
+
* surface BEFORE `pipelineRunner.attachCamera` rather than at the first
|
|
35007
|
+
* per-frame resolve. `ok` is false iff `issues` is non-empty (both
|
|
35008
|
+
* `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
|
|
35009
|
+
* is informational (a degraded-but-loadable model swap) and never
|
|
35010
|
+
* affects `ok`. Never throws.
|
|
35011
|
+
*/
|
|
35012
|
+
validatePipeline: method(zod.z.object({ steps: zod.z.array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
|
|
35013
|
+
listTemplates: method(zod.z.void(), zod.z.array(PipelineTemplateSchema$1).readonly()),
|
|
35014
|
+
saveTemplate: method(zod.z.object({
|
|
35015
|
+
name: zod.z.string(),
|
|
35016
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
35017
|
+
engine: PipelineEngineChoiceSchema
|
|
35018
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
35019
|
+
updateTemplate: method(zod.z.object({
|
|
35020
|
+
id: zod.z.string(),
|
|
35021
|
+
name: zod.z.string().optional(),
|
|
35022
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly().optional()
|
|
35023
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
35024
|
+
deleteTemplate: method(zod.z.object({ id: zod.z.string() }), zod.z.void(), { kind: "mutation" }),
|
|
35025
|
+
getCapabilities: method(zod.z.void(), InferenceCapabilitiesBridge),
|
|
35026
|
+
getAddonModels: method(zod.z.object({ addonId: zod.z.string() }), ModelAvailabilityListBridge),
|
|
35027
|
+
downloadModel: method(zod.z.object({
|
|
35028
|
+
addonId: zod.z.string(),
|
|
35029
|
+
modelId: zod.z.string(),
|
|
35030
|
+
format: ModelFormatSchema$1
|
|
35031
|
+
}), DownloadModelResultSchema, { kind: "mutation" }),
|
|
35032
|
+
deleteModel: method(zod.z.object({
|
|
35033
|
+
addonId: zod.z.string(),
|
|
35034
|
+
modelId: zod.z.string(),
|
|
35035
|
+
format: ModelFormatSchema$1
|
|
35036
|
+
}), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }),
|
|
35037
|
+
/**
|
|
35038
|
+
* Stateless single-frame execution. Callers (runner, benchmark) pass
|
|
35039
|
+
* the complete `engine` + `steps` tree; the executor holds no state
|
|
35040
|
+
* about cameras or saved pipelines.
|
|
35041
|
+
*
|
|
35042
|
+
* `engine` is optional during the migration window to preserve the
|
|
35043
|
+
* legacy call shape used by existing benchmark code; once all
|
|
35044
|
+
* callers pass it explicitly we make it required.
|
|
35045
|
+
*
|
|
35046
|
+
* Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
|
|
35047
|
+
* `referenceImage` must be provided:
|
|
35048
|
+
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
35049
|
+
* Carries the raw buffer, dimensions, and format; the executor
|
|
35050
|
+
* uses it directly without base64 round-tripping.
|
|
35051
|
+
* - `frameHandle` (CB5): a zero-pixel shm `FrameHandle` for the SAME
|
|
35052
|
+
* decoded frame. Both runner and executor are hub-local processes
|
|
35053
|
+
* sharing `/dev/shm`, so the executor maps the named segment and
|
|
35054
|
+
* reads the pixels back zero-copy — eliminating the ~1.2MB
|
|
35055
|
+
* re-serialisation over UDS/MsgPack the `frame` path pays per call.
|
|
35056
|
+
* High-risk: the FrameRing is a latest-wins seqlock with no
|
|
35057
|
+
* refcount, so a recycled slot yields a null read; the executor
|
|
35058
|
+
* then degrades to an empty result and the runner ships pixels via
|
|
35059
|
+
* `frame` as the fallback (queue-depth gated on the runner side).
|
|
35060
|
+
* - `imageBase64`: one-shot test path (benchmark ImageTab).
|
|
35061
|
+
* - `referenceImage`: named file from the reference-image store.
|
|
35062
|
+
*/
|
|
35063
|
+
runPipeline: method(zod.z.object({
|
|
35064
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
35065
|
+
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
35066
|
+
frame: FrameInputSchema.optional(),
|
|
35067
|
+
/**
|
|
35068
|
+
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
35069
|
+
* in the same execution-group process; split/cross-node callers use
|
|
35070
|
+
* `frame`/`image` inline compatibility instead.
|
|
35071
|
+
*/
|
|
35072
|
+
frameRef: FrameRefSchema.optional(),
|
|
35073
|
+
/**
|
|
35074
|
+
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
35075
|
+
* the decoded pixels live in. One more member of the one-of
|
|
35076
|
+
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
35077
|
+
*/
|
|
35078
|
+
frameHandle: FrameHandleSchema.optional(),
|
|
35079
|
+
imageBase64: zod.z.string().optional(),
|
|
35080
|
+
/**
|
|
35081
|
+
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
35082
|
+
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
35083
|
+
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
35084
|
+
* the detection-pipeline worker. Callers can pass either; exactly
|
|
35085
|
+
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
35086
|
+
*/
|
|
35087
|
+
image: zod.z.instanceof(Uint8Array).optional(),
|
|
35088
|
+
referenceImage: zod.z.string().optional(),
|
|
35089
|
+
deviceId: zod.z.number().optional(),
|
|
35090
|
+
sessionId: zod.z.string().optional(),
|
|
35091
|
+
/**
|
|
35092
|
+
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
35093
|
+
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
35094
|
+
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
35095
|
+
* (inputClasses ≠ null) are skipped and served per-track via
|
|
35096
|
+
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
35097
|
+
*/
|
|
35098
|
+
plane: zod.z.enum(["full", "frame"]).optional(),
|
|
35099
|
+
/**
|
|
35100
|
+
* Inference-device selector (Phase 2 multi-device). Format
|
|
35101
|
+
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
35102
|
+
* Omitted ⇒ the runner's default device (current single-engine
|
|
35103
|
+
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
35104
|
+
*/
|
|
35105
|
+
deviceKey: zod.z.string().optional(),
|
|
35106
|
+
/**
|
|
35107
|
+
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
35108
|
+
* when the parent crop was resolved from the frame's retained NATIVE
|
|
35109
|
+
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
35110
|
+
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
35111
|
+
* resolution from that surface — the SAME quality path faces already
|
|
35112
|
+
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
35113
|
+
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
35114
|
+
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
35115
|
+
* the executor's crop-normalized child ROI back into frame-normalized
|
|
35116
|
+
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
35117
|
+
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
35118
|
+
* (today's behaviour on the fallback path).
|
|
35119
|
+
*/
|
|
35120
|
+
nativeCropRef: NativeCropRefSchema.optional()
|
|
35121
|
+
}), PipelineRunResultBridge, { kind: "mutation" }),
|
|
35122
|
+
/**
|
|
35123
|
+
* Batched run — N raw frames packed into one cap call. The provider
|
|
35124
|
+
* routes the batch through `SharedInferencePool.inferBatch`
|
|
35125
|
+
* (`MSG_INFER_BATCH = 0x03`) so the IPC framing and JSON response
|
|
35126
|
+
* envelope cost is amortised N:1 vs N concurrent `runPipeline`
|
|
35127
|
+
* calls. Single root step + uniform model assumed; trees with crop
|
|
35128
|
+
* children fall back to sequential execution.
|
|
35129
|
+
*
|
|
35130
|
+
* Used by `scripts/bench-batch-style.mts` for batch benchmarking —
|
|
35131
|
+
* N frames in one call to amortise per-call IPC overhead.
|
|
35132
|
+
*/
|
|
35133
|
+
runPipelineBatch: method(zod.z.object({
|
|
35134
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
35135
|
+
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
35136
|
+
frames: zod.z.array(FrameInputSchema).min(1).max(255),
|
|
35137
|
+
deviceId: zod.z.number().optional(),
|
|
35138
|
+
sessionId: zod.z.string().optional(),
|
|
35139
|
+
/**
|
|
35140
|
+
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
35141
|
+
* the batch to the Python pool's bench preprocess cache
|
|
35142
|
+
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
35143
|
+
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
35144
|
+
* hit — the sustained-throughput run measures inference, not
|
|
35145
|
+
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
35146
|
+
* full preprocess every call, correct). Fresh per sustained run;
|
|
35147
|
+
* released via `uncacheFrame`.
|
|
35148
|
+
*/
|
|
35149
|
+
frameId: zod.z.number().int().nonnegative().optional(),
|
|
35150
|
+
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
35151
|
+
deviceKey: zod.z.string().optional()
|
|
35152
|
+
}), zod.z.object({ results: zod.z.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
|
|
35153
|
+
/**
|
|
35154
|
+
* Cache a raw frame inside the Python inference pool's memory.
|
|
35155
|
+
* Returns a numeric `frameId` that `inferCached` references —
|
|
35156
|
+
* subsequent calls send only 5 bytes through the pipe instead of
|
|
35157
|
+
* 1.2MB raw data, eliminating the pipe transfer bottleneck.
|
|
35158
|
+
*/
|
|
35159
|
+
cacheFrameInPool: method(zod.z.object({
|
|
35160
|
+
data: zod.z.instanceof(Uint8Array),
|
|
35161
|
+
width: zod.z.number().int().positive(),
|
|
35162
|
+
height: zod.z.number().int().positive(),
|
|
35163
|
+
format: zod.z.enum([
|
|
35164
|
+
"rgb",
|
|
35165
|
+
"bgr",
|
|
35166
|
+
"gray"
|
|
35167
|
+
])
|
|
35168
|
+
}), zod.z.object({
|
|
35169
|
+
frameId: zod.z.number(),
|
|
35170
|
+
width: zod.z.number(),
|
|
35171
|
+
height: zod.z.number()
|
|
35172
|
+
}), { kind: "mutation" }),
|
|
35173
|
+
/**
|
|
35174
|
+
* Run inference on a previously cached frame. Sends only 5 bytes
|
|
35175
|
+
* (model_idx + frameId) through the IPC pipe — eliminates the
|
|
35176
|
+
* ~35ms per-call overhead of transferring 1.2MB raw data.
|
|
35177
|
+
*/
|
|
35178
|
+
inferCached: method(zod.z.object({
|
|
35179
|
+
stepId: zod.z.string(),
|
|
35180
|
+
frameId: zod.z.number().int()
|
|
35181
|
+
}), zod.z.record(zod.z.string(), zod.z.unknown()), { kind: "mutation" }),
|
|
35182
|
+
/**
|
|
35183
|
+
* Release a cached frame from the Python pool's memory.
|
|
35184
|
+
*/
|
|
35185
|
+
uncacheFrame: method(zod.z.object({ frameId: zod.z.number().int() }), zod.z.void(), { kind: "mutation" }),
|
|
35186
|
+
/** Returns the effective pool tuning (resolved from user overrides + backend defaults). */
|
|
35187
|
+
getEffectiveTuning: method(zod.z.void(), zod.z.object({
|
|
35188
|
+
batchMode: zod.z.string(),
|
|
35189
|
+
windowMs: zod.z.number(),
|
|
35190
|
+
maxBatchSize: zod.z.number(),
|
|
35191
|
+
concurrency: zod.z.number()
|
|
35192
|
+
})),
|
|
35193
|
+
/**
|
|
35194
|
+
* List every EngineFactory currently loaded in this executor's RAM,
|
|
35195
|
+
* with the models resident and a coarse "in use" marker derived from
|
|
35196
|
+
* ongoing inference activity. Used by the Pipeline page Engines tab.
|
|
35197
|
+
*/
|
|
35198
|
+
listLoadedEngines: method(zod.z.void(), zod.z.array(zod.z.object({
|
|
35199
|
+
engineKey: zod.z.string(),
|
|
35200
|
+
engine: PipelineEngineChoiceSchema,
|
|
35201
|
+
modelsLoaded: zod.z.array(zod.z.string()).readonly(),
|
|
35202
|
+
inUseByCameras: zod.z.array(zod.z.number()).readonly(),
|
|
35203
|
+
/**
|
|
35204
|
+
* Origin of this resident factory.
|
|
35205
|
+
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
35206
|
+
* - `warm-override` — benchmark/test override held in the warm
|
|
35207
|
+
* cache; auto-disposed after the idle TTL.
|
|
35208
|
+
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
35209
|
+
* multi-device, keyed by `deviceKey`) resolved
|
|
35210
|
+
* via `resolveDeviceFactory`. Runs alongside the
|
|
35211
|
+
* `runtime` engine on a DIFFERENT accelerator
|
|
35212
|
+
* (NPU / iGPU / Coral) — this is how the
|
|
35213
|
+
* Engines tab shows all pools running at once.
|
|
35214
|
+
*/
|
|
35215
|
+
kind: zod.z.enum([
|
|
35216
|
+
"runtime",
|
|
35217
|
+
"warm-override",
|
|
35218
|
+
"device-pool"
|
|
35219
|
+
]),
|
|
35220
|
+
/** Native pid of the underlying Python pool (null when no pool). */
|
|
35221
|
+
poolPid: zod.z.number().nullable(),
|
|
35222
|
+
/** ms since this factory was last used (null when not warm-tracked). */
|
|
35223
|
+
idleMs: zod.z.number().nullable(),
|
|
35224
|
+
/** Idle TTL after which `warm-override` factories self-evict (null when not applicable). */
|
|
35225
|
+
idleTtlMs: zod.z.number().nullable()
|
|
35226
|
+
})).readonly()),
|
|
35227
|
+
/** Warm up an engine without running a frame. No-op if already loaded. */
|
|
35228
|
+
spinEngine: method(zod.z.object({ engine: PipelineEngineChoiceSchema }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
35229
|
+
kind: "mutation",
|
|
35230
|
+
auth: "admin"
|
|
35231
|
+
}),
|
|
35232
|
+
/**
|
|
35233
|
+
* Unload an engine from RAM. `force:true` unloads even when cameras
|
|
35234
|
+
* are actively using it (they re-spin on next frame). Default is
|
|
35235
|
+
* gated — returns `{success:false, reason}` when in use.
|
|
35236
|
+
*/
|
|
35237
|
+
killEngine: method(zod.z.object({
|
|
35238
|
+
engine: PipelineEngineChoiceSchema,
|
|
35239
|
+
force: zod.z.boolean().optional()
|
|
35240
|
+
}), zod.z.object({
|
|
35241
|
+
success: zod.z.boolean(),
|
|
35242
|
+
reason: zod.z.string().optional()
|
|
35243
|
+
}), {
|
|
35244
|
+
kind: "mutation",
|
|
35245
|
+
auth: "admin"
|
|
35246
|
+
}),
|
|
35247
|
+
listReferenceImages: method(zod.z.void(), zod.z.array(ReferenceImageEntrySchema).readonly()),
|
|
35248
|
+
getReferenceImage: method(zod.z.object({ filename: zod.z.string() }), ReferenceImageBodySchema.nullable()),
|
|
35249
|
+
getReferenceAudioFiles: method(zod.z.void(), zod.z.array(ReferenceAudioEntrySchema).readonly()),
|
|
35250
|
+
getReferenceAudio: method(zod.z.object({ filename: zod.z.string() }), ReferenceAudioBodySchema.nullable()),
|
|
35251
|
+
getAudioCapabilities: method(zod.z.void(), AudioCapabilitiesSchema),
|
|
35252
|
+
runAudioTest: method(zod.z.object({
|
|
35253
|
+
addonId: zod.z.string(),
|
|
35254
|
+
modelId: zod.z.string(),
|
|
35255
|
+
filename: zod.z.string().optional(),
|
|
35256
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
35257
|
+
}), AudioTestResultSchema, { kind: "mutation" }),
|
|
35258
|
+
getDetectionConfigSchema: method(zod.z.void(), ConfigUISchemaNullableBridge)
|
|
35259
|
+
}
|
|
35260
|
+
};
|
|
35261
|
+
var ZoneRuleModeEnum = zod.z.enum(["include", "exclude"]);
|
|
35262
|
+
var ZoneRuleSchema = zod.z.object({
|
|
35263
|
+
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
35264
|
+
id: zod.z.string(),
|
|
35265
|
+
/** Optional human-readable label rendered in the rule editor. */
|
|
35266
|
+
name: zod.z.string().optional(),
|
|
35267
|
+
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
35268
|
+
* listed zones (OR-set: a detection in any one of them counts).
|
|
35269
|
+
* At least one zone id required — a rule with no targets is a
|
|
35270
|
+
* configuration mistake and the form validator rejects it. */
|
|
35271
|
+
zoneIds: zod.z.array(zod.z.string()).min(1).readonly(),
|
|
35272
|
+
mode: ZoneRuleModeEnum,
|
|
35273
|
+
/**
|
|
35274
|
+
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
35275
|
+
* applies to every class. Class strings match the `macroClass`
|
|
35276
|
+
* field on detections (e.g. `person`, `car`, `dog`).
|
|
35277
|
+
*/
|
|
35278
|
+
classFilter: zod.z.array(zod.z.string()).readonly().optional(),
|
|
35279
|
+
/**
|
|
35280
|
+
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
35281
|
+
* required to consider an entity "in the zone". Defaults to the
|
|
35282
|
+
* consumer's stage default when omitted. Kept for back-compat with
|
|
35283
|
+
* existing per-rule overrides; new operators pick the value via
|
|
35284
|
+
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
35285
|
+
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
35286
|
+
*/
|
|
35287
|
+
overlapThreshold: zod.z.number().min(0).max(1).optional(),
|
|
35288
|
+
/**
|
|
35289
|
+
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
35290
|
+
* of the detection's bbox that must lie inside the zone for the
|
|
35291
|
+
* rule to match. Documented default is 85%; the engine substitutes
|
|
35292
|
+
* that when the field is omitted (kept optional so existing rules
|
|
35293
|
+
* stored without it stay valid).
|
|
35294
|
+
*
|
|
35295
|
+
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
35296
|
+
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
35297
|
+
* field exposed in the UI. Internally both feed the same gate.
|
|
35298
|
+
*/
|
|
35299
|
+
bboxInclusionPct: zod.z.number().min(0).max(100).optional(),
|
|
35300
|
+
/**
|
|
35301
|
+
* When `true` and a detection has a segmentation mask, use the
|
|
35302
|
+
* mask for overlap instead of the bbox. Detection-stage only;
|
|
35303
|
+
* motion rules ignore this field.
|
|
35304
|
+
*/
|
|
35305
|
+
preferMask: zod.z.boolean().optional(),
|
|
35306
|
+
/**
|
|
35307
|
+
* Soft-toggle: `false` disables the rule without deleting it.
|
|
35308
|
+
* Defaults to `true` so operators creating a rule via the UI
|
|
35309
|
+
* see it active immediately.
|
|
35310
|
+
*/
|
|
35311
|
+
enabled: zod.z.boolean().default(true)
|
|
35312
|
+
});
|
|
35313
|
+
zod.z.array(ZoneRuleSchema).readonly();
|
|
35314
|
+
var ZoneKindEnum = zod.z.enum(["polygon", "tripwire"]);
|
|
35315
|
+
var PolygonPointSchema = zod.z.object({
|
|
35316
|
+
x: zod.z.number(),
|
|
35317
|
+
y: zod.z.number()
|
|
35318
|
+
});
|
|
35319
|
+
var ZoneSchema = zod.z.object({
|
|
35320
|
+
id: zod.z.string(),
|
|
35321
|
+
name: zod.z.string(),
|
|
35322
|
+
kind: ZoneKindEnum.default("polygon"),
|
|
35323
|
+
/** Polygon vertices, fraction of frame (0–1). */
|
|
35324
|
+
polygon: zod.z.array(PolygonPointSchema).readonly(),
|
|
35325
|
+
/** Visual color for UI rendering. */
|
|
35326
|
+
color: zod.z.string().default("#3b82f6")
|
|
35327
|
+
});
|
|
35328
|
+
var zonesCapability = {
|
|
35329
|
+
name: "zones",
|
|
35330
|
+
scope: "device",
|
|
35331
|
+
mode: "singleton",
|
|
35332
|
+
deviceTypes: [DeviceType.Camera],
|
|
35333
|
+
methods: {
|
|
35334
|
+
listZones: method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(ZoneSchema).readonly()),
|
|
35335
|
+
addZone: method(zod.z.object({
|
|
35336
|
+
deviceId: zod.z.number(),
|
|
35337
|
+
zone: ZoneSchema
|
|
35338
|
+
}), zod.z.void(), {
|
|
35339
|
+
kind: "mutation",
|
|
35340
|
+
auth: "admin"
|
|
35341
|
+
}),
|
|
35342
|
+
removeZone: method(zod.z.object({
|
|
35343
|
+
deviceId: zod.z.number(),
|
|
35344
|
+
zoneId: zod.z.string()
|
|
35345
|
+
}), zod.z.void(), {
|
|
35346
|
+
kind: "mutation",
|
|
35347
|
+
auth: "admin"
|
|
35348
|
+
}),
|
|
35349
|
+
updateZone: method(zod.z.object({
|
|
35350
|
+
deviceId: zod.z.number(),
|
|
35351
|
+
zone: ZoneSchema
|
|
35352
|
+
}), zod.z.void(), {
|
|
35353
|
+
kind: "mutation",
|
|
35354
|
+
auth: "admin"
|
|
35355
|
+
})
|
|
35356
|
+
},
|
|
35357
|
+
/**
|
|
35358
|
+
* Runtime-state slice — the live zone catalogue mirrored by the
|
|
35359
|
+
* orchestrator on every CRUD mutation. Consumers read via
|
|
35360
|
+
* `device.state.zones.value` / `.watch(...)` without round-tripping
|
|
35361
|
+
* the cap, and the codegen DeviceProxy auto-wires the reactive
|
|
35362
|
+
* handle. Slice shape is `{ zones: Zone[] }` so future extensions
|
|
35363
|
+
* (e.g. zone groupings) can sit alongside the polygon list.
|
|
35364
|
+
*/
|
|
35365
|
+
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() }),
|
|
35366
|
+
/**
|
|
35367
|
+
* Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
|
|
35368
|
+
*
|
|
35369
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
35370
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
35371
|
+
*/
|
|
35372
|
+
durability: "restored"
|
|
35373
|
+
};
|
|
34624
35374
|
var TrackStateSchema = zod.z.enum([
|
|
34625
35375
|
"new",
|
|
34626
35376
|
"entered",
|
|
@@ -35441,6 +36191,25 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
35441
36191
|
/** Present when the pass ended by throwing. */
|
|
35442
36192
|
error: zod.z.string().nullable()
|
|
35443
36193
|
});
|
|
36194
|
+
var ReplayFrameInputSchema = zod.z.object({
|
|
36195
|
+
timestamp: zod.z.number(),
|
|
36196
|
+
frame: PipelineRunResultBridge
|
|
36197
|
+
});
|
|
36198
|
+
var ReplayTrackSchema = zod.z.object({
|
|
36199
|
+
className: zod.z.string(),
|
|
36200
|
+
firstSeenMs: zod.z.number(),
|
|
36201
|
+
lastSeenMs: zod.z.number(),
|
|
36202
|
+
/** Bbox of the track's FIRST matched detection, pixel-space in the clip's
|
|
36203
|
+
* frame — a representative box for the diff's `(className, window, IoU)`
|
|
36204
|
+
* pairing (`replay-diff.ts`). A replay does not need the full per-frame
|
|
36205
|
+
* trajectory production's `Track.positions` keeps. */
|
|
36206
|
+
bbox: BoundingBoxSchema,
|
|
36207
|
+
/** How many of the input frames this track matched a real detection on
|
|
36208
|
+
* (never a coasted/extrapolated frame) — the replay's own signal for "how
|
|
36209
|
+
* solid is this track", cheaper than re-deriving it from a trajectory. */
|
|
36210
|
+
framesMatched: zod.z.number().int()
|
|
36211
|
+
});
|
|
36212
|
+
var RunReplayFrameProcessorResultSchema = zod.z.object({ tracks: zod.z.array(ReplayTrackSchema).readonly() });
|
|
35444
36213
|
var pipelineAnalyticsCapability = {
|
|
35445
36214
|
name: "pipeline-analytics",
|
|
35446
36215
|
scope: "device",
|
|
@@ -35931,6 +36700,32 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
35931
36700
|
kind: "mutation",
|
|
35932
36701
|
auth: "admin"
|
|
35933
36702
|
}),
|
|
36703
|
+
/**
|
|
36704
|
+
* The FrameProcessor pass of a replay run — see the `Replay` section
|
|
36705
|
+
* above this capability's definition for why this is not the
|
|
36706
|
+
* `processFrame` method this file's header says pipeline-analytics does
|
|
36707
|
+
* not have.
|
|
36708
|
+
*
|
|
36709
|
+
* Constructs a FRESH `FrameProcessor` for `(deviceId, source)`, feeds it
|
|
36710
|
+
* `frames` IN THE ORDER GIVEN (the caller is responsible for time
|
|
36711
|
+
* ordering — this method does not sort), and returns the tracks it
|
|
36712
|
+
* produced. Zero persistence: no `TrackStore`, no event bus, no media
|
|
36713
|
+
* capture. `zones` / `detectionRules` are the run's OWN zone set —
|
|
36714
|
+
* typically the camera's real zones plus an ephemeral overlay
|
|
36715
|
+
* (`addon-benchmark`'s `replay-plan.ts`), never read from or written to
|
|
36716
|
+
* the `zones` capability by this method itself.
|
|
36717
|
+
*/
|
|
36718
|
+
runReplayFrameProcessor: method(zod.z.object({
|
|
36719
|
+
deviceId: zod.z.number(),
|
|
36720
|
+
source: DetectionSourceSchema,
|
|
36721
|
+
zones: zod.z.array(ZoneSchema).readonly().optional(),
|
|
36722
|
+
detectionRules: zod.z.array(ZoneRuleSchema).readonly().optional(),
|
|
36723
|
+
zoneMembershipMinOverlap: zod.z.number().min(0).max(1).optional(),
|
|
36724
|
+
frames: zod.z.array(ReplayFrameInputSchema).min(1)
|
|
36725
|
+
}), RunReplayFrameProcessorResultSchema, {
|
|
36726
|
+
kind: "mutation",
|
|
36727
|
+
auth: "admin"
|
|
36728
|
+
}),
|
|
35934
36729
|
/** Every annotation on a track, oldest first. */
|
|
35935
36730
|
listRetrainAnnotations: method(zod.z.object({ trackId: zod.z.string() }), zod.z.array(RetrainAnnotationSchema).readonly(), {
|
|
35936
36731
|
kind: "query",
|
|
@@ -36097,559 +36892,6 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
36097
36892
|
}) }
|
|
36098
36893
|
}
|
|
36099
36894
|
};
|
|
36100
|
-
var NativeCropRefSchema = zod.z.object({
|
|
36101
|
-
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
36102
|
-
handle: FrameHandleSchema,
|
|
36103
|
-
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
36104
|
-
cropFrameSpace: zod.z.object({
|
|
36105
|
-
x: zod.z.number(),
|
|
36106
|
-
y: zod.z.number(),
|
|
36107
|
-
w: zod.z.number(),
|
|
36108
|
-
h: zod.z.number()
|
|
36109
|
-
})
|
|
36110
|
-
});
|
|
36111
|
-
zod.z.object({
|
|
36112
|
-
crop: zod.z.object({
|
|
36113
|
-
left: zod.z.number(),
|
|
36114
|
-
top: zod.z.number(),
|
|
36115
|
-
width: zod.z.number().positive(),
|
|
36116
|
-
height: zod.z.number().positive()
|
|
36117
|
-
}).optional(),
|
|
36118
|
-
content: zod.z.object({
|
|
36119
|
-
width: zod.z.number().int().positive(),
|
|
36120
|
-
height: zod.z.number().int().positive()
|
|
36121
|
-
}),
|
|
36122
|
-
fit: zod.z.enum(["stretch", "contain"]),
|
|
36123
|
-
format: zod.z.enum([
|
|
36124
|
-
"rgb",
|
|
36125
|
-
"gray",
|
|
36126
|
-
"jpeg"
|
|
36127
|
-
])
|
|
36128
|
-
});
|
|
36129
|
-
var FrameRefSchema = zod.z.object({
|
|
36130
|
-
registryId: zod.z.string().min(1),
|
|
36131
|
-
id: zod.z.string().min(1),
|
|
36132
|
-
width: zod.z.number().int().positive(),
|
|
36133
|
-
height: zod.z.number().int().positive(),
|
|
36134
|
-
format: zod.z.enum(["rgb", "gray"]),
|
|
36135
|
-
timestamp: zod.z.number(),
|
|
36136
|
-
capturedAt: zod.z.number().optional()
|
|
36137
|
-
});
|
|
36138
|
-
var ModelFormatSchema$1 = zod.z.enum([
|
|
36139
|
-
"onnx",
|
|
36140
|
-
"coreml",
|
|
36141
|
-
"openvino",
|
|
36142
|
-
"tflite",
|
|
36143
|
-
"pt",
|
|
36144
|
-
"gguf"
|
|
36145
|
-
]);
|
|
36146
|
-
var PipelineSlotSchema = zod.z.enum([
|
|
36147
|
-
"detector",
|
|
36148
|
-
"cropper",
|
|
36149
|
-
"classifier",
|
|
36150
|
-
"refiner",
|
|
36151
|
-
"audio-classifier"
|
|
36152
|
-
]);
|
|
36153
|
-
var PipelineEngineChoiceSchema = zod.z.object({
|
|
36154
|
-
runtime: zod.z.enum(["node", "python"]),
|
|
36155
|
-
backend: zod.z.string(),
|
|
36156
|
-
format: ModelFormatSchema$1,
|
|
36157
|
-
device: zod.z.string().optional()
|
|
36158
|
-
});
|
|
36159
|
-
var EngineDeviceInfoSchema = zod.z.object({
|
|
36160
|
-
id: zod.z.string(),
|
|
36161
|
-
label: zod.z.string(),
|
|
36162
|
-
description: zod.z.string().optional()
|
|
36163
|
-
});
|
|
36164
|
-
var AvailableEngineSchema = zod.z.object({
|
|
36165
|
-
engine: PipelineEngineChoiceSchema,
|
|
36166
|
-
devices: zod.z.array(EngineDeviceInfoSchema).readonly(),
|
|
36167
|
-
defaultDevice: zod.z.string()
|
|
36168
|
-
});
|
|
36169
|
-
var PipelineDefaultStepSchema = zod.z.lazy(() => zod.z.object({
|
|
36170
|
-
addonId: zod.z.string(),
|
|
36171
|
-
addonName: zod.z.string(),
|
|
36172
|
-
slot: PipelineSlotSchema,
|
|
36173
|
-
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
36174
|
-
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
36175
|
-
enabled: zod.z.boolean(),
|
|
36176
|
-
modelId: zod.z.string(),
|
|
36177
|
-
children: zod.z.array(PipelineDefaultStepSchema).readonly(),
|
|
36178
|
-
group: zod.z.string().optional(),
|
|
36179
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
36180
|
-
}));
|
|
36181
|
-
var PipelineTemplateStepSchema = zod.z.lazy(() => zod.z.object({
|
|
36182
|
-
addonId: zod.z.string(),
|
|
36183
|
-
enabled: zod.z.boolean(),
|
|
36184
|
-
modelId: zod.z.string(),
|
|
36185
|
-
children: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
36186
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
36187
|
-
}));
|
|
36188
|
-
var PipelineTemplateSchema$1 = zod.z.object({
|
|
36189
|
-
id: zod.z.string(),
|
|
36190
|
-
name: zod.z.string(),
|
|
36191
|
-
createdAt: zod.z.string(),
|
|
36192
|
-
updatedAt: zod.z.string(),
|
|
36193
|
-
engine: PipelineEngineChoiceSchema,
|
|
36194
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly()
|
|
36195
|
-
});
|
|
36196
|
-
var PipelineModelOptionSchema = zod.z.object({
|
|
36197
|
-
id: zod.z.string(),
|
|
36198
|
-
name: zod.z.string(),
|
|
36199
|
-
formats: zod.z.record(zod.z.string(), zod.z.object({
|
|
36200
|
-
downloaded: zod.z.boolean(),
|
|
36201
|
-
sizeMB: zod.z.number()
|
|
36202
|
-
})),
|
|
36203
|
-
group: ModelVariantGroupSchema.optional(),
|
|
36204
|
-
legacy: zod.z.boolean().optional(),
|
|
36205
|
-
provider: ModelProviderIdSchema.optional()
|
|
36206
|
-
});
|
|
36207
|
-
var ConfigFieldBridge = zod.z.custom();
|
|
36208
|
-
var PipelineAddonSchemaSchema = zod.z.object({
|
|
36209
|
-
id: zod.z.string(),
|
|
36210
|
-
name: zod.z.string(),
|
|
36211
|
-
slot: PipelineSlotSchema,
|
|
36212
|
-
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
36213
|
-
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
36214
|
-
childSlots: zod.z.array(PipelineSlotSchema).readonly(),
|
|
36215
|
-
models: zod.z.array(PipelineModelOptionSchema).readonly(),
|
|
36216
|
-
defaultModelId: zod.z.string(),
|
|
36217
|
-
defaultModelIdByFormat: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
36218
|
-
enabledByDefault: zod.z.boolean().optional(),
|
|
36219
|
-
backfillIntoExistingOverrides: zod.z.boolean().optional(),
|
|
36220
|
-
defaultConfidence: zod.z.number(),
|
|
36221
|
-
group: zod.z.string().optional(),
|
|
36222
|
-
configSchema: zod.z.array(ConfigFieldBridge).readonly().optional()
|
|
36223
|
-
});
|
|
36224
|
-
var PipelineSlotSchemaSchema = zod.z.object({
|
|
36225
|
-
id: PipelineSlotSchema,
|
|
36226
|
-
label: zod.z.string(),
|
|
36227
|
-
priority: zod.z.number(),
|
|
36228
|
-
parentSlot: PipelineSlotSchema.nullable(),
|
|
36229
|
-
addons: zod.z.array(PipelineAddonSchemaSchema).readonly()
|
|
36230
|
-
});
|
|
36231
|
-
var PipelineSchemaSchema = zod.z.object({
|
|
36232
|
-
availableEngines: zod.z.array(AvailableEngineSchema).readonly(),
|
|
36233
|
-
selectedEngine: PipelineEngineChoiceSchema,
|
|
36234
|
-
slots: zod.z.array(PipelineSlotSchemaSchema).readonly()
|
|
36235
|
-
});
|
|
36236
|
-
var EngineProvisioningSchema = zod.z.object({
|
|
36237
|
-
runtimeId: zod.z.enum([
|
|
36238
|
-
"onnx",
|
|
36239
|
-
"openvino",
|
|
36240
|
-
"coreml",
|
|
36241
|
-
"edgetpu"
|
|
36242
|
-
]).nullable(),
|
|
36243
|
-
device: zod.z.string().nullable(),
|
|
36244
|
-
state: zod.z.enum([
|
|
36245
|
-
"idle",
|
|
36246
|
-
"installing",
|
|
36247
|
-
"verifying",
|
|
36248
|
-
"ready",
|
|
36249
|
-
"failed"
|
|
36250
|
-
]),
|
|
36251
|
-
progress: zod.z.number().optional(),
|
|
36252
|
-
error: zod.z.string().optional(),
|
|
36253
|
-
nextRetryAt: zod.z.number().optional(),
|
|
36254
|
-
/**
|
|
36255
|
-
* Gate A (config-correctness gate at engine change): human-readable
|
|
36256
|
-
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
36257
|
-
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
36258
|
-
* has a <format> build"). Additive/optional: informational only, never
|
|
36259
|
-
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
36260
|
-
* Absent/empty when the node-default tree resolves cleanly.
|
|
36261
|
-
*/
|
|
36262
|
-
configIssues: zod.z.array(zod.z.string()).optional()
|
|
36263
|
-
});
|
|
36264
|
-
var PipelineStepInputSchema = zod.z.lazy(() => zod.z.object({
|
|
36265
|
-
addonId: zod.z.string(),
|
|
36266
|
-
modelId: zod.z.string().optional(),
|
|
36267
|
-
enabled: zod.z.boolean().default(true),
|
|
36268
|
-
children: zod.z.array(PipelineStepInputSchema).optional(),
|
|
36269
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
36270
|
-
jumpDeviceKey: zod.z.string().optional()
|
|
36271
|
-
}));
|
|
36272
|
-
var ModelSubstitutionSchema = zod.z.object({
|
|
36273
|
-
addonId: zod.z.string(),
|
|
36274
|
-
chosen: zod.z.string(),
|
|
36275
|
-
running: zod.z.string(),
|
|
36276
|
-
format: zod.z.string()
|
|
36277
|
-
});
|
|
36278
|
-
var PipelineValidationIssueSchema = zod.z.object({
|
|
36279
|
-
addonId: zod.z.string(),
|
|
36280
|
-
kind: zod.z.enum(["unknown-addon", "no-format-build"]),
|
|
36281
|
-
detail: zod.z.string()
|
|
36282
|
-
});
|
|
36283
|
-
var PipelineValidationResultSchema = zod.z.object({
|
|
36284
|
-
ok: zod.z.boolean(),
|
|
36285
|
-
issues: zod.z.array(PipelineValidationIssueSchema).readonly(),
|
|
36286
|
-
substitutions: zod.z.array(ModelSubstitutionSchema).readonly(),
|
|
36287
|
-
/** The node's `currentEngine.format` this validation ran against. */
|
|
36288
|
-
format: zod.z.string()
|
|
36289
|
-
});
|
|
36290
|
-
var ReferenceImageEntrySchema = zod.z.object({
|
|
36291
|
-
filename: zod.z.string(),
|
|
36292
|
-
stepIds: zod.z.array(zod.z.string()).readonly().optional()
|
|
36293
|
-
});
|
|
36294
|
-
var ReferenceImageBodySchema = zod.z.object({
|
|
36295
|
-
base64: zod.z.string(),
|
|
36296
|
-
filename: zod.z.string()
|
|
36297
|
-
});
|
|
36298
|
-
var ReferenceAudioEntrySchema = zod.z.object({
|
|
36299
|
-
filename: zod.z.string(),
|
|
36300
|
-
sizeKb: zod.z.number()
|
|
36301
|
-
});
|
|
36302
|
-
var ReferenceAudioBodySchema = zod.z.object({ base64: zod.z.string() });
|
|
36303
|
-
var AudioBackendSchema = zod.z.object({
|
|
36304
|
-
id: zod.z.string(),
|
|
36305
|
-
name: zod.z.string(),
|
|
36306
|
-
description: zod.z.string(),
|
|
36307
|
-
available: zod.z.boolean(),
|
|
36308
|
-
/**
|
|
36309
|
-
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
36310
|
-
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
36311
|
-
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
36312
|
-
* specific to the selected backend without a separate fetch.
|
|
36313
|
-
*/
|
|
36314
|
-
rawLabels: zod.z.array(zod.z.string()).readonly().optional()
|
|
36315
|
-
});
|
|
36316
|
-
var AudioCapabilitiesSchema = zod.z.object({
|
|
36317
|
-
activeBackend: zod.z.string(),
|
|
36318
|
-
availableBackends: zod.z.array(AudioBackendSchema).readonly(),
|
|
36319
|
-
sampleRate: zod.z.number(),
|
|
36320
|
-
chunkDurationMs: zod.z.number()
|
|
36321
|
-
});
|
|
36322
|
-
var DownloadModelResultSchema = zod.z.object({
|
|
36323
|
-
filePath: zod.z.string(),
|
|
36324
|
-
sizeMB: zod.z.number(),
|
|
36325
|
-
durationMs: zod.z.number()
|
|
36326
|
-
});
|
|
36327
|
-
var AudioTestResultSchema = zod.z.object({
|
|
36328
|
-
success: zod.z.boolean(),
|
|
36329
|
-
error: zod.z.string().optional(),
|
|
36330
|
-
frame: zod.z.custom().optional()
|
|
36331
|
-
});
|
|
36332
|
-
var PipelineConfigBridge = zod.z.custom();
|
|
36333
|
-
var ConfigUISchemaBridge = zod.z.custom();
|
|
36334
|
-
var ConfigUISchemaNullableBridge = zod.z.custom();
|
|
36335
|
-
var InferenceCapabilitiesBridge = zod.z.custom();
|
|
36336
|
-
var ModelAvailabilityListBridge = zod.z.custom();
|
|
36337
|
-
var PipelineRunResultBridge = zod.z.custom();
|
|
36338
|
-
var pipelineExecutorCapability = {
|
|
36339
|
-
name: "pipeline-executor",
|
|
36340
|
-
scope: "system",
|
|
36341
|
-
mode: "singleton",
|
|
36342
|
-
methods: {
|
|
36343
|
-
getAvailableEngines: method(zod.z.void(), zod.z.array(PipelineEngineChoiceSchema)),
|
|
36344
|
-
getSelectedEngine: method(zod.z.void(), PipelineEngineChoiceSchema),
|
|
36345
|
-
getDefaultSteps: method(PipelineEngineChoiceSchema, zod.z.array(PipelineDefaultStepSchema)),
|
|
36346
|
-
/**
|
|
36347
|
-
* Per-node detection-engine provisioning snapshot. Returns the live
|
|
36348
|
-
* state of the lazy runtime-provisioning machine on `nodeId`
|
|
36349
|
-
* (idle / installing / verifying / ready / failed). The UI pairs this
|
|
36350
|
-
* one-shot query with the `pipeline.engine-provisioning` live event
|
|
36351
|
-
* (emitted on every transition) to drive a per-node "engine ready?"
|
|
36352
|
-
* indicator without polling. Phase 2.
|
|
36353
|
-
*/
|
|
36354
|
-
getEngineProvisioning: method(zod.z.object({ nodeId: zod.z.string() }), EngineProvisioningSchema),
|
|
36355
|
-
getVideoPipelineSteps: method(zod.z.void(), zod.z.record(zod.z.string(), zod.z.object({
|
|
36356
|
-
modelId: zod.z.string(),
|
|
36357
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
36358
|
-
}))),
|
|
36359
|
-
setVideoPipelineSteps: method(zod.z.object({ steps: zod.z.record(zod.z.string(), zod.z.object({
|
|
36360
|
-
modelId: zod.z.string(),
|
|
36361
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
36362
|
-
})) }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
36363
|
-
kind: "mutation",
|
|
36364
|
-
auth: "admin"
|
|
36365
|
-
}),
|
|
36366
|
-
/**
|
|
36367
|
-
* Clear THIS node's executor-side PER-DEVICE settings stores (the
|
|
36368
|
-
* per-camera step overrides the object-detection root reads via
|
|
36369
|
-
* `applyDeviceOverridesToTree`). `nodeId` is the ROUTING key — the
|
|
36370
|
-
* generated cap-router strips it (default `nodeIdMode: 'routing'`) and
|
|
36371
|
-
* dispatches to that node, so the provider method runs ON the target
|
|
36372
|
-
* node and receives no `nodeId`.
|
|
36373
|
-
*
|
|
36374
|
-
* This is the slimmed executor leg of the orchestrator's
|
|
36375
|
-
* `resetNodePipelineDefaults` flow (which owns the real reset: node
|
|
36376
|
-
* addonDefaults pins + per-camera orchestrator overrides). The legacy
|
|
36377
|
-
* `resetToDefault` — which reset a persisted global step-tree seed
|
|
36378
|
-
* nothing in the live per-camera path read — was removed together with
|
|
36379
|
-
* that seed.
|
|
36380
|
-
*/
|
|
36381
|
-
clearDeviceOverrides: method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({
|
|
36382
|
-
success: zod.z.literal(true),
|
|
36383
|
-
clearedDevices: zod.z.number()
|
|
36384
|
-
}), {
|
|
36385
|
-
kind: "mutation",
|
|
36386
|
-
auth: "admin"
|
|
36387
|
-
}),
|
|
36388
|
-
getSchema: method(zod.z.void(), PipelineSchemaSchema),
|
|
36389
|
-
getGlobalSteps: method(zod.z.void(), zod.z.array(PipelineDefaultStepSchema).readonly().nullable()),
|
|
36390
|
-
getGlobalPipelineConfig: method(zod.z.void(), PipelineConfigBridge),
|
|
36391
|
-
getOrchestratorConfigSchema: method(zod.z.void(), ConfigUISchemaBridge),
|
|
36392
|
-
/**
|
|
36393
|
-
* Gate B (pre-init config-correctness gate). PURE COMPUTE against this
|
|
36394
|
-
* node's `currentEngine.format` — resolves `steps` the same way the
|
|
36395
|
-
* runtime dispatch path would, and reports what WOULD happen without
|
|
36396
|
-
* touching any node-global state. Called by the orchestrator at attach
|
|
36397
|
-
* time (`attachOn`), node-pinned to the TARGET node, so config problems
|
|
36398
|
-
* surface BEFORE `pipelineRunner.attachCamera` rather than at the first
|
|
36399
|
-
* per-frame resolve. `ok` is false iff `issues` is non-empty (both
|
|
36400
|
-
* `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
|
|
36401
|
-
* is informational (a degraded-but-loadable model swap) and never
|
|
36402
|
-
* affects `ok`. Never throws.
|
|
36403
|
-
*/
|
|
36404
|
-
validatePipeline: method(zod.z.object({ steps: zod.z.array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
|
|
36405
|
-
listTemplates: method(zod.z.void(), zod.z.array(PipelineTemplateSchema$1).readonly()),
|
|
36406
|
-
saveTemplate: method(zod.z.object({
|
|
36407
|
-
name: zod.z.string(),
|
|
36408
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
36409
|
-
engine: PipelineEngineChoiceSchema
|
|
36410
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
36411
|
-
updateTemplate: method(zod.z.object({
|
|
36412
|
-
id: zod.z.string(),
|
|
36413
|
-
name: zod.z.string().optional(),
|
|
36414
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly().optional()
|
|
36415
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
36416
|
-
deleteTemplate: method(zod.z.object({ id: zod.z.string() }), zod.z.void(), { kind: "mutation" }),
|
|
36417
|
-
getCapabilities: method(zod.z.void(), InferenceCapabilitiesBridge),
|
|
36418
|
-
getAddonModels: method(zod.z.object({ addonId: zod.z.string() }), ModelAvailabilityListBridge),
|
|
36419
|
-
downloadModel: method(zod.z.object({
|
|
36420
|
-
addonId: zod.z.string(),
|
|
36421
|
-
modelId: zod.z.string(),
|
|
36422
|
-
format: ModelFormatSchema$1
|
|
36423
|
-
}), DownloadModelResultSchema, { kind: "mutation" }),
|
|
36424
|
-
deleteModel: method(zod.z.object({
|
|
36425
|
-
addonId: zod.z.string(),
|
|
36426
|
-
modelId: zod.z.string(),
|
|
36427
|
-
format: ModelFormatSchema$1
|
|
36428
|
-
}), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }),
|
|
36429
|
-
/**
|
|
36430
|
-
* Stateless single-frame execution. Callers (runner, benchmark) pass
|
|
36431
|
-
* the complete `engine` + `steps` tree; the executor holds no state
|
|
36432
|
-
* about cameras or saved pipelines.
|
|
36433
|
-
*
|
|
36434
|
-
* `engine` is optional during the migration window to preserve the
|
|
36435
|
-
* legacy call shape used by existing benchmark code; once all
|
|
36436
|
-
* callers pass it explicitly we make it required.
|
|
36437
|
-
*
|
|
36438
|
-
* Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
|
|
36439
|
-
* `referenceImage` must be provided:
|
|
36440
|
-
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
36441
|
-
* Carries the raw buffer, dimensions, and format; the executor
|
|
36442
|
-
* uses it directly without base64 round-tripping.
|
|
36443
|
-
* - `frameHandle` (CB5): a zero-pixel shm `FrameHandle` for the SAME
|
|
36444
|
-
* decoded frame. Both runner and executor are hub-local processes
|
|
36445
|
-
* sharing `/dev/shm`, so the executor maps the named segment and
|
|
36446
|
-
* reads the pixels back zero-copy — eliminating the ~1.2MB
|
|
36447
|
-
* re-serialisation over UDS/MsgPack the `frame` path pays per call.
|
|
36448
|
-
* High-risk: the FrameRing is a latest-wins seqlock with no
|
|
36449
|
-
* refcount, so a recycled slot yields a null read; the executor
|
|
36450
|
-
* then degrades to an empty result and the runner ships pixels via
|
|
36451
|
-
* `frame` as the fallback (queue-depth gated on the runner side).
|
|
36452
|
-
* - `imageBase64`: one-shot test path (benchmark ImageTab).
|
|
36453
|
-
* - `referenceImage`: named file from the reference-image store.
|
|
36454
|
-
*/
|
|
36455
|
-
runPipeline: method(zod.z.object({
|
|
36456
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
36457
|
-
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
36458
|
-
frame: FrameInputSchema.optional(),
|
|
36459
|
-
/**
|
|
36460
|
-
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
36461
|
-
* in the same execution-group process; split/cross-node callers use
|
|
36462
|
-
* `frame`/`image` inline compatibility instead.
|
|
36463
|
-
*/
|
|
36464
|
-
frameRef: FrameRefSchema.optional(),
|
|
36465
|
-
/**
|
|
36466
|
-
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
36467
|
-
* the decoded pixels live in. One more member of the one-of
|
|
36468
|
-
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
36469
|
-
*/
|
|
36470
|
-
frameHandle: FrameHandleSchema.optional(),
|
|
36471
|
-
imageBase64: zod.z.string().optional(),
|
|
36472
|
-
/**
|
|
36473
|
-
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
36474
|
-
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
36475
|
-
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
36476
|
-
* the detection-pipeline worker. Callers can pass either; exactly
|
|
36477
|
-
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
36478
|
-
*/
|
|
36479
|
-
image: zod.z.instanceof(Uint8Array).optional(),
|
|
36480
|
-
referenceImage: zod.z.string().optional(),
|
|
36481
|
-
deviceId: zod.z.number().optional(),
|
|
36482
|
-
sessionId: zod.z.string().optional(),
|
|
36483
|
-
/**
|
|
36484
|
-
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
36485
|
-
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
36486
|
-
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
36487
|
-
* (inputClasses ≠ null) are skipped and served per-track via
|
|
36488
|
-
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
36489
|
-
*/
|
|
36490
|
-
plane: zod.z.enum(["full", "frame"]).optional(),
|
|
36491
|
-
/**
|
|
36492
|
-
* Inference-device selector (Phase 2 multi-device). Format
|
|
36493
|
-
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
36494
|
-
* Omitted ⇒ the runner's default device (current single-engine
|
|
36495
|
-
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
36496
|
-
*/
|
|
36497
|
-
deviceKey: zod.z.string().optional(),
|
|
36498
|
-
/**
|
|
36499
|
-
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
36500
|
-
* when the parent crop was resolved from the frame's retained NATIVE
|
|
36501
|
-
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
36502
|
-
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
36503
|
-
* resolution from that surface — the SAME quality path faces already
|
|
36504
|
-
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
36505
|
-
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
36506
|
-
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
36507
|
-
* the executor's crop-normalized child ROI back into frame-normalized
|
|
36508
|
-
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
36509
|
-
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
36510
|
-
* (today's behaviour on the fallback path).
|
|
36511
|
-
*/
|
|
36512
|
-
nativeCropRef: NativeCropRefSchema.optional()
|
|
36513
|
-
}), PipelineRunResultBridge, { kind: "mutation" }),
|
|
36514
|
-
/**
|
|
36515
|
-
* Batched run — N raw frames packed into one cap call. The provider
|
|
36516
|
-
* routes the batch through `SharedInferencePool.inferBatch`
|
|
36517
|
-
* (`MSG_INFER_BATCH = 0x03`) so the IPC framing and JSON response
|
|
36518
|
-
* envelope cost is amortised N:1 vs N concurrent `runPipeline`
|
|
36519
|
-
* calls. Single root step + uniform model assumed; trees with crop
|
|
36520
|
-
* children fall back to sequential execution.
|
|
36521
|
-
*
|
|
36522
|
-
* Used by `scripts/bench-batch-style.mts` for batch benchmarking —
|
|
36523
|
-
* N frames in one call to amortise per-call IPC overhead.
|
|
36524
|
-
*/
|
|
36525
|
-
runPipelineBatch: method(zod.z.object({
|
|
36526
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
36527
|
-
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
36528
|
-
frames: zod.z.array(FrameInputSchema).min(1).max(255),
|
|
36529
|
-
deviceId: zod.z.number().optional(),
|
|
36530
|
-
sessionId: zod.z.string().optional(),
|
|
36531
|
-
/**
|
|
36532
|
-
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
36533
|
-
* the batch to the Python pool's bench preprocess cache
|
|
36534
|
-
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
36535
|
-
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
36536
|
-
* hit — the sustained-throughput run measures inference, not
|
|
36537
|
-
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
36538
|
-
* full preprocess every call, correct). Fresh per sustained run;
|
|
36539
|
-
* released via `uncacheFrame`.
|
|
36540
|
-
*/
|
|
36541
|
-
frameId: zod.z.number().int().nonnegative().optional(),
|
|
36542
|
-
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
36543
|
-
deviceKey: zod.z.string().optional()
|
|
36544
|
-
}), zod.z.object({ results: zod.z.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
|
|
36545
|
-
/**
|
|
36546
|
-
* Cache a raw frame inside the Python inference pool's memory.
|
|
36547
|
-
* Returns a numeric `frameId` that `inferCached` references —
|
|
36548
|
-
* subsequent calls send only 5 bytes through the pipe instead of
|
|
36549
|
-
* 1.2MB raw data, eliminating the pipe transfer bottleneck.
|
|
36550
|
-
*/
|
|
36551
|
-
cacheFrameInPool: method(zod.z.object({
|
|
36552
|
-
data: zod.z.instanceof(Uint8Array),
|
|
36553
|
-
width: zod.z.number().int().positive(),
|
|
36554
|
-
height: zod.z.number().int().positive(),
|
|
36555
|
-
format: zod.z.enum([
|
|
36556
|
-
"rgb",
|
|
36557
|
-
"bgr",
|
|
36558
|
-
"gray"
|
|
36559
|
-
])
|
|
36560
|
-
}), zod.z.object({
|
|
36561
|
-
frameId: zod.z.number(),
|
|
36562
|
-
width: zod.z.number(),
|
|
36563
|
-
height: zod.z.number()
|
|
36564
|
-
}), { kind: "mutation" }),
|
|
36565
|
-
/**
|
|
36566
|
-
* Run inference on a previously cached frame. Sends only 5 bytes
|
|
36567
|
-
* (model_idx + frameId) through the IPC pipe — eliminates the
|
|
36568
|
-
* ~35ms per-call overhead of transferring 1.2MB raw data.
|
|
36569
|
-
*/
|
|
36570
|
-
inferCached: method(zod.z.object({
|
|
36571
|
-
stepId: zod.z.string(),
|
|
36572
|
-
frameId: zod.z.number().int()
|
|
36573
|
-
}), zod.z.record(zod.z.string(), zod.z.unknown()), { kind: "mutation" }),
|
|
36574
|
-
/**
|
|
36575
|
-
* Release a cached frame from the Python pool's memory.
|
|
36576
|
-
*/
|
|
36577
|
-
uncacheFrame: method(zod.z.object({ frameId: zod.z.number().int() }), zod.z.void(), { kind: "mutation" }),
|
|
36578
|
-
/** Returns the effective pool tuning (resolved from user overrides + backend defaults). */
|
|
36579
|
-
getEffectiveTuning: method(zod.z.void(), zod.z.object({
|
|
36580
|
-
batchMode: zod.z.string(),
|
|
36581
|
-
windowMs: zod.z.number(),
|
|
36582
|
-
maxBatchSize: zod.z.number(),
|
|
36583
|
-
concurrency: zod.z.number()
|
|
36584
|
-
})),
|
|
36585
|
-
/**
|
|
36586
|
-
* List every EngineFactory currently loaded in this executor's RAM,
|
|
36587
|
-
* with the models resident and a coarse "in use" marker derived from
|
|
36588
|
-
* ongoing inference activity. Used by the Pipeline page Engines tab.
|
|
36589
|
-
*/
|
|
36590
|
-
listLoadedEngines: method(zod.z.void(), zod.z.array(zod.z.object({
|
|
36591
|
-
engineKey: zod.z.string(),
|
|
36592
|
-
engine: PipelineEngineChoiceSchema,
|
|
36593
|
-
modelsLoaded: zod.z.array(zod.z.string()).readonly(),
|
|
36594
|
-
inUseByCameras: zod.z.array(zod.z.number()).readonly(),
|
|
36595
|
-
/**
|
|
36596
|
-
* Origin of this resident factory.
|
|
36597
|
-
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
36598
|
-
* - `warm-override` — benchmark/test override held in the warm
|
|
36599
|
-
* cache; auto-disposed after the idle TTL.
|
|
36600
|
-
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
36601
|
-
* multi-device, keyed by `deviceKey`) resolved
|
|
36602
|
-
* via `resolveDeviceFactory`. Runs alongside the
|
|
36603
|
-
* `runtime` engine on a DIFFERENT accelerator
|
|
36604
|
-
* (NPU / iGPU / Coral) — this is how the
|
|
36605
|
-
* Engines tab shows all pools running at once.
|
|
36606
|
-
*/
|
|
36607
|
-
kind: zod.z.enum([
|
|
36608
|
-
"runtime",
|
|
36609
|
-
"warm-override",
|
|
36610
|
-
"device-pool"
|
|
36611
|
-
]),
|
|
36612
|
-
/** Native pid of the underlying Python pool (null when no pool). */
|
|
36613
|
-
poolPid: zod.z.number().nullable(),
|
|
36614
|
-
/** ms since this factory was last used (null when not warm-tracked). */
|
|
36615
|
-
idleMs: zod.z.number().nullable(),
|
|
36616
|
-
/** Idle TTL after which `warm-override` factories self-evict (null when not applicable). */
|
|
36617
|
-
idleTtlMs: zod.z.number().nullable()
|
|
36618
|
-
})).readonly()),
|
|
36619
|
-
/** Warm up an engine without running a frame. No-op if already loaded. */
|
|
36620
|
-
spinEngine: method(zod.z.object({ engine: PipelineEngineChoiceSchema }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
36621
|
-
kind: "mutation",
|
|
36622
|
-
auth: "admin"
|
|
36623
|
-
}),
|
|
36624
|
-
/**
|
|
36625
|
-
* Unload an engine from RAM. `force:true` unloads even when cameras
|
|
36626
|
-
* are actively using it (they re-spin on next frame). Default is
|
|
36627
|
-
* gated — returns `{success:false, reason}` when in use.
|
|
36628
|
-
*/
|
|
36629
|
-
killEngine: method(zod.z.object({
|
|
36630
|
-
engine: PipelineEngineChoiceSchema,
|
|
36631
|
-
force: zod.z.boolean().optional()
|
|
36632
|
-
}), zod.z.object({
|
|
36633
|
-
success: zod.z.boolean(),
|
|
36634
|
-
reason: zod.z.string().optional()
|
|
36635
|
-
}), {
|
|
36636
|
-
kind: "mutation",
|
|
36637
|
-
auth: "admin"
|
|
36638
|
-
}),
|
|
36639
|
-
listReferenceImages: method(zod.z.void(), zod.z.array(ReferenceImageEntrySchema).readonly()),
|
|
36640
|
-
getReferenceImage: method(zod.z.object({ filename: zod.z.string() }), ReferenceImageBodySchema.nullable()),
|
|
36641
|
-
getReferenceAudioFiles: method(zod.z.void(), zod.z.array(ReferenceAudioEntrySchema).readonly()),
|
|
36642
|
-
getReferenceAudio: method(zod.z.object({ filename: zod.z.string() }), ReferenceAudioBodySchema.nullable()),
|
|
36643
|
-
getAudioCapabilities: method(zod.z.void(), AudioCapabilitiesSchema),
|
|
36644
|
-
runAudioTest: method(zod.z.object({
|
|
36645
|
-
addonId: zod.z.string(),
|
|
36646
|
-
modelId: zod.z.string(),
|
|
36647
|
-
filename: zod.z.string().optional(),
|
|
36648
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
36649
|
-
}), AudioTestResultSchema, { kind: "mutation" }),
|
|
36650
|
-
getDetectionConfigSchema: method(zod.z.void(), ConfigUISchemaNullableBridge)
|
|
36651
|
-
}
|
|
36652
|
-
};
|
|
36653
36895
|
zod.z.object({
|
|
36654
36896
|
activeCameras: zod.z.number(),
|
|
36655
36897
|
throttledCameras: zod.z.number(),
|
|
@@ -36674,66 +36916,6 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
36674
36916
|
])
|
|
36675
36917
|
});
|
|
36676
36918
|
var CameraMetricsWithDeviceIdSchema = CameraMetricsSchema.extend({ deviceId: zod.z.number() });
|
|
36677
|
-
var ZoneKindEnum = zod.z.enum(["polygon", "tripwire"]);
|
|
36678
|
-
var PolygonPointSchema = zod.z.object({
|
|
36679
|
-
x: zod.z.number(),
|
|
36680
|
-
y: zod.z.number()
|
|
36681
|
-
});
|
|
36682
|
-
var ZoneSchema = zod.z.object({
|
|
36683
|
-
id: zod.z.string(),
|
|
36684
|
-
name: zod.z.string(),
|
|
36685
|
-
kind: ZoneKindEnum.default("polygon"),
|
|
36686
|
-
/** Polygon vertices, fraction of frame (0–1). */
|
|
36687
|
-
polygon: zod.z.array(PolygonPointSchema).readonly(),
|
|
36688
|
-
/** Visual color for UI rendering. */
|
|
36689
|
-
color: zod.z.string().default("#3b82f6")
|
|
36690
|
-
});
|
|
36691
|
-
var zonesCapability = {
|
|
36692
|
-
name: "zones",
|
|
36693
|
-
scope: "device",
|
|
36694
|
-
mode: "singleton",
|
|
36695
|
-
deviceTypes: [DeviceType.Camera],
|
|
36696
|
-
methods: {
|
|
36697
|
-
listZones: method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(ZoneSchema).readonly()),
|
|
36698
|
-
addZone: method(zod.z.object({
|
|
36699
|
-
deviceId: zod.z.number(),
|
|
36700
|
-
zone: ZoneSchema
|
|
36701
|
-
}), zod.z.void(), {
|
|
36702
|
-
kind: "mutation",
|
|
36703
|
-
auth: "admin"
|
|
36704
|
-
}),
|
|
36705
|
-
removeZone: method(zod.z.object({
|
|
36706
|
-
deviceId: zod.z.number(),
|
|
36707
|
-
zoneId: zod.z.string()
|
|
36708
|
-
}), zod.z.void(), {
|
|
36709
|
-
kind: "mutation",
|
|
36710
|
-
auth: "admin"
|
|
36711
|
-
}),
|
|
36712
|
-
updateZone: method(zod.z.object({
|
|
36713
|
-
deviceId: zod.z.number(),
|
|
36714
|
-
zone: ZoneSchema
|
|
36715
|
-
}), zod.z.void(), {
|
|
36716
|
-
kind: "mutation",
|
|
36717
|
-
auth: "admin"
|
|
36718
|
-
})
|
|
36719
|
-
},
|
|
36720
|
-
/**
|
|
36721
|
-
* Runtime-state slice — the live zone catalogue mirrored by the
|
|
36722
|
-
* orchestrator on every CRUD mutation. Consumers read via
|
|
36723
|
-
* `device.state.zones.value` / `.watch(...)` without round-tripping
|
|
36724
|
-
* the cap, and the codegen DeviceProxy auto-wires the reactive
|
|
36725
|
-
* handle. Slice shape is `{ zones: Zone[] }` so future extensions
|
|
36726
|
-
* (e.g. zone groupings) can sit alongside the polygon list.
|
|
36727
|
-
*/
|
|
36728
|
-
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() }),
|
|
36729
|
-
/**
|
|
36730
|
-
* Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
|
|
36731
|
-
*
|
|
36732
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
36733
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
36734
|
-
*/
|
|
36735
|
-
durability: "restored"
|
|
36736
|
-
};
|
|
36737
36919
|
var NativeCropBboxSchema = zod.z.object({
|
|
36738
36920
|
x: zod.z.number(),
|
|
36739
36921
|
y: zod.z.number(),
|
|
@@ -45526,6 +45708,23 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
45526
45708
|
/** Media ms the returned fragment covers. */
|
|
45527
45709
|
gopDurMs: zod.z.number()
|
|
45528
45710
|
});
|
|
45711
|
+
var ReadWindowBytesResultSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
|
|
45712
|
+
kind: zod.z.literal("ok"),
|
|
45713
|
+
data: zod.z.instanceof(Uint8Array),
|
|
45714
|
+
/** Absolute epoch ms of the returned bytes' first sample — at or before
|
|
45715
|
+
* the requested `fromMs` (anchored on the nearest keyframe). */
|
|
45716
|
+
gopStartMs: zod.z.number(),
|
|
45717
|
+
/** Media ms the returned bytes cover, from `gopStartMs`. */
|
|
45718
|
+
gopDurMs: zod.z.number(),
|
|
45719
|
+
/** `false` ⇒ the safety byte cap cut the read short before it reached
|
|
45720
|
+
* the requested `toMs`; the caller got fewer frames than asked for. */
|
|
45721
|
+
reachesRequestedEnd: zod.z.boolean()
|
|
45722
|
+
}), zod.z.object({
|
|
45723
|
+
kind: zod.z.literal("spans-multiple-segments"),
|
|
45724
|
+
/** Where the covering segment's own footage runs out — informational,
|
|
45725
|
+
* not a retry hint (retrying the same window would refuse again). */
|
|
45726
|
+
segmentEndMs: zod.z.number()
|
|
45727
|
+
})]);
|
|
45529
45728
|
var recordingCapability = {
|
|
45530
45729
|
name: "recording",
|
|
45531
45730
|
scope: "system",
|
|
@@ -45605,6 +45804,21 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
45605
45804
|
kind: "query",
|
|
45606
45805
|
auth: "admin"
|
|
45607
45806
|
}),
|
|
45807
|
+
/** Read a WINDOW `[fromMs, toMs)` of segment `startMs`, by mfra byte
|
|
45808
|
+
* range — the multi-GOP twin of `readGopBytes`. Refuses (does not
|
|
45809
|
+
* degrade) when the window runs past the covering segment. Used by the
|
|
45810
|
+
* replay clip's `recording` source to fetch several seconds of native
|
|
45811
|
+
* footage for its single ffmpeg decode pass. */
|
|
45812
|
+
readWindowBytes: method(zod.z.object({
|
|
45813
|
+
deviceId: zod.z.number(),
|
|
45814
|
+
profile: zod.z.string(),
|
|
45815
|
+
startMs: zod.z.number(),
|
|
45816
|
+
fromMs: zod.z.number(),
|
|
45817
|
+
toMs: zod.z.number()
|
|
45818
|
+
}), ReadWindowBytesResultSchema, {
|
|
45819
|
+
kind: "query",
|
|
45820
|
+
auth: "admin"
|
|
45821
|
+
}),
|
|
45608
45822
|
setDeviceConfig: method(zod.z.object({
|
|
45609
45823
|
deviceId: zod.z.number(),
|
|
45610
45824
|
config: RecordingConfigSchema
|
|
@@ -46167,59 +46381,6 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
46167
46381
|
*/
|
|
46168
46382
|
durability: "session"
|
|
46169
46383
|
};
|
|
46170
|
-
var ZoneRuleModeEnum = zod.z.enum(["include", "exclude"]);
|
|
46171
|
-
var ZoneRuleSchema = zod.z.object({
|
|
46172
|
-
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
46173
|
-
id: zod.z.string(),
|
|
46174
|
-
/** Optional human-readable label rendered in the rule editor. */
|
|
46175
|
-
name: zod.z.string().optional(),
|
|
46176
|
-
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
46177
|
-
* listed zones (OR-set: a detection in any one of them counts).
|
|
46178
|
-
* At least one zone id required — a rule with no targets is a
|
|
46179
|
-
* configuration mistake and the form validator rejects it. */
|
|
46180
|
-
zoneIds: zod.z.array(zod.z.string()).min(1).readonly(),
|
|
46181
|
-
mode: ZoneRuleModeEnum,
|
|
46182
|
-
/**
|
|
46183
|
-
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
46184
|
-
* applies to every class. Class strings match the `macroClass`
|
|
46185
|
-
* field on detections (e.g. `person`, `car`, `dog`).
|
|
46186
|
-
*/
|
|
46187
|
-
classFilter: zod.z.array(zod.z.string()).readonly().optional(),
|
|
46188
|
-
/**
|
|
46189
|
-
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
46190
|
-
* required to consider an entity "in the zone". Defaults to the
|
|
46191
|
-
* consumer's stage default when omitted. Kept for back-compat with
|
|
46192
|
-
* existing per-rule overrides; new operators pick the value via
|
|
46193
|
-
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
46194
|
-
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
46195
|
-
*/
|
|
46196
|
-
overlapThreshold: zod.z.number().min(0).max(1).optional(),
|
|
46197
|
-
/**
|
|
46198
|
-
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
46199
|
-
* of the detection's bbox that must lie inside the zone for the
|
|
46200
|
-
* rule to match. Documented default is 85%; the engine substitutes
|
|
46201
|
-
* that when the field is omitted (kept optional so existing rules
|
|
46202
|
-
* stored without it stay valid).
|
|
46203
|
-
*
|
|
46204
|
-
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
46205
|
-
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
46206
|
-
* field exposed in the UI. Internally both feed the same gate.
|
|
46207
|
-
*/
|
|
46208
|
-
bboxInclusionPct: zod.z.number().min(0).max(100).optional(),
|
|
46209
|
-
/**
|
|
46210
|
-
* When `true` and a detection has a segmentation mask, use the
|
|
46211
|
-
* mask for overlap instead of the bbox. Detection-stage only;
|
|
46212
|
-
* motion rules ignore this field.
|
|
46213
|
-
*/
|
|
46214
|
-
preferMask: zod.z.boolean().optional(),
|
|
46215
|
-
/**
|
|
46216
|
-
* Soft-toggle: `false` disables the rule without deleting it.
|
|
46217
|
-
* Defaults to `true` so operators creating a rule via the UI
|
|
46218
|
-
* see it active immediately.
|
|
46219
|
-
*/
|
|
46220
|
-
enabled: zod.z.boolean().default(true)
|
|
46221
|
-
});
|
|
46222
|
-
zod.z.array(ZoneRuleSchema).readonly();
|
|
46223
46384
|
var ScriptRunnerStatusSchema = zod.z.object({
|
|
46224
46385
|
/** Whether the script is currently executing. */
|
|
46225
46386
|
isRunning: zod.z.boolean(),
|
|
@@ -51166,6 +51327,12 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
51166
51327
|
addonId: null,
|
|
51167
51328
|
access: "view"
|
|
51168
51329
|
},
|
|
51330
|
+
"notificationRules.resolveArtifactUrl": {
|
|
51331
|
+
capName: "notification-rules",
|
|
51332
|
+
capScope: "system",
|
|
51333
|
+
addonId: null,
|
|
51334
|
+
access: "view"
|
|
51335
|
+
},
|
|
51169
51336
|
"notificationRules.setAlarmConfig": {
|
|
51170
51337
|
capName: "notification-rules",
|
|
51171
51338
|
capScope: "system",
|
|
@@ -51610,6 +51777,12 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
51610
51777
|
addonId: null,
|
|
51611
51778
|
access: "create"
|
|
51612
51779
|
},
|
|
51780
|
+
"pipelineAnalytics.runReplayFrameProcessor": {
|
|
51781
|
+
capName: "pipeline-analytics",
|
|
51782
|
+
capScope: "device",
|
|
51783
|
+
addonId: null,
|
|
51784
|
+
access: "create"
|
|
51785
|
+
},
|
|
51613
51786
|
"pipelineAnalytics.saveRetrainAnnotations": {
|
|
51614
51787
|
capName: "pipeline-analytics",
|
|
51615
51788
|
capScope: "device",
|
|
@@ -51742,6 +51915,12 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
51742
51915
|
addonId: null,
|
|
51743
51916
|
access: "view"
|
|
51744
51917
|
},
|
|
51918
|
+
"pipelineExecutor.getInferenceDeviceHealth": {
|
|
51919
|
+
capName: "pipeline-executor",
|
|
51920
|
+
capScope: "system",
|
|
51921
|
+
addonId: null,
|
|
51922
|
+
access: "view"
|
|
51923
|
+
},
|
|
51745
51924
|
"pipelineExecutor.getOrchestratorConfigSchema": {
|
|
51746
51925
|
capName: "pipeline-executor",
|
|
51747
51926
|
capScope: "system",
|
|
@@ -51814,6 +51993,12 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
51814
51993
|
addonId: null,
|
|
51815
51994
|
access: "view"
|
|
51816
51995
|
},
|
|
51996
|
+
"pipelineExecutor.rearmInferenceDevice": {
|
|
51997
|
+
capName: "pipeline-executor",
|
|
51998
|
+
capScope: "system",
|
|
51999
|
+
addonId: null,
|
|
52000
|
+
access: "create"
|
|
52001
|
+
},
|
|
51817
52002
|
"pipelineExecutor.runAudioTest": {
|
|
51818
52003
|
capName: "pipeline-executor",
|
|
51819
52004
|
capScope: "system",
|
|
@@ -52552,6 +52737,12 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
52552
52737
|
addonId: null,
|
|
52553
52738
|
access: "view"
|
|
52554
52739
|
},
|
|
52740
|
+
"recording.readWindowBytes": {
|
|
52741
|
+
capName: "recording",
|
|
52742
|
+
capScope: "system",
|
|
52743
|
+
addonId: null,
|
|
52744
|
+
access: "view"
|
|
52745
|
+
},
|
|
52555
52746
|
"recording.refreshStorageLocationsForMigration": {
|
|
52556
52747
|
capName: "recording",
|
|
52557
52748
|
capScope: "system",
|
|
@@ -55062,6 +55253,11 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
55062
55253
|
form: "single",
|
|
55063
55254
|
optional: false
|
|
55064
55255
|
}],
|
|
55256
|
+
"pipelineAnalytics.runReplayFrameProcessor": [{
|
|
55257
|
+
name: "deviceId",
|
|
55258
|
+
form: "single",
|
|
55259
|
+
optional: false
|
|
55260
|
+
}],
|
|
55065
55261
|
"pipelineAnalytics.saveRetrainAnnotations": [{
|
|
55066
55262
|
name: "deviceId",
|
|
55067
55263
|
form: "single",
|
|
@@ -55377,6 +55573,11 @@ var require_dist_D5Jhh8Vk = __commonJS({
|
|
|
55377
55573
|
form: "single",
|
|
55378
55574
|
optional: false
|
|
55379
55575
|
}],
|
|
55576
|
+
"recording.readWindowBytes": [{
|
|
55577
|
+
name: "deviceId",
|
|
55578
|
+
form: "single",
|
|
55579
|
+
optional: false
|
|
55580
|
+
}],
|
|
55380
55581
|
"recording.relocateFootage": [{
|
|
55381
55582
|
name: "deviceId",
|
|
55382
55583
|
form: "single",
|
|
@@ -57031,7 +57232,7 @@ var require_alerts_addon = __commonJS({
|
|
|
57031
57232
|
[Symbol.toStringTag]: { value: "Module" }
|
|
57032
57233
|
});
|
|
57033
57234
|
require_chunk_Cek0wNdY();
|
|
57034
|
-
var require_dist10 =
|
|
57235
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
57035
57236
|
function selectExpired(alerts, cutoffMs) {
|
|
57036
57237
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
57037
57238
|
}
|
|
@@ -57850,7 +58051,7 @@ var require_console_logging = __commonJS({
|
|
|
57850
58051
|
[Symbol.toStringTag]: { value: "Module" }
|
|
57851
58052
|
});
|
|
57852
58053
|
require_chunk_Cek0wNdY();
|
|
57853
|
-
var require_dist10 =
|
|
58054
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
57854
58055
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
57855
58056
|
var LEVEL_RANK = {
|
|
57856
58057
|
debug: 0,
|
|
@@ -57944,7 +58145,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
57944
58145
|
"use strict";
|
|
57945
58146
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
57946
58147
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
57947
|
-
var require_dist10 =
|
|
58148
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
57948
58149
|
var node_crypto = __require("crypto");
|
|
57949
58150
|
var node_fs_promises = __require("fs/promises");
|
|
57950
58151
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -58841,11 +59042,11 @@ var require_core_blocks = __commonJS({
|
|
|
58841
59042
|
}
|
|
58842
59043
|
});
|
|
58843
59044
|
|
|
58844
|
-
// ../system/dist/retired-settings-keys-
|
|
58845
|
-
var
|
|
58846
|
-
"../system/dist/retired-settings-keys-
|
|
59045
|
+
// ../system/dist/retired-settings-keys-ovd_DQzc.js
|
|
59046
|
+
var require_retired_settings_keys_ovd_DQzc = __commonJS({
|
|
59047
|
+
"../system/dist/retired-settings-keys-ovd_DQzc.js"(exports) {
|
|
58847
59048
|
"use strict";
|
|
58848
|
-
var require_dist10 =
|
|
59049
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
58849
59050
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
58850
59051
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
58851
59052
|
return raw === "" || raw === "hub";
|
|
@@ -60888,8 +61089,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
60888
61089
|
[Symbol.toStringTag]: { value: "Module" }
|
|
60889
61090
|
});
|
|
60890
61091
|
require_chunk_Cek0wNdY();
|
|
60891
|
-
var require_dist10 =
|
|
60892
|
-
var require_retired_settings_keys =
|
|
61092
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
61093
|
+
var require_retired_settings_keys = require_retired_settings_keys_ovd_DQzc();
|
|
60893
61094
|
var node_crypto = __require("crypto");
|
|
60894
61095
|
var _camstack_types_node = require_node();
|
|
60895
61096
|
var JOB_HISTORY = 20;
|
|
@@ -61908,6 +62109,10 @@ var require_device_manager_addon = __commonJS({
|
|
|
61908
62109
|
device
|
|
61909
62110
|
};
|
|
61910
62111
|
}
|
|
62112
|
+
function extractCallerAddonId(input) {
|
|
62113
|
+
const raw = Reflect.get(input, "callerAddonId");
|
|
62114
|
+
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
62115
|
+
}
|
|
61911
62116
|
async function listPersistedByAddon(pctx, input) {
|
|
61912
62117
|
const { addonId } = input;
|
|
61913
62118
|
return (await pctx.metaStore.rows.listByAddon(addonId)).map(({ meta: m }) => ({
|
|
@@ -61935,6 +62140,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
61935
62140
|
async function listAll(pctx, input) {
|
|
61936
62141
|
const ownerFilter = Reflect.get(input, "addonId");
|
|
61937
62142
|
if (ownerFilter !== void 0 && (typeof ownerFilter !== "string" || ownerFilter.length === 0)) throw new Error(`deviceManager.listAll: addonId must be a non-empty string or be omitted \u2014 got ${JSON.stringify(ownerFilter)}. An owner filter that is present but empty is never widened to every device. On an addon context the id is \`ctx.id\`; there is no \`ctx.addonId\`.`);
|
|
62143
|
+
const callerAddonId = pctx.metaStore.rows.censusArmed ? extractCallerAddonId(input) : void 0;
|
|
61938
62144
|
const { addonId } = input;
|
|
61939
62145
|
const slim = input.projection === "slim";
|
|
61940
62146
|
const camerasOnly = input.isCamera === true;
|
|
@@ -61944,7 +62150,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
61944
62150
|
const fleet = addonId ? await pctx.metaStore.rows.listByAddon(addonId) : await pctx.metaStore.rows.listFleet({
|
|
61945
62151
|
...input.deviceIds !== void 0 ? { deviceIds: input.deviceIds } : {},
|
|
61946
62152
|
slim
|
|
61947
|
-
});
|
|
62153
|
+
}, callerAddonId);
|
|
61948
62154
|
const rowById = /* @__PURE__ */ new Map();
|
|
61949
62155
|
for (const row of fleet) rowById.set(row.meta.id, row);
|
|
61950
62156
|
if (pctx.registry) {
|
|
@@ -62446,18 +62652,38 @@ var require_device_manager_addon = __commonJS({
|
|
|
62446
62652
|
manualIds
|
|
62447
62653
|
};
|
|
62448
62654
|
}
|
|
62655
|
+
function expandContainer(id, byId, byParent, visited, out) {
|
|
62656
|
+
if (visited.has(id)) return;
|
|
62657
|
+
const candidate = byId.get(id);
|
|
62658
|
+
if (!candidate) return;
|
|
62659
|
+
if (candidate.type !== require_dist10.DeviceType.Container) {
|
|
62660
|
+
out.add(id);
|
|
62661
|
+
return;
|
|
62662
|
+
}
|
|
62663
|
+
const nextVisited = new Set(visited);
|
|
62664
|
+
nextVisited.add(id);
|
|
62665
|
+
const children = byParent.get(id) ?? [];
|
|
62666
|
+
for (const child of children) expandContainer(child.id, byId, byParent, nextVisited, out);
|
|
62667
|
+
}
|
|
62449
62668
|
function resolveLinkedDeviceIds(params) {
|
|
62450
62669
|
const { selfId, selfLocation, config, candidates } = params;
|
|
62670
|
+
const byId = new Map(candidates.map((c) => [c.id, c]));
|
|
62671
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
62672
|
+
for (const c of candidates) {
|
|
62673
|
+
if (c.parentDeviceId === null) continue;
|
|
62674
|
+
const siblings = byParent.get(c.parentDeviceId);
|
|
62675
|
+
if (siblings) siblings.push(c);
|
|
62676
|
+
else byParent.set(c.parentDeviceId, [c]);
|
|
62677
|
+
}
|
|
62451
62678
|
const ids = /* @__PURE__ */ new Set();
|
|
62452
|
-
|
|
62679
|
+
const expand = (id) => expandContainer(id, byId, byParent, /* @__PURE__ */ new Set(), ids);
|
|
62680
|
+
for (const c of candidates) if (c.parentDeviceId === selfId) expand(c.id);
|
|
62453
62681
|
if (config.mode === "auto") {
|
|
62454
|
-
if (selfLocation !== null && selfLocation.length > 0) {
|
|
62455
|
-
|
|
62682
|
+
if (selfLocation !== null && selfLocation.length > 0) for (const c of candidates) {
|
|
62683
|
+
if (c.type === require_dist10.DeviceType.Container) continue;
|
|
62684
|
+
if (c.location === selfLocation) ids.add(c.id);
|
|
62456
62685
|
}
|
|
62457
|
-
} else
|
|
62458
|
-
const known = new Set(candidates.map((c) => c.id));
|
|
62459
|
-
for (const id of config.manualIds) if (known.has(id)) ids.add(id);
|
|
62460
|
-
}
|
|
62686
|
+
} else for (const id of config.manualIds) if (byId.has(id)) expand(id);
|
|
62461
62687
|
ids.delete(selfId);
|
|
62462
62688
|
return [...ids];
|
|
62463
62689
|
}
|
|
@@ -62524,7 +62750,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
62524
62750
|
if (!persisted || persisted.meta.type !== require_dist10.DeviceType.Camera) return null;
|
|
62525
62751
|
const [all, blob] = await Promise.all([listAll(pctx, LINK_CANDIDATE_PROJECTION), pctx.settings.readDeviceStore(deviceId)]);
|
|
62526
62752
|
const config = parseLinkedDevicesConfig(blob);
|
|
62527
|
-
const options = all.filter((d) => d.id !== deviceId).map((d) => ({
|
|
62753
|
+
const options = all.filter((d) => d.id !== deviceId && d.type !== require_dist10.DeviceType.Container).map((d) => ({
|
|
62528
62754
|
value: String(d.id),
|
|
62529
62755
|
label: d.location !== null ? `${d.name} (${d.location})` : d.name
|
|
62530
62756
|
}));
|
|
@@ -63528,11 +63754,42 @@ var require_device_manager_addon = __commonJS({
|
|
|
63528
63754
|
}
|
|
63529
63755
|
});
|
|
63530
63756
|
}
|
|
63757
|
+
async function collectDescendants(metaStore, rootId) {
|
|
63758
|
+
const out = [];
|
|
63759
|
+
const visited = /* @__PURE__ */ new Set([rootId]);
|
|
63760
|
+
const queue = [rootId];
|
|
63761
|
+
while (queue.length > 0) {
|
|
63762
|
+
const parentId = queue.shift();
|
|
63763
|
+
if (parentId === void 0) break;
|
|
63764
|
+
for (const row of await metaStore.rows.listByParent(parentId)) {
|
|
63765
|
+
if (visited.has(row.meta.id)) continue;
|
|
63766
|
+
visited.add(row.meta.id);
|
|
63767
|
+
out.push(row.meta);
|
|
63768
|
+
queue.push(row.meta.id);
|
|
63769
|
+
}
|
|
63770
|
+
}
|
|
63771
|
+
return out;
|
|
63772
|
+
}
|
|
63531
63773
|
async function setLocation(pctx, input) {
|
|
63532
63774
|
const { deviceId, location } = input;
|
|
63775
|
+
const cascaded = [];
|
|
63776
|
+
const failed = [];
|
|
63533
63777
|
await pctx.metaStore.withMetaWriteLock(async () => {
|
|
63534
|
-
|
|
63778
|
+
const persisted = await pctx.metaStore.resolvePersistedById(deviceId);
|
|
63779
|
+
if (!persisted) throw new Error(`[device-manager] setLocation: unknown device id=${deviceId}`);
|
|
63535
63780
|
await pctx.metaStore.rows.patch(deviceId, { location });
|
|
63781
|
+
if (persisted.meta.type === require_dist10.DeviceType.Container) {
|
|
63782
|
+
const descendants = await collectDescendants(pctx.metaStore, deviceId);
|
|
63783
|
+
for (const descendant of descendants) try {
|
|
63784
|
+
await pctx.metaStore.rows.patch(descendant.id, { location });
|
|
63785
|
+
cascaded.push(descendant.id);
|
|
63786
|
+
} catch (err) {
|
|
63787
|
+
failed.push({
|
|
63788
|
+
id: descendant.id,
|
|
63789
|
+
error: err
|
|
63790
|
+
});
|
|
63791
|
+
}
|
|
63792
|
+
}
|
|
63536
63793
|
});
|
|
63537
63794
|
pctx.host.ctx.eventBus.emit({
|
|
63538
63795
|
id: (0, node_crypto.randomUUID)(),
|
|
@@ -63548,6 +63805,36 @@ var require_device_manager_addon = __commonJS({
|
|
|
63548
63805
|
value: location
|
|
63549
63806
|
}
|
|
63550
63807
|
});
|
|
63808
|
+
for (const childId of cascaded) pctx.host.ctx.eventBus.emit({
|
|
63809
|
+
id: (0, node_crypto.randomUUID)(),
|
|
63810
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
63811
|
+
source: {
|
|
63812
|
+
type: "device",
|
|
63813
|
+
id: childId
|
|
63814
|
+
},
|
|
63815
|
+
category: require_dist10.EventCategory.DeviceMetaChanged,
|
|
63816
|
+
data: {
|
|
63817
|
+
deviceId: childId,
|
|
63818
|
+
field: "location",
|
|
63819
|
+
value: location
|
|
63820
|
+
}
|
|
63821
|
+
});
|
|
63822
|
+
if (cascaded.length > 0 || failed.length > 0) pctx.host.ctx.logger.info("setLocation: cascaded location to container descendants", {
|
|
63823
|
+
tags: { deviceId },
|
|
63824
|
+
meta: {
|
|
63825
|
+
location,
|
|
63826
|
+
updated: cascaded.length,
|
|
63827
|
+
failed: failed.length
|
|
63828
|
+
}
|
|
63829
|
+
});
|
|
63830
|
+
if (failed.length > 0) pctx.host.ctx.logger.error("setLocation: cascade partially failed \u2014 some descendants NOT aligned to the new location", {
|
|
63831
|
+
tags: { deviceId },
|
|
63832
|
+
meta: {
|
|
63833
|
+
location,
|
|
63834
|
+
failedIds: failed.map((f) => f.id),
|
|
63835
|
+
errors: failed.map((f) => f.error instanceof Error ? f.error.message : String(f.error))
|
|
63836
|
+
}
|
|
63837
|
+
});
|
|
63551
63838
|
}
|
|
63552
63839
|
async function setType(pctx, input) {
|
|
63553
63840
|
const { deviceId, type } = input;
|
|
@@ -64039,9 +64326,29 @@ var require_device_manager_addon = __commonJS({
|
|
|
64039
64326
|
* to it even if it lands after the close — otherwise the slow reads at the
|
|
64040
64327
|
* edge would be attributed to nobody, and the slow ones are the interesting
|
|
64041
64328
|
* ones.
|
|
64042
|
-
|
|
64043
|
-
|
|
64329
|
+
*
|
|
64330
|
+
* `callerAddonId`, when given, is formatted as the site VERBATIM instead of
|
|
64331
|
+
* walking the local stack. A call that arrived over the cap channel — a
|
|
64332
|
+
* forked addon's `ctx.api.deviceManager.listAll.query()`, routed through
|
|
64333
|
+
* `LocalChildRegistry` → `onUnownedCall` → `CapRouteResolver` — carries its
|
|
64334
|
+
* origin as DATA (the registered `childId` the parent captured off the UDS
|
|
64335
|
+
* connection), and no amount of stack depth would ever recover it: every
|
|
64336
|
+
* frame between the socket read and this call is the SAME generic
|
|
64337
|
+
* dispatcher code (`onUnownedCall`, `dispatch`, `invoke`) regardless of
|
|
64338
|
+
* which addon called — the 2026-08-25 boot census measured this directly,
|
|
64339
|
+
* five thousand calls landing on `listAll` with nothing nameable above it.
|
|
64340
|
+
*
|
|
64341
|
+
* `isOpen` is checked FIRST, before the id is even looked at — a caller
|
|
64342
|
+
* threading a (cheap, already-known) `callerAddonId` through on every
|
|
64343
|
+
* request, armed or not, must not pay for the template string when
|
|
64344
|
+
* disarmed. This is also why formatting lives HERE rather than at the call
|
|
64345
|
+
* site: `DeviceRowStore` passes the raw id through unconditionally, and
|
|
64346
|
+
* only this method — which already knows whether armed — decides whether
|
|
64347
|
+
* to spend anything on it.
|
|
64348
|
+
*/
|
|
64349
|
+
siteOf(callerAddonId, nowMs = Date.now()) {
|
|
64044
64350
|
if (!this.isOpen(nowMs)) return null;
|
|
64351
|
+
if (callerAddonId !== void 0) return `addon:${callerAddonId}`;
|
|
64045
64352
|
const holder = {};
|
|
64046
64353
|
Error.captureStackTrace(holder, this.siteOf);
|
|
64047
64354
|
return siteFromStack(holder.stack);
|
|
@@ -64329,6 +64636,16 @@ var require_device_manager_addon = __commonJS({
|
|
|
64329
64636
|
/** Call-site attribution for fleet reads. Armed only by
|
|
64330
64637
|
* `CAMSTACK_FLEET_READ_CENSUS_MS`; see `fleet-read-census.ts`. */
|
|
64331
64638
|
census;
|
|
64639
|
+
/**
|
|
64640
|
+
* Is the fleet-read census armed right now? Exposed so a caller ABOVE this
|
|
64641
|
+
* store (`device-queries.ts`) can skip extracting a caller identity off its
|
|
64642
|
+
* input entirely when nobody is measuring — "the boolean field read first"
|
|
64643
|
+
* pattern this repo already uses elsewhere to keep a diagnostic seam at
|
|
64644
|
+
* zero cost while disarmed.
|
|
64645
|
+
*/
|
|
64646
|
+
get censusArmed() {
|
|
64647
|
+
return this.census.armed;
|
|
64648
|
+
}
|
|
64332
64649
|
constructor(backend, logger, census) {
|
|
64333
64650
|
this.backend = backend;
|
|
64334
64651
|
this.logger = logger;
|
|
@@ -64377,15 +64694,23 @@ var require_device_manager_addon = __commonJS({
|
|
|
64377
64694
|
}
|
|
64378
64695
|
return decoded;
|
|
64379
64696
|
}
|
|
64380
|
-
/**
|
|
64381
|
-
|
|
64697
|
+
/**
|
|
64698
|
+
* Every device, ordered by numeric id.
|
|
64699
|
+
*
|
|
64700
|
+
* `callerAddonId`, when known, is the addon that ORIGINATED this call —
|
|
64701
|
+
* captured off the cap-channel envelope (`CapCallInput.callerAddonId`, set
|
|
64702
|
+
* by `LocalChildRegistry` from the registered `childId`), never guessed.
|
|
64703
|
+
* Passed straight to the census; a stack walk can never name it (see
|
|
64704
|
+
* `fleet-read-census.ts#siteOf`).
|
|
64705
|
+
*/
|
|
64706
|
+
async listAll(callerAddonId) {
|
|
64382
64707
|
return this.list({
|
|
64383
64708
|
orderBy: {
|
|
64384
64709
|
field: "deviceId",
|
|
64385
64710
|
direction: "asc"
|
|
64386
64711
|
},
|
|
64387
64712
|
limit: DEVICE_ROWS_FLEET_LIMIT
|
|
64388
|
-
});
|
|
64713
|
+
}, void 0, callerAddonId);
|
|
64389
64714
|
}
|
|
64390
64715
|
/**
|
|
64391
64716
|
* The fleet, read as narrowly as the question allows.
|
|
@@ -64402,8 +64727,10 @@ var require_device_manager_addon = __commonJS({
|
|
|
64402
64727
|
*
|
|
64403
64728
|
* `isCamera` is deliberately NOT one of them — see that constant's note and
|
|
64404
64729
|
* `device-row-store-filtered.spec.ts`.
|
|
64730
|
+
*
|
|
64731
|
+
* `callerAddonId` — see {@link listAll}'s doc; same meaning here.
|
|
64405
64732
|
*/
|
|
64406
|
-
async listFleet(opts) {
|
|
64733
|
+
async listFleet(opts, callerAddonId) {
|
|
64407
64734
|
if (opts.deviceIds !== void 0 && opts.deviceIds.length === 0) return [];
|
|
64408
64735
|
return this.list({
|
|
64409
64736
|
...opts.deviceIds !== void 0 ? { whereIn: { deviceId: [...new Set(opts.deviceIds)] } } : {},
|
|
@@ -64412,7 +64739,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
64412
64739
|
direction: "asc"
|
|
64413
64740
|
},
|
|
64414
64741
|
limit: DEVICE_ROWS_FLEET_LIMIT
|
|
64415
|
-
}, opts.slim === true ? DEVICE_ROWS_SLIM_COLUMNS : void 0);
|
|
64742
|
+
}, opts.slim === true ? DEVICE_ROWS_SLIM_COLUMNS : void 0, callerAddonId);
|
|
64416
64743
|
}
|
|
64417
64744
|
/**
|
|
64418
64745
|
* Many devices, by numeric id, in ONE query.
|
|
@@ -64503,8 +64830,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
64503
64830
|
await this.declare();
|
|
64504
64831
|
return this.backend.count({ collection: DEVICE_ROWS_COLLECTION });
|
|
64505
64832
|
}
|
|
64506
|
-
async list(filter, columns) {
|
|
64507
|
-
const site = this.census.siteOf();
|
|
64833
|
+
async list(filter, columns, callerAddonId) {
|
|
64834
|
+
const site = this.census.siteOf(callerAddonId);
|
|
64508
64835
|
await this.declare();
|
|
64509
64836
|
const records = await this.backend.query({
|
|
64510
64837
|
collection: DEVICE_ROWS_COLLECTION,
|
|
@@ -65432,7 +65759,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
65432
65759
|
[Symbol.toStringTag]: { value: "Module" }
|
|
65433
65760
|
});
|
|
65434
65761
|
require_chunk_Cek0wNdY();
|
|
65435
|
-
var require_dist10 =
|
|
65762
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
65436
65763
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
65437
65764
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
65438
65765
|
var HubForwarderDestination = class {
|
|
@@ -65569,7 +65896,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
65569
65896
|
"use strict";
|
|
65570
65897
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
65571
65898
|
require_chunk_Cek0wNdY();
|
|
65572
|
-
var require_dist10 =
|
|
65899
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
65573
65900
|
var NO_DEVICES = "liveness:no-devices";
|
|
65574
65901
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
65575
65902
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -65759,7 +66086,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
65759
66086
|
[Symbol.toStringTag]: { value: "Module" }
|
|
65760
66087
|
});
|
|
65761
66088
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
65762
|
-
var require_dist10 =
|
|
66089
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
65763
66090
|
var node_crypto = __require("crypto");
|
|
65764
66091
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
65765
66092
|
var crypto$1 = __require("crypto");
|
|
@@ -73443,7 +73770,7 @@ var require_loki_logging = __commonJS({
|
|
|
73443
73770
|
[Symbol.toStringTag]: { value: "Module" }
|
|
73444
73771
|
});
|
|
73445
73772
|
require_chunk_Cek0wNdY();
|
|
73446
|
-
var require_dist10 =
|
|
73773
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
73447
73774
|
function sanitizeLabelName(raw) {
|
|
73448
73775
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
73449
73776
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -74008,7 +74335,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
74008
74335
|
[Symbol.toStringTag]: { value: "Module" }
|
|
74009
74336
|
});
|
|
74010
74337
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
74011
|
-
var require_dist10 =
|
|
74338
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
74012
74339
|
var node_child_process = __require("child_process");
|
|
74013
74340
|
var node_util = __require("util");
|
|
74014
74341
|
var node_os = __require("os");
|
|
@@ -74950,7 +75277,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
74950
75277
|
[Symbol.toStringTag]: { value: "Module" }
|
|
74951
75278
|
});
|
|
74952
75279
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
74953
|
-
var require_dist10 =
|
|
75280
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
74954
75281
|
var node_crypto = __require("crypto");
|
|
74955
75282
|
var node_fs_promises = __require("fs/promises");
|
|
74956
75283
|
var node_path = __require("path");
|
|
@@ -76066,8 +76393,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
76066
76393
|
[Symbol.toStringTag]: { value: "Module" }
|
|
76067
76394
|
});
|
|
76068
76395
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
76069
|
-
var require_dist10 =
|
|
76070
|
-
var require_retired_settings_keys =
|
|
76396
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
76397
|
+
var require_retired_settings_keys = require_retired_settings_keys_ovd_DQzc();
|
|
76071
76398
|
var node_crypto = __require("crypto");
|
|
76072
76399
|
var node_fs = __require("fs");
|
|
76073
76400
|
var node_module = __require("module");
|
|
@@ -78261,7 +78588,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
78261
78588
|
[Symbol.toStringTag]: { value: "Module" }
|
|
78262
78589
|
});
|
|
78263
78590
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
78264
|
-
var require_dist10 =
|
|
78591
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
78265
78592
|
var node_crypto = __require("crypto");
|
|
78266
78593
|
var node_fs_promises = __require("fs/promises");
|
|
78267
78594
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -80140,7 +80467,7 @@ var require_system_config_addon = __commonJS({
|
|
|
80140
80467
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80141
80468
|
});
|
|
80142
80469
|
require_chunk_Cek0wNdY();
|
|
80143
|
-
var require_dist10 =
|
|
80470
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
80144
80471
|
var SECTION_TITLES = {
|
|
80145
80472
|
server: "Server",
|
|
80146
80473
|
auth: "Authentication"
|
|
@@ -98201,7 +98528,7 @@ var require_winston_logging = __commonJS({
|
|
|
98201
98528
|
[Symbol.toStringTag]: { value: "Module" }
|
|
98202
98529
|
});
|
|
98203
98530
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
98204
|
-
var require_dist10 =
|
|
98531
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
98205
98532
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
98206
98533
|
var node_path = __require("path");
|
|
98207
98534
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -100144,9 +100471,9 @@ var require_event_category_EY0GNjV9 = __commonJS({
|
|
|
100144
100471
|
}
|
|
100145
100472
|
});
|
|
100146
100473
|
|
|
100147
|
-
// ../types/dist/sleep-
|
|
100148
|
-
var
|
|
100149
|
-
"../types/dist/sleep-
|
|
100474
|
+
// ../types/dist/sleep-CSodb2vQ.js
|
|
100475
|
+
var require_sleep_CSodb2vQ = __commonJS({
|
|
100476
|
+
"../types/dist/sleep-CSodb2vQ.js"(exports) {
|
|
100150
100477
|
"use strict";
|
|
100151
100478
|
var require_event_category = require_event_category_EY0GNjV9();
|
|
100152
100479
|
var zod = require_zod();
|
|
@@ -102674,6 +103001,7 @@ var require_sleep_DnbNfEhn = __commonJS({
|
|
|
102674
103001
|
testRule: (input) => dispatch("notification-rules", "notificationRules", "testRule", "mutation", input),
|
|
102675
103002
|
getConditionCatalog: (input) => dispatch("notification-rules", "notificationRules", "getConditionCatalog", "query", input),
|
|
102676
103003
|
getHistory: (input) => dispatch("notification-rules", "notificationRules", "getHistory", "query", input),
|
|
103004
|
+
resolveArtifactUrl: (input) => dispatch("notification-rules", "notificationRules", "resolveArtifactUrl", "query", input),
|
|
102677
103005
|
listSnoozes: (input) => dispatch("notification-rules", "notificationRules", "listSnoozes", "query", input),
|
|
102678
103006
|
createSnooze: (input) => dispatch("notification-rules", "notificationRules", "createSnooze", "mutation", input),
|
|
102679
103007
|
cancelSnooze: (input) => dispatch("notification-rules", "notificationRules", "cancelSnooze", "mutation", input),
|
|
@@ -102746,6 +103074,7 @@ var require_sleep_DnbNfEhn = __commonJS({
|
|
|
102746
103074
|
deselectRetrainFrame: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deselectRetrainFrame", "mutation", input),
|
|
102747
103075
|
getRetrainFrameImage: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getRetrainFrameImage", "query", input),
|
|
102748
103076
|
proposeRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "proposeRetrainAnnotations", "mutation", input),
|
|
103077
|
+
runReplayFrameProcessor: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "runReplayFrameProcessor", "mutation", input),
|
|
102749
103078
|
listRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRetrainAnnotations", "query", input),
|
|
102750
103079
|
saveRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "saveRetrainAnnotations", "mutation", input),
|
|
102751
103080
|
completeRetrainTrack: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "completeRetrainTrack", "mutation", input),
|
|
@@ -103016,6 +103345,7 @@ var require_sleep_DnbNfEhn = __commonJS({
|
|
|
103016
103345
|
locateSegment: (input) => dispatchSystem("recording", "locateSegment", "query", input),
|
|
103017
103346
|
readSegmentBytes: (input) => dispatchSystem("recording", "readSegmentBytes", "query", input),
|
|
103018
103347
|
readGopBytes: (input) => dispatchSystem("recording", "readGopBytes", "query", input),
|
|
103348
|
+
readWindowBytes: (input) => dispatchSystem("recording", "readWindowBytes", "query", input),
|
|
103019
103349
|
setDeviceConfig: (input) => dispatchSystem("recording", "setDeviceConfig", "mutation", input),
|
|
103020
103350
|
rescanStorage: (input) => dispatchSystem("recording", "rescanStorage", "mutation", input),
|
|
103021
103351
|
pruneFootage: (input) => dispatchSystem("recording", "pruneFootage", "mutation", input),
|
|
@@ -103697,7 +104027,7 @@ var require_addon = __commonJS({
|
|
|
103697
104027
|
"use strict";
|
|
103698
104028
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
103699
104029
|
var require_event_category = require_event_category_EY0GNjV9();
|
|
103700
|
-
var require_sleep =
|
|
104030
|
+
var require_sleep = require_sleep_CSodb2vQ();
|
|
103701
104031
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
103702
104032
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
103703
104033
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -110573,9 +110903,9 @@ var require_dist2 = __commonJS({
|
|
|
110573
110903
|
}
|
|
110574
110904
|
});
|
|
110575
110905
|
|
|
110576
|
-
// ../system/dist/manifest-python-deps-
|
|
110577
|
-
var
|
|
110578
|
-
"../system/dist/manifest-python-deps-
|
|
110906
|
+
// ../system/dist/manifest-python-deps-DBQarwp9.js
|
|
110907
|
+
var require_manifest_python_deps_DBQarwp9 = __commonJS({
|
|
110908
|
+
"../system/dist/manifest-python-deps-DBQarwp9.js"(exports) {
|
|
110579
110909
|
"use strict";
|
|
110580
110910
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
110581
110911
|
var node_crypto = __require("crypto");
|
|
@@ -114426,6 +114756,14 @@ var require_manifest_python_deps_Bu8H1_rg = __commonJS({
|
|
|
114426
114756
|
const raw = Reflect.get(args, "nodeId");
|
|
114427
114757
|
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
114428
114758
|
}
|
|
114759
|
+
function withCallerAddonId(args, callerAddonId) {
|
|
114760
|
+
if (callerAddonId === void 0) return args;
|
|
114761
|
+
if (args === null || typeof args !== "object" || Array.isArray(args)) return args;
|
|
114762
|
+
return {
|
|
114763
|
+
...args,
|
|
114764
|
+
callerAddonId
|
|
114765
|
+
};
|
|
114766
|
+
}
|
|
114429
114767
|
var CapRouteResolver = class {
|
|
114430
114768
|
hubNodeId;
|
|
114431
114769
|
broker;
|
|
@@ -114493,10 +114831,20 @@ var require_manifest_python_deps_Bu8H1_rg = __commonJS({
|
|
|
114493
114831
|
* `hub-local-uds` caller that already knows the addonId (`buildCapCallFn`)
|
|
114494
114832
|
* talks to `LocalChildRegistry.callCapOnChild` directly rather than through
|
|
114495
114833
|
* `dispatch`.
|
|
114496
|
-
|
|
114497
|
-
|
|
114834
|
+
* @param callerAddonId Optional out-of-band CALLER-identity hint — the
|
|
114835
|
+
* addon that ORIGINATED the call, distinct from `addonId` above (which
|
|
114836
|
+
* names the resolved PROVIDER, not the caller). Set by
|
|
114837
|
+
* `onUnownedCall` from `CapCallInput.callerAddonId`
|
|
114838
|
+
* (`LocalChildRegistry` stamped it off the registered `childId`). Only
|
|
114839
|
+
* the `hub-in-process` branch consumes it — merged into `args` so a
|
|
114840
|
+
* diagnostic tool deep in that provider (e.g. device-manager's
|
|
114841
|
+
* fleet-read census) can read it without every provider method changing
|
|
114842
|
+
* signature, the same "extra field the provider destructures or
|
|
114843
|
+
* ignores" convention `nodeId` already uses on this path.
|
|
114844
|
+
*/
|
|
114845
|
+
async dispatch(route, method, args, addonId, callerAddonId) {
|
|
114498
114846
|
try {
|
|
114499
|
-
return await this.dispatchInner(route, method, args, addonId);
|
|
114847
|
+
return await this.dispatchInner(route, method, args, addonId, callerAddonId);
|
|
114500
114848
|
} catch (err) {
|
|
114501
114849
|
if (err instanceof CapRouteError) throw err;
|
|
114502
114850
|
const nodeId = this.routeNodeId(route);
|
|
@@ -114515,10 +114863,10 @@ var require_manifest_python_deps_Bu8H1_rg = __commonJS({
|
|
|
114515
114863
|
* Inner dispatch: may throw CapRouteError (validation failures) or arbitrary
|
|
114516
114864
|
* transport errors. The outer `dispatch` wraps non-CapRouteErrors.
|
|
114517
114865
|
*/
|
|
114518
|
-
async dispatchInner(route, method, args, addonId) {
|
|
114866
|
+
async dispatchInner(route, method, args, addonId, callerAddonId) {
|
|
114519
114867
|
switch (route.kind) {
|
|
114520
114868
|
case "hub-in-process":
|
|
114521
|
-
return route.ref.invoke(method, args);
|
|
114869
|
+
return route.ref.invoke(method, withCallerAddonId(args, callerAddonId));
|
|
114522
114870
|
case "hub-local-uds": {
|
|
114523
114871
|
const registry = this.hubLocalRegistry;
|
|
114524
114872
|
if (registry === null) throw new CapRouteError(route.capName, method, {
|
|
@@ -115052,7 +115400,8 @@ var require_manifest_python_deps_Bu8H1_rg = __commonJS({
|
|
|
115052
115400
|
args: out.args,
|
|
115053
115401
|
...out.deviceId !== void 0 ? { deviceId: out.deviceId } : {},
|
|
115054
115402
|
...out.nodeId !== void 0 ? { nodeId: out.nodeId } : {},
|
|
115055
|
-
...out.native === true ? { native: true } : {}
|
|
115403
|
+
...out.native === true ? { native: true } : {},
|
|
115404
|
+
...childId !== null ? { callerAddonId: childId } : {}
|
|
115056
115405
|
};
|
|
115057
115406
|
const pinnedNodeId = out.nodeId ?? extractNodeId(out.args);
|
|
115058
115407
|
const pinTargetsThisNode = pinnedNodeId !== void 0 && this.ownNodeId !== void 0 && pinnedNodeId === this.ownNodeId;
|
|
@@ -115546,7 +115895,7 @@ var require_manifest_python_deps_Bu8H1_rg = __commonJS({
|
|
|
115546
115895
|
...nodeId !== void 0 ? { nodeId } : {},
|
|
115547
115896
|
...deviceId !== void 0 ? { deviceId } : {}
|
|
115548
115897
|
});
|
|
115549
|
-
return await resolver.dispatch(route, input.method, input.args);
|
|
115898
|
+
return input.callerAddonId !== void 0 ? await resolver.dispatch(route, input.method, input.args, void 0, input.callerAddonId) : await resolver.dispatch(route, input.method, input.args);
|
|
115550
115899
|
} catch (err) {
|
|
115551
115900
|
if (!(err instanceof CapRouteError) || err.reason !== "no-provider") throw err;
|
|
115552
115901
|
}
|
|
@@ -121417,7 +121766,7 @@ var require_dist3 = __commonJS({
|
|
|
121417
121766
|
"use strict";
|
|
121418
121767
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
121419
121768
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
121420
|
-
var require_dist10 =
|
|
121769
|
+
var require_dist10 = require_dist_jRSrzoXr();
|
|
121421
121770
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
121422
121771
|
require_alerts();
|
|
121423
121772
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -121443,7 +121792,7 @@ var require_dist3 = __commonJS({
|
|
|
121443
121792
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
121444
121793
|
var require_file_data_plane = require_file_data_plane_DO8KbxCe();
|
|
121445
121794
|
var require_tls$1 = require_tls_u8QCJCFE();
|
|
121446
|
-
var require_manifest_python_deps =
|
|
121795
|
+
var require_manifest_python_deps = require_manifest_python_deps_DBQarwp9();
|
|
121447
121796
|
var require_resource_monitor = require_resource_monitor_CdnzxBLP();
|
|
121448
121797
|
var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
|
|
121449
121798
|
var zod = require_zod();
|
|
@@ -202065,7 +202414,7 @@ var require_dist4 = __commonJS({
|
|
|
202065
202414
|
"use strict";
|
|
202066
202415
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
202067
202416
|
var require_event_category = require_event_category_EY0GNjV9();
|
|
202068
|
-
var require_sleep =
|
|
202417
|
+
var require_sleep = require_sleep_CSodb2vQ();
|
|
202069
202418
|
var require_canonical_hash = require_canonical_hash_DNV8S5ET();
|
|
202070
202419
|
var require_enums2 = require_enums();
|
|
202071
202420
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
@@ -213052,7 +213401,23 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
213052
213401
|
updatedAt: zod.z.number(),
|
|
213053
213402
|
/** Failure detail — present on a `dead` row. */
|
|
213054
213403
|
error: zod.z.string().optional(),
|
|
213055
|
-
subject: NcHistorySubjectSchema
|
|
213404
|
+
subject: NcHistorySubjectSchema,
|
|
213405
|
+
/**
|
|
213406
|
+
* Ids of the artefacts (still, then gif, then clip) this row's successful
|
|
213407
|
+
* delivery indexed in the artefact library — a REFERENCE, never the bytes
|
|
213408
|
+
* (an artefact is often megabytes; this row is durable JSON rewritten on
|
|
213409
|
+
* every delivery attempt). Absent on a row still pending/dead, a row
|
|
213410
|
+
* delivered before this field shipped, or a wiring with no artefact index.
|
|
213411
|
+
*
|
|
213412
|
+
* Resolve one to a fetchable URL with `resolveArtifactUrl` — an id
|
|
213413
|
+
* outlives any one URL's TTL, so a caller mints a fresh link on demand
|
|
213414
|
+
* rather than trusting one frozen at delivery time. `resolveArtifactUrl`
|
|
213415
|
+
* also answers `null` for an id whose artefact has since expired past the
|
|
213416
|
+
* retained shelf's own age bound — the degrade a caller (the Home
|
|
213417
|
+
* Assistant export) must render as "no image right now", never as a
|
|
213418
|
+
* broken link.
|
|
213419
|
+
*/
|
|
213420
|
+
artifactIds: zod.z.array(zod.z.string().min(1)).optional()
|
|
213056
213421
|
});
|
|
213057
213422
|
var NC_HISTORY_LIMIT_DEFAULT = 100;
|
|
213058
213423
|
var NC_HISTORY_LIMIT_MAX = 500;
|
|
@@ -213300,6 +213665,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
213300
213665
|
*/
|
|
213301
213666
|
getHistory: require_sleep.method(zod.z.object({ filter: NcHistoryFilterSchema.default({ limit: 100 }) }), zod.z.object({ entries: zod.z.array(NcHistoryEntrySchema) }), { auth: "admin" }),
|
|
213302
213667
|
/**
|
|
213668
|
+
* Mint a fresh, externally-reachable URL for one artefact a history row
|
|
213669
|
+
* named in {@link NcHistoryEntrySchema.shape.artifactIds} — the SAME
|
|
213670
|
+
* signed-link mechanism the dispatcher uses to attach media to an
|
|
213671
|
+
* outgoing notification (one derivation; this never re-implements it).
|
|
213672
|
+
*
|
|
213673
|
+
* `url: null` on THREE causes a caller must treat identically ("no image
|
|
213674
|
+
* right now", never a broken link): the id is unknown, its artefact has
|
|
213675
|
+
* expired past the retained shelf's own age bound, or this install has no
|
|
213676
|
+
* externally-reachable base URL. A caller that received a URL on a
|
|
213677
|
+
* previous call and now gets `null` must stop showing it — a link that
|
|
213678
|
+
* worked five minutes ago is not proof it works now.
|
|
213679
|
+
*/
|
|
213680
|
+
resolveArtifactUrl: require_sleep.method(zod.z.object({ artifactId: zod.z.string().min(1) }), zod.z.object({ url: zod.z.string().nullable() }), { auth: "admin" }),
|
|
213681
|
+
/**
|
|
213303
213682
|
* Snooze windows currently in effect, plus any whose digest has not yet
|
|
213304
213683
|
* gone out. `caller: 'required'`: a user sees their OWN windows and the
|
|
213305
213684
|
* global ones that silence them, never another person's private silence.
|
|
@@ -213539,6 +213918,726 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
213539
213918
|
getDescriptor: require_sleep.method(zod.z.void(), OauthIntegrationDescriptorSchema, { auth: "admin" })
|
|
213540
213919
|
}
|
|
213541
213920
|
};
|
|
213921
|
+
var NativeCropRefSchema = zod.z.object({
|
|
213922
|
+
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
213923
|
+
handle: require_sleep.FrameHandleSchema,
|
|
213924
|
+
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
213925
|
+
cropFrameSpace: zod.z.object({
|
|
213926
|
+
x: zod.z.number(),
|
|
213927
|
+
y: zod.z.number(),
|
|
213928
|
+
w: zod.z.number(),
|
|
213929
|
+
h: zod.z.number()
|
|
213930
|
+
})
|
|
213931
|
+
});
|
|
213932
|
+
zod.z.object({
|
|
213933
|
+
crop: zod.z.object({
|
|
213934
|
+
left: zod.z.number(),
|
|
213935
|
+
top: zod.z.number(),
|
|
213936
|
+
width: zod.z.number().positive(),
|
|
213937
|
+
height: zod.z.number().positive()
|
|
213938
|
+
}).optional(),
|
|
213939
|
+
content: zod.z.object({
|
|
213940
|
+
width: zod.z.number().int().positive(),
|
|
213941
|
+
height: zod.z.number().int().positive()
|
|
213942
|
+
}),
|
|
213943
|
+
fit: zod.z.enum(["stretch", "contain"]),
|
|
213944
|
+
format: zod.z.enum([
|
|
213945
|
+
"rgb",
|
|
213946
|
+
"gray",
|
|
213947
|
+
"jpeg"
|
|
213948
|
+
])
|
|
213949
|
+
});
|
|
213950
|
+
var FrameRefSchema = zod.z.object({
|
|
213951
|
+
registryId: zod.z.string().min(1),
|
|
213952
|
+
id: zod.z.string().min(1),
|
|
213953
|
+
width: zod.z.number().int().positive(),
|
|
213954
|
+
height: zod.z.number().int().positive(),
|
|
213955
|
+
format: zod.z.enum(["rgb", "gray"]),
|
|
213956
|
+
timestamp: zod.z.number(),
|
|
213957
|
+
capturedAt: zod.z.number().optional()
|
|
213958
|
+
});
|
|
213959
|
+
var ModelFormatSchema$1 = zod.z.enum([
|
|
213960
|
+
"onnx",
|
|
213961
|
+
"coreml",
|
|
213962
|
+
"openvino",
|
|
213963
|
+
"tflite",
|
|
213964
|
+
"pt",
|
|
213965
|
+
"gguf"
|
|
213966
|
+
]);
|
|
213967
|
+
var PipelineSlotSchema = zod.z.enum([
|
|
213968
|
+
"detector",
|
|
213969
|
+
"cropper",
|
|
213970
|
+
"classifier",
|
|
213971
|
+
"refiner",
|
|
213972
|
+
"audio-classifier"
|
|
213973
|
+
]);
|
|
213974
|
+
var PipelineEngineChoiceSchema = zod.z.object({
|
|
213975
|
+
runtime: zod.z.enum(["node", "python"]),
|
|
213976
|
+
backend: zod.z.string(),
|
|
213977
|
+
format: ModelFormatSchema$1,
|
|
213978
|
+
device: zod.z.string().optional()
|
|
213979
|
+
});
|
|
213980
|
+
var EngineDeviceInfoSchema = zod.z.object({
|
|
213981
|
+
id: zod.z.string(),
|
|
213982
|
+
label: zod.z.string(),
|
|
213983
|
+
description: zod.z.string().optional()
|
|
213984
|
+
});
|
|
213985
|
+
var AvailableEngineSchema = zod.z.object({
|
|
213986
|
+
engine: PipelineEngineChoiceSchema,
|
|
213987
|
+
devices: zod.z.array(EngineDeviceInfoSchema).readonly(),
|
|
213988
|
+
defaultDevice: zod.z.string()
|
|
213989
|
+
});
|
|
213990
|
+
var PipelineDefaultStepSchema = zod.z.lazy(() => zod.z.object({
|
|
213991
|
+
addonId: zod.z.string(),
|
|
213992
|
+
addonName: zod.z.string(),
|
|
213993
|
+
slot: PipelineSlotSchema,
|
|
213994
|
+
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
213995
|
+
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
213996
|
+
enabled: zod.z.boolean(),
|
|
213997
|
+
modelId: zod.z.string(),
|
|
213998
|
+
children: zod.z.array(PipelineDefaultStepSchema).readonly(),
|
|
213999
|
+
group: zod.z.string().optional(),
|
|
214000
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
214001
|
+
}));
|
|
214002
|
+
var PipelineTemplateStepSchema = zod.z.lazy(() => zod.z.object({
|
|
214003
|
+
addonId: zod.z.string(),
|
|
214004
|
+
enabled: zod.z.boolean(),
|
|
214005
|
+
modelId: zod.z.string(),
|
|
214006
|
+
children: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
214007
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
214008
|
+
}));
|
|
214009
|
+
var PipelineTemplateSchema$1 = zod.z.object({
|
|
214010
|
+
id: zod.z.string(),
|
|
214011
|
+
name: zod.z.string(),
|
|
214012
|
+
createdAt: zod.z.string(),
|
|
214013
|
+
updatedAt: zod.z.string(),
|
|
214014
|
+
engine: PipelineEngineChoiceSchema,
|
|
214015
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly()
|
|
214016
|
+
});
|
|
214017
|
+
var PipelineModelOptionSchema = zod.z.object({
|
|
214018
|
+
id: zod.z.string(),
|
|
214019
|
+
name: zod.z.string(),
|
|
214020
|
+
formats: zod.z.record(zod.z.string(), zod.z.object({
|
|
214021
|
+
downloaded: zod.z.boolean(),
|
|
214022
|
+
sizeMB: zod.z.number()
|
|
214023
|
+
})),
|
|
214024
|
+
group: ModelVariantGroupSchema.optional(),
|
|
214025
|
+
legacy: zod.z.boolean().optional(),
|
|
214026
|
+
provider: ModelProviderIdSchema.optional()
|
|
214027
|
+
});
|
|
214028
|
+
var ConfigFieldBridge = zod.z.custom();
|
|
214029
|
+
var PipelineAddonSchemaSchema = zod.z.object({
|
|
214030
|
+
id: zod.z.string(),
|
|
214031
|
+
name: zod.z.string(),
|
|
214032
|
+
slot: PipelineSlotSchema,
|
|
214033
|
+
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
214034
|
+
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
214035
|
+
childSlots: zod.z.array(PipelineSlotSchema).readonly(),
|
|
214036
|
+
models: zod.z.array(PipelineModelOptionSchema).readonly(),
|
|
214037
|
+
defaultModelId: zod.z.string(),
|
|
214038
|
+
defaultModelIdByFormat: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
214039
|
+
enabledByDefault: zod.z.boolean().optional(),
|
|
214040
|
+
backfillIntoExistingOverrides: zod.z.boolean().optional(),
|
|
214041
|
+
defaultConfidence: zod.z.number(),
|
|
214042
|
+
group: zod.z.string().optional(),
|
|
214043
|
+
configSchema: zod.z.array(ConfigFieldBridge).readonly().optional()
|
|
214044
|
+
});
|
|
214045
|
+
var PipelineSlotSchemaSchema = zod.z.object({
|
|
214046
|
+
id: PipelineSlotSchema,
|
|
214047
|
+
label: zod.z.string(),
|
|
214048
|
+
priority: zod.z.number(),
|
|
214049
|
+
parentSlot: PipelineSlotSchema.nullable(),
|
|
214050
|
+
addons: zod.z.array(PipelineAddonSchemaSchema).readonly()
|
|
214051
|
+
});
|
|
214052
|
+
var PipelineSchemaSchema = zod.z.object({
|
|
214053
|
+
availableEngines: zod.z.array(AvailableEngineSchema).readonly(),
|
|
214054
|
+
selectedEngine: PipelineEngineChoiceSchema,
|
|
214055
|
+
slots: zod.z.array(PipelineSlotSchemaSchema).readonly()
|
|
214056
|
+
});
|
|
214057
|
+
var EngineProvisioningSchema = zod.z.object({
|
|
214058
|
+
runtimeId: zod.z.enum([
|
|
214059
|
+
"onnx",
|
|
214060
|
+
"openvino",
|
|
214061
|
+
"coreml",
|
|
214062
|
+
"edgetpu"
|
|
214063
|
+
]).nullable(),
|
|
214064
|
+
device: zod.z.string().nullable(),
|
|
214065
|
+
state: zod.z.enum([
|
|
214066
|
+
"idle",
|
|
214067
|
+
"installing",
|
|
214068
|
+
"verifying",
|
|
214069
|
+
"ready",
|
|
214070
|
+
"failed"
|
|
214071
|
+
]),
|
|
214072
|
+
progress: zod.z.number().optional(),
|
|
214073
|
+
error: zod.z.string().optional(),
|
|
214074
|
+
nextRetryAt: zod.z.number().optional(),
|
|
214075
|
+
/**
|
|
214076
|
+
* Gate A (config-correctness gate at engine change): human-readable
|
|
214077
|
+
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
214078
|
+
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
214079
|
+
* has a <format> build"). Additive/optional: informational only, never
|
|
214080
|
+
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
214081
|
+
* Absent/empty when the node-default tree resolves cleanly.
|
|
214082
|
+
*/
|
|
214083
|
+
configIssues: zod.z.array(zod.z.string()).optional()
|
|
214084
|
+
});
|
|
214085
|
+
var PipelineStepInputSchema = zod.z.lazy(() => zod.z.object({
|
|
214086
|
+
addonId: zod.z.string(),
|
|
214087
|
+
modelId: zod.z.string().optional(),
|
|
214088
|
+
enabled: zod.z.boolean().default(true),
|
|
214089
|
+
children: zod.z.array(PipelineStepInputSchema).optional(),
|
|
214090
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
214091
|
+
jumpDeviceKey: zod.z.string().optional()
|
|
214092
|
+
}));
|
|
214093
|
+
var ModelSubstitutionSchema = zod.z.object({
|
|
214094
|
+
addonId: zod.z.string(),
|
|
214095
|
+
chosen: zod.z.string(),
|
|
214096
|
+
running: zod.z.string(),
|
|
214097
|
+
format: zod.z.string()
|
|
214098
|
+
});
|
|
214099
|
+
var PipelineValidationIssueSchema = zod.z.object({
|
|
214100
|
+
addonId: zod.z.string(),
|
|
214101
|
+
kind: zod.z.enum(["unknown-addon", "no-format-build"]),
|
|
214102
|
+
detail: zod.z.string()
|
|
214103
|
+
});
|
|
214104
|
+
var PipelineValidationResultSchema = zod.z.object({
|
|
214105
|
+
ok: zod.z.boolean(),
|
|
214106
|
+
issues: zod.z.array(PipelineValidationIssueSchema).readonly(),
|
|
214107
|
+
substitutions: zod.z.array(ModelSubstitutionSchema).readonly(),
|
|
214108
|
+
/** The node's `currentEngine.format` this validation ran against. */
|
|
214109
|
+
format: zod.z.string()
|
|
214110
|
+
});
|
|
214111
|
+
var ReferenceImageEntrySchema = zod.z.object({
|
|
214112
|
+
filename: zod.z.string(),
|
|
214113
|
+
stepIds: zod.z.array(zod.z.string()).readonly().optional()
|
|
214114
|
+
});
|
|
214115
|
+
var ReferenceImageBodySchema = zod.z.object({
|
|
214116
|
+
base64: zod.z.string(),
|
|
214117
|
+
filename: zod.z.string()
|
|
214118
|
+
});
|
|
214119
|
+
var ReferenceAudioEntrySchema = zod.z.object({
|
|
214120
|
+
filename: zod.z.string(),
|
|
214121
|
+
sizeKb: zod.z.number()
|
|
214122
|
+
});
|
|
214123
|
+
var ReferenceAudioBodySchema = zod.z.object({ base64: zod.z.string() });
|
|
214124
|
+
var AudioBackendSchema = zod.z.object({
|
|
214125
|
+
id: zod.z.string(),
|
|
214126
|
+
name: zod.z.string(),
|
|
214127
|
+
description: zod.z.string(),
|
|
214128
|
+
available: zod.z.boolean(),
|
|
214129
|
+
/**
|
|
214130
|
+
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
214131
|
+
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
214132
|
+
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
214133
|
+
* specific to the selected backend without a separate fetch.
|
|
214134
|
+
*/
|
|
214135
|
+
rawLabels: zod.z.array(zod.z.string()).readonly().optional()
|
|
214136
|
+
});
|
|
214137
|
+
var AudioCapabilitiesSchema = zod.z.object({
|
|
214138
|
+
activeBackend: zod.z.string(),
|
|
214139
|
+
availableBackends: zod.z.array(AudioBackendSchema).readonly(),
|
|
214140
|
+
sampleRate: zod.z.number(),
|
|
214141
|
+
chunkDurationMs: zod.z.number()
|
|
214142
|
+
});
|
|
214143
|
+
var DownloadModelResultSchema = zod.z.object({
|
|
214144
|
+
filePath: zod.z.string(),
|
|
214145
|
+
sizeMB: zod.z.number(),
|
|
214146
|
+
durationMs: zod.z.number()
|
|
214147
|
+
});
|
|
214148
|
+
var AudioTestResultSchema = zod.z.object({
|
|
214149
|
+
success: zod.z.boolean(),
|
|
214150
|
+
error: zod.z.string().optional(),
|
|
214151
|
+
frame: zod.z.custom().optional()
|
|
214152
|
+
});
|
|
214153
|
+
var PipelineConfigBridge = zod.z.custom();
|
|
214154
|
+
var ConfigUISchemaBridge = zod.z.custom();
|
|
214155
|
+
var ConfigUISchemaNullableBridge = zod.z.custom();
|
|
214156
|
+
var InferenceCapabilitiesBridge = zod.z.custom();
|
|
214157
|
+
var ModelAvailabilityListBridge = zod.z.custom();
|
|
214158
|
+
var PipelineRunResultBridge = zod.z.custom();
|
|
214159
|
+
var pipelineExecutorCapability = {
|
|
214160
|
+
name: "pipeline-executor",
|
|
214161
|
+
scope: "system",
|
|
214162
|
+
mode: "singleton",
|
|
214163
|
+
methods: {
|
|
214164
|
+
getAvailableEngines: require_sleep.method(zod.z.void(), zod.z.array(PipelineEngineChoiceSchema)),
|
|
214165
|
+
getSelectedEngine: require_sleep.method(zod.z.void(), PipelineEngineChoiceSchema),
|
|
214166
|
+
getDefaultSteps: require_sleep.method(PipelineEngineChoiceSchema, zod.z.array(PipelineDefaultStepSchema)),
|
|
214167
|
+
/**
|
|
214168
|
+
* Per-node detection-engine provisioning snapshot. Returns the live
|
|
214169
|
+
* state of the lazy runtime-provisioning machine on `nodeId`
|
|
214170
|
+
* (idle / installing / verifying / ready / failed). The UI pairs this
|
|
214171
|
+
* one-shot query with the `pipeline.engine-provisioning` live event
|
|
214172
|
+
* (emitted on every transition) to drive a per-node "engine ready?"
|
|
214173
|
+
* indicator without polling. Phase 2.
|
|
214174
|
+
*/
|
|
214175
|
+
getEngineProvisioning: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), EngineProvisioningSchema),
|
|
214176
|
+
getVideoPipelineSteps: require_sleep.method(zod.z.void(), zod.z.record(zod.z.string(), zod.z.object({
|
|
214177
|
+
modelId: zod.z.string(),
|
|
214178
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
214179
|
+
}))),
|
|
214180
|
+
setVideoPipelineSteps: require_sleep.method(zod.z.object({ steps: zod.z.record(zod.z.string(), zod.z.object({
|
|
214181
|
+
modelId: zod.z.string(),
|
|
214182
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
214183
|
+
})) }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
214184
|
+
kind: "mutation",
|
|
214185
|
+
auth: "admin"
|
|
214186
|
+
}),
|
|
214187
|
+
/**
|
|
214188
|
+
* Clear THIS node's executor-side PER-DEVICE settings stores (the
|
|
214189
|
+
* per-camera step overrides the object-detection root reads via
|
|
214190
|
+
* `applyDeviceOverridesToTree`). `nodeId` is the ROUTING key — the
|
|
214191
|
+
* generated cap-router strips it (default `nodeIdMode: 'routing'`) and
|
|
214192
|
+
* dispatches to that node, so the provider method runs ON the target
|
|
214193
|
+
* node and receives no `nodeId`.
|
|
214194
|
+
*
|
|
214195
|
+
* This is the slimmed executor leg of the orchestrator's
|
|
214196
|
+
* `resetNodePipelineDefaults` flow (which owns the real reset: node
|
|
214197
|
+
* addonDefaults pins + per-camera orchestrator overrides). The legacy
|
|
214198
|
+
* `resetToDefault` — which reset a persisted global step-tree seed
|
|
214199
|
+
* nothing in the live per-camera path read — was removed together with
|
|
214200
|
+
* that seed.
|
|
214201
|
+
*/
|
|
214202
|
+
clearDeviceOverrides: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({
|
|
214203
|
+
success: zod.z.literal(true),
|
|
214204
|
+
clearedDevices: zod.z.number()
|
|
214205
|
+
}), {
|
|
214206
|
+
kind: "mutation",
|
|
214207
|
+
auth: "admin"
|
|
214208
|
+
}),
|
|
214209
|
+
/**
|
|
214210
|
+
* Which of THIS node's inference devices the executor currently refuses,
|
|
214211
|
+
* and why. `nodeId` is the ROUTING key (stripped by the generated router).
|
|
214212
|
+
*
|
|
214213
|
+
* The channel that did not exist. Pool health was known only inside the
|
|
214214
|
+
* detection addon and was an input to no routing decision anywhere: the
|
|
214215
|
+
* per-dispatch capability gate is keyed on model FORMAT and so can never
|
|
214216
|
+
* separate `openvino:gpu` from `openvino:npu`, and the orchestrator's live
|
|
214217
|
+
* eligibility probe (`platformProbe.getCapabilities`) answers about
|
|
214218
|
+
* HARDWARE — which was present throughout. So when the hub's `openvino:gpu`
|
|
214219
|
+
* Python worker was SIGABRT'd by the Intel GPU plugin on 2026-08-25, the
|
|
214220
|
+
* balancer went on handing that dead pool cameras by rotation for 31 hours:
|
|
214221
|
+
* ~370 000 `PoolWorker[w0]: not initialized` lines, every frame lost.
|
|
214222
|
+
*
|
|
214223
|
+
* Read semantics the caller depends on, and which the provider guarantees:
|
|
214224
|
+
* this is a synchronous read of in-memory state. It never probes hardware,
|
|
214225
|
+
* never spawns a pool and never throws — an EMPTY `unhealthy` means "asked,
|
|
214226
|
+
* nothing is refused", which is what re-admits a device. A read that FAILS
|
|
214227
|
+
* (node offline, version skew) must therefore be distinguishable from an
|
|
214228
|
+
* empty answer, and it is: it rejects.
|
|
214229
|
+
*/
|
|
214230
|
+
getInferenceDeviceHealth: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({ unhealthy: zod.z.array(zod.z.object({
|
|
214231
|
+
/** `<backend>:<device>`, e.g. `openvino:gpu`. */
|
|
214232
|
+
deviceKey: zod.z.string(),
|
|
214233
|
+
/**
|
|
214234
|
+
* `failed` — the per-device restart budget is exhausted; no pool
|
|
214235
|
+
* will be spawned until an operator re-arms it or the runner
|
|
214236
|
+
* respawns. `backoff` — under budget, waiting out the backoff (or
|
|
214237
|
+
* a cached pool observed dead and not yet condemned).
|
|
214238
|
+
*/
|
|
214239
|
+
state: zod.z.enum(["failed", "backoff"]),
|
|
214240
|
+
/** Epoch ms of the death that produced this state. */
|
|
214241
|
+
since: zod.z.number(),
|
|
214242
|
+
/** Pool deaths inside the current window. */
|
|
214243
|
+
deaths: zod.z.number(),
|
|
214244
|
+
/** The last death's message. */
|
|
214245
|
+
lastError: zod.z.string()
|
|
214246
|
+
})).readonly() })),
|
|
214247
|
+
/**
|
|
214248
|
+
* Re-arm a terminally `failed` inference device on `nodeId`: forget its
|
|
214249
|
+
* restart budget so the next dispatch builds a fresh pool.
|
|
214250
|
+
*
|
|
214251
|
+
* The terminal state is deliberate (the abort it bounds is deterministic —
|
|
214252
|
+
* an automatic probation would just respawn Python forever, more slowly),
|
|
214253
|
+
* and a terminal state an operator cannot leave is a silent fault. This is
|
|
214254
|
+
* the way out. `rearmed:false` means there was nothing to forget.
|
|
214255
|
+
*/
|
|
214256
|
+
rearmInferenceDevice: require_sleep.method(zod.z.object({
|
|
214257
|
+
nodeId: zod.z.string(),
|
|
214258
|
+
deviceKey: zod.z.string()
|
|
214259
|
+
}), zod.z.object({ rearmed: zod.z.boolean() }), {
|
|
214260
|
+
kind: "mutation",
|
|
214261
|
+
auth: "admin"
|
|
214262
|
+
}),
|
|
214263
|
+
getSchema: require_sleep.method(zod.z.void(), PipelineSchemaSchema),
|
|
214264
|
+
getGlobalSteps: require_sleep.method(zod.z.void(), zod.z.array(PipelineDefaultStepSchema).readonly().nullable()),
|
|
214265
|
+
getGlobalPipelineConfig: require_sleep.method(zod.z.void(), PipelineConfigBridge),
|
|
214266
|
+
getOrchestratorConfigSchema: require_sleep.method(zod.z.void(), ConfigUISchemaBridge),
|
|
214267
|
+
/**
|
|
214268
|
+
* Gate B (pre-init config-correctness gate). PURE COMPUTE against this
|
|
214269
|
+
* node's `currentEngine.format` — resolves `steps` the same way the
|
|
214270
|
+
* runtime dispatch path would, and reports what WOULD happen without
|
|
214271
|
+
* touching any node-global state. Called by the orchestrator at attach
|
|
214272
|
+
* time (`attachOn`), node-pinned to the TARGET node, so config problems
|
|
214273
|
+
* surface BEFORE `pipelineRunner.attachCamera` rather than at the first
|
|
214274
|
+
* per-frame resolve. `ok` is false iff `issues` is non-empty (both
|
|
214275
|
+
* `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
|
|
214276
|
+
* is informational (a degraded-but-loadable model swap) and never
|
|
214277
|
+
* affects `ok`. Never throws.
|
|
214278
|
+
*/
|
|
214279
|
+
validatePipeline: require_sleep.method(zod.z.object({ steps: zod.z.array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
|
|
214280
|
+
listTemplates: require_sleep.method(zod.z.void(), zod.z.array(PipelineTemplateSchema$1).readonly()),
|
|
214281
|
+
saveTemplate: require_sleep.method(zod.z.object({
|
|
214282
|
+
name: zod.z.string(),
|
|
214283
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
214284
|
+
engine: PipelineEngineChoiceSchema
|
|
214285
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
214286
|
+
updateTemplate: require_sleep.method(zod.z.object({
|
|
214287
|
+
id: zod.z.string(),
|
|
214288
|
+
name: zod.z.string().optional(),
|
|
214289
|
+
steps: zod.z.array(PipelineTemplateStepSchema).readonly().optional()
|
|
214290
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
214291
|
+
deleteTemplate: require_sleep.method(zod.z.object({ id: zod.z.string() }), zod.z.void(), { kind: "mutation" }),
|
|
214292
|
+
getCapabilities: require_sleep.method(zod.z.void(), InferenceCapabilitiesBridge),
|
|
214293
|
+
getAddonModels: require_sleep.method(zod.z.object({ addonId: zod.z.string() }), ModelAvailabilityListBridge),
|
|
214294
|
+
downloadModel: require_sleep.method(zod.z.object({
|
|
214295
|
+
addonId: zod.z.string(),
|
|
214296
|
+
modelId: zod.z.string(),
|
|
214297
|
+
format: ModelFormatSchema$1
|
|
214298
|
+
}), DownloadModelResultSchema, { kind: "mutation" }),
|
|
214299
|
+
deleteModel: require_sleep.method(zod.z.object({
|
|
214300
|
+
addonId: zod.z.string(),
|
|
214301
|
+
modelId: zod.z.string(),
|
|
214302
|
+
format: ModelFormatSchema$1
|
|
214303
|
+
}), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }),
|
|
214304
|
+
/**
|
|
214305
|
+
* Stateless single-frame execution. Callers (runner, benchmark) pass
|
|
214306
|
+
* the complete `engine` + `steps` tree; the executor holds no state
|
|
214307
|
+
* about cameras or saved pipelines.
|
|
214308
|
+
*
|
|
214309
|
+
* `engine` is optional during the migration window to preserve the
|
|
214310
|
+
* legacy call shape used by existing benchmark code; once all
|
|
214311
|
+
* callers pass it explicitly we make it required.
|
|
214312
|
+
*
|
|
214313
|
+
* Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
|
|
214314
|
+
* `referenceImage` must be provided:
|
|
214315
|
+
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
214316
|
+
* Carries the raw buffer, dimensions, and format; the executor
|
|
214317
|
+
* uses it directly without base64 round-tripping.
|
|
214318
|
+
* - `frameHandle` (CB5): a zero-pixel shm `FrameHandle` for the SAME
|
|
214319
|
+
* decoded frame. Both runner and executor are hub-local processes
|
|
214320
|
+
* sharing `/dev/shm`, so the executor maps the named segment and
|
|
214321
|
+
* reads the pixels back zero-copy — eliminating the ~1.2MB
|
|
214322
|
+
* re-serialisation over UDS/MsgPack the `frame` path pays per call.
|
|
214323
|
+
* High-risk: the FrameRing is a latest-wins seqlock with no
|
|
214324
|
+
* refcount, so a recycled slot yields a null read; the executor
|
|
214325
|
+
* then degrades to an empty result and the runner ships pixels via
|
|
214326
|
+
* `frame` as the fallback (queue-depth gated on the runner side).
|
|
214327
|
+
* - `imageBase64`: one-shot test path (benchmark ImageTab).
|
|
214328
|
+
* - `referenceImage`: named file from the reference-image store.
|
|
214329
|
+
*/
|
|
214330
|
+
runPipeline: require_sleep.method(zod.z.object({
|
|
214331
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
214332
|
+
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
214333
|
+
frame: FrameInputSchema.optional(),
|
|
214334
|
+
/**
|
|
214335
|
+
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
214336
|
+
* in the same execution-group process; split/cross-node callers use
|
|
214337
|
+
* `frame`/`image` inline compatibility instead.
|
|
214338
|
+
*/
|
|
214339
|
+
frameRef: FrameRefSchema.optional(),
|
|
214340
|
+
/**
|
|
214341
|
+
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
214342
|
+
* the decoded pixels live in. One more member of the one-of
|
|
214343
|
+
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
214344
|
+
*/
|
|
214345
|
+
frameHandle: require_sleep.FrameHandleSchema.optional(),
|
|
214346
|
+
imageBase64: zod.z.string().optional(),
|
|
214347
|
+
/**
|
|
214348
|
+
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
214349
|
+
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
214350
|
+
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
214351
|
+
* the detection-pipeline worker. Callers can pass either; exactly
|
|
214352
|
+
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
214353
|
+
*/
|
|
214354
|
+
image: zod.z.instanceof(Uint8Array).optional(),
|
|
214355
|
+
referenceImage: zod.z.string().optional(),
|
|
214356
|
+
deviceId: zod.z.number().optional(),
|
|
214357
|
+
sessionId: zod.z.string().optional(),
|
|
214358
|
+
/**
|
|
214359
|
+
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
214360
|
+
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
214361
|
+
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
214362
|
+
* (inputClasses ≠ null) are skipped and served per-track via
|
|
214363
|
+
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
214364
|
+
*/
|
|
214365
|
+
plane: zod.z.enum(["full", "frame"]).optional(),
|
|
214366
|
+
/**
|
|
214367
|
+
* Inference-device selector (Phase 2 multi-device). Format
|
|
214368
|
+
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
214369
|
+
* Omitted ⇒ the runner's default device (current single-engine
|
|
214370
|
+
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
214371
|
+
*/
|
|
214372
|
+
deviceKey: zod.z.string().optional(),
|
|
214373
|
+
/**
|
|
214374
|
+
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
214375
|
+
* when the parent crop was resolved from the frame's retained NATIVE
|
|
214376
|
+
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
214377
|
+
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
214378
|
+
* resolution from that surface — the SAME quality path faces already
|
|
214379
|
+
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
214380
|
+
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
214381
|
+
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
214382
|
+
* the executor's crop-normalized child ROI back into frame-normalized
|
|
214383
|
+
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
214384
|
+
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
214385
|
+
* (today's behaviour on the fallback path).
|
|
214386
|
+
*/
|
|
214387
|
+
nativeCropRef: NativeCropRefSchema.optional()
|
|
214388
|
+
}), PipelineRunResultBridge, { kind: "mutation" }),
|
|
214389
|
+
/**
|
|
214390
|
+
* Batched run — N raw frames packed into one cap call. The provider
|
|
214391
|
+
* routes the batch through `SharedInferencePool.inferBatch`
|
|
214392
|
+
* (`MSG_INFER_BATCH = 0x03`) so the IPC framing and JSON response
|
|
214393
|
+
* envelope cost is amortised N:1 vs N concurrent `runPipeline`
|
|
214394
|
+
* calls. Single root step + uniform model assumed; trees with crop
|
|
214395
|
+
* children fall back to sequential execution.
|
|
214396
|
+
*
|
|
214397
|
+
* Used by `scripts/bench-batch-style.mts` for batch benchmarking —
|
|
214398
|
+
* N frames in one call to amortise per-call IPC overhead.
|
|
214399
|
+
*/
|
|
214400
|
+
runPipelineBatch: require_sleep.method(zod.z.object({
|
|
214401
|
+
engine: PipelineEngineChoiceSchema.optional(),
|
|
214402
|
+
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
214403
|
+
frames: zod.z.array(FrameInputSchema).min(1).max(255),
|
|
214404
|
+
deviceId: zod.z.number().optional(),
|
|
214405
|
+
sessionId: zod.z.string().optional(),
|
|
214406
|
+
/**
|
|
214407
|
+
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
214408
|
+
* the batch to the Python pool's bench preprocess cache
|
|
214409
|
+
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
214410
|
+
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
214411
|
+
* hit — the sustained-throughput run measures inference, not
|
|
214412
|
+
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
214413
|
+
* full preprocess every call, correct). Fresh per sustained run;
|
|
214414
|
+
* released via `uncacheFrame`.
|
|
214415
|
+
*/
|
|
214416
|
+
frameId: zod.z.number().int().nonnegative().optional(),
|
|
214417
|
+
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
214418
|
+
deviceKey: zod.z.string().optional()
|
|
214419
|
+
}), zod.z.object({ results: zod.z.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
|
|
214420
|
+
/**
|
|
214421
|
+
* Cache a raw frame inside the Python inference pool's memory.
|
|
214422
|
+
* Returns a numeric `frameId` that `inferCached` references —
|
|
214423
|
+
* subsequent calls send only 5 bytes through the pipe instead of
|
|
214424
|
+
* 1.2MB raw data, eliminating the pipe transfer bottleneck.
|
|
214425
|
+
*/
|
|
214426
|
+
cacheFrameInPool: require_sleep.method(zod.z.object({
|
|
214427
|
+
data: zod.z.instanceof(Uint8Array),
|
|
214428
|
+
width: zod.z.number().int().positive(),
|
|
214429
|
+
height: zod.z.number().int().positive(),
|
|
214430
|
+
format: zod.z.enum([
|
|
214431
|
+
"rgb",
|
|
214432
|
+
"bgr",
|
|
214433
|
+
"gray"
|
|
214434
|
+
])
|
|
214435
|
+
}), zod.z.object({
|
|
214436
|
+
frameId: zod.z.number(),
|
|
214437
|
+
width: zod.z.number(),
|
|
214438
|
+
height: zod.z.number()
|
|
214439
|
+
}), { kind: "mutation" }),
|
|
214440
|
+
/**
|
|
214441
|
+
* Run inference on a previously cached frame. Sends only 5 bytes
|
|
214442
|
+
* (model_idx + frameId) through the IPC pipe — eliminates the
|
|
214443
|
+
* ~35ms per-call overhead of transferring 1.2MB raw data.
|
|
214444
|
+
*/
|
|
214445
|
+
inferCached: require_sleep.method(zod.z.object({
|
|
214446
|
+
stepId: zod.z.string(),
|
|
214447
|
+
frameId: zod.z.number().int()
|
|
214448
|
+
}), zod.z.record(zod.z.string(), zod.z.unknown()), { kind: "mutation" }),
|
|
214449
|
+
/**
|
|
214450
|
+
* Release a cached frame from the Python pool's memory.
|
|
214451
|
+
*/
|
|
214452
|
+
uncacheFrame: require_sleep.method(zod.z.object({ frameId: zod.z.number().int() }), zod.z.void(), { kind: "mutation" }),
|
|
214453
|
+
/** Returns the effective pool tuning (resolved from user overrides + backend defaults). */
|
|
214454
|
+
getEffectiveTuning: require_sleep.method(zod.z.void(), zod.z.object({
|
|
214455
|
+
batchMode: zod.z.string(),
|
|
214456
|
+
windowMs: zod.z.number(),
|
|
214457
|
+
maxBatchSize: zod.z.number(),
|
|
214458
|
+
concurrency: zod.z.number()
|
|
214459
|
+
})),
|
|
214460
|
+
/**
|
|
214461
|
+
* List every EngineFactory currently loaded in this executor's RAM,
|
|
214462
|
+
* with the models resident and a coarse "in use" marker derived from
|
|
214463
|
+
* ongoing inference activity. Used by the Pipeline page Engines tab.
|
|
214464
|
+
*/
|
|
214465
|
+
listLoadedEngines: require_sleep.method(zod.z.void(), zod.z.array(zod.z.object({
|
|
214466
|
+
engineKey: zod.z.string(),
|
|
214467
|
+
engine: PipelineEngineChoiceSchema,
|
|
214468
|
+
modelsLoaded: zod.z.array(zod.z.string()).readonly(),
|
|
214469
|
+
inUseByCameras: zod.z.array(zod.z.number()).readonly(),
|
|
214470
|
+
/**
|
|
214471
|
+
* Origin of this resident factory.
|
|
214472
|
+
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
214473
|
+
* - `warm-override` — benchmark/test override held in the warm
|
|
214474
|
+
* cache; auto-disposed after the idle TTL.
|
|
214475
|
+
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
214476
|
+
* multi-device, keyed by `deviceKey`) resolved
|
|
214477
|
+
* via `resolveDeviceFactory`. Runs alongside the
|
|
214478
|
+
* `runtime` engine on a DIFFERENT accelerator
|
|
214479
|
+
* (NPU / iGPU / Coral) — this is how the
|
|
214480
|
+
* Engines tab shows all pools running at once.
|
|
214481
|
+
*/
|
|
214482
|
+
kind: zod.z.enum([
|
|
214483
|
+
"runtime",
|
|
214484
|
+
"warm-override",
|
|
214485
|
+
"device-pool"
|
|
214486
|
+
]),
|
|
214487
|
+
/** Native pid of the underlying Python pool (null when no pool). */
|
|
214488
|
+
poolPid: zod.z.number().nullable(),
|
|
214489
|
+
/** ms since this factory was last used (null when not warm-tracked). */
|
|
214490
|
+
idleMs: zod.z.number().nullable(),
|
|
214491
|
+
/** Idle TTL after which `warm-override` factories self-evict (null when not applicable). */
|
|
214492
|
+
idleTtlMs: zod.z.number().nullable()
|
|
214493
|
+
})).readonly()),
|
|
214494
|
+
/** Warm up an engine without running a frame. No-op if already loaded. */
|
|
214495
|
+
spinEngine: require_sleep.method(zod.z.object({ engine: PipelineEngineChoiceSchema }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
214496
|
+
kind: "mutation",
|
|
214497
|
+
auth: "admin"
|
|
214498
|
+
}),
|
|
214499
|
+
/**
|
|
214500
|
+
* Unload an engine from RAM. `force:true` unloads even when cameras
|
|
214501
|
+
* are actively using it (they re-spin on next frame). Default is
|
|
214502
|
+
* gated — returns `{success:false, reason}` when in use.
|
|
214503
|
+
*/
|
|
214504
|
+
killEngine: require_sleep.method(zod.z.object({
|
|
214505
|
+
engine: PipelineEngineChoiceSchema,
|
|
214506
|
+
force: zod.z.boolean().optional()
|
|
214507
|
+
}), zod.z.object({
|
|
214508
|
+
success: zod.z.boolean(),
|
|
214509
|
+
reason: zod.z.string().optional()
|
|
214510
|
+
}), {
|
|
214511
|
+
kind: "mutation",
|
|
214512
|
+
auth: "admin"
|
|
214513
|
+
}),
|
|
214514
|
+
listReferenceImages: require_sleep.method(zod.z.void(), zod.z.array(ReferenceImageEntrySchema).readonly()),
|
|
214515
|
+
getReferenceImage: require_sleep.method(zod.z.object({ filename: zod.z.string() }), ReferenceImageBodySchema.nullable()),
|
|
214516
|
+
getReferenceAudioFiles: require_sleep.method(zod.z.void(), zod.z.array(ReferenceAudioEntrySchema).readonly()),
|
|
214517
|
+
getReferenceAudio: require_sleep.method(zod.z.object({ filename: zod.z.string() }), ReferenceAudioBodySchema.nullable()),
|
|
214518
|
+
getAudioCapabilities: require_sleep.method(zod.z.void(), AudioCapabilitiesSchema),
|
|
214519
|
+
runAudioTest: require_sleep.method(zod.z.object({
|
|
214520
|
+
addonId: zod.z.string(),
|
|
214521
|
+
modelId: zod.z.string(),
|
|
214522
|
+
filename: zod.z.string().optional(),
|
|
214523
|
+
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
214524
|
+
}), AudioTestResultSchema, { kind: "mutation" }),
|
|
214525
|
+
getDetectionConfigSchema: require_sleep.method(zod.z.void(), ConfigUISchemaNullableBridge)
|
|
214526
|
+
}
|
|
214527
|
+
};
|
|
214528
|
+
var ZoneRuleModeEnum = zod.z.enum(["include", "exclude"]);
|
|
214529
|
+
var ZoneRuleSchema = zod.z.object({
|
|
214530
|
+
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
214531
|
+
id: zod.z.string(),
|
|
214532
|
+
/** Optional human-readable label rendered in the rule editor. */
|
|
214533
|
+
name: zod.z.string().optional(),
|
|
214534
|
+
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
214535
|
+
* listed zones (OR-set: a detection in any one of them counts).
|
|
214536
|
+
* At least one zone id required — a rule with no targets is a
|
|
214537
|
+
* configuration mistake and the form validator rejects it. */
|
|
214538
|
+
zoneIds: zod.z.array(zod.z.string()).min(1).readonly(),
|
|
214539
|
+
mode: ZoneRuleModeEnum,
|
|
214540
|
+
/**
|
|
214541
|
+
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
214542
|
+
* applies to every class. Class strings match the `macroClass`
|
|
214543
|
+
* field on detections (e.g. `person`, `car`, `dog`).
|
|
214544
|
+
*/
|
|
214545
|
+
classFilter: zod.z.array(zod.z.string()).readonly().optional(),
|
|
214546
|
+
/**
|
|
214547
|
+
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
214548
|
+
* required to consider an entity "in the zone". Defaults to the
|
|
214549
|
+
* consumer's stage default when omitted. Kept for back-compat with
|
|
214550
|
+
* existing per-rule overrides; new operators pick the value via
|
|
214551
|
+
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
214552
|
+
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
214553
|
+
*/
|
|
214554
|
+
overlapThreshold: zod.z.number().min(0).max(1).optional(),
|
|
214555
|
+
/**
|
|
214556
|
+
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
214557
|
+
* of the detection's bbox that must lie inside the zone for the
|
|
214558
|
+
* rule to match. Documented default is 85%; the engine substitutes
|
|
214559
|
+
* that when the field is omitted (kept optional so existing rules
|
|
214560
|
+
* stored without it stay valid).
|
|
214561
|
+
*
|
|
214562
|
+
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
214563
|
+
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
214564
|
+
* field exposed in the UI. Internally both feed the same gate.
|
|
214565
|
+
*/
|
|
214566
|
+
bboxInclusionPct: zod.z.number().min(0).max(100).optional(),
|
|
214567
|
+
/**
|
|
214568
|
+
* When `true` and a detection has a segmentation mask, use the
|
|
214569
|
+
* mask for overlap instead of the bbox. Detection-stage only;
|
|
214570
|
+
* motion rules ignore this field.
|
|
214571
|
+
*/
|
|
214572
|
+
preferMask: zod.z.boolean().optional(),
|
|
214573
|
+
/**
|
|
214574
|
+
* Soft-toggle: `false` disables the rule without deleting it.
|
|
214575
|
+
* Defaults to `true` so operators creating a rule via the UI
|
|
214576
|
+
* see it active immediately.
|
|
214577
|
+
*/
|
|
214578
|
+
enabled: zod.z.boolean().default(true)
|
|
214579
|
+
});
|
|
214580
|
+
var ZoneRulesArraySchema = zod.z.array(ZoneRuleSchema).readonly();
|
|
214581
|
+
var ZoneKindEnum = zod.z.enum(["polygon", "tripwire"]);
|
|
214582
|
+
var PolygonPointSchema = zod.z.object({
|
|
214583
|
+
x: zod.z.number(),
|
|
214584
|
+
y: zod.z.number()
|
|
214585
|
+
});
|
|
214586
|
+
var ZoneSchema = zod.z.object({
|
|
214587
|
+
id: zod.z.string(),
|
|
214588
|
+
name: zod.z.string(),
|
|
214589
|
+
kind: ZoneKindEnum.default("polygon"),
|
|
214590
|
+
/** Polygon vertices, fraction of frame (0–1). */
|
|
214591
|
+
polygon: zod.z.array(PolygonPointSchema).readonly(),
|
|
214592
|
+
/** Visual color for UI rendering. */
|
|
214593
|
+
color: zod.z.string().default("#3b82f6")
|
|
214594
|
+
});
|
|
214595
|
+
var zonesCapability = {
|
|
214596
|
+
name: "zones",
|
|
214597
|
+
scope: "device",
|
|
214598
|
+
mode: "singleton",
|
|
214599
|
+
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
214600
|
+
methods: {
|
|
214601
|
+
listZones: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(ZoneSchema).readonly()),
|
|
214602
|
+
addZone: require_sleep.method(zod.z.object({
|
|
214603
|
+
deviceId: zod.z.number(),
|
|
214604
|
+
zone: ZoneSchema
|
|
214605
|
+
}), zod.z.void(), {
|
|
214606
|
+
kind: "mutation",
|
|
214607
|
+
auth: "admin"
|
|
214608
|
+
}),
|
|
214609
|
+
removeZone: require_sleep.method(zod.z.object({
|
|
214610
|
+
deviceId: zod.z.number(),
|
|
214611
|
+
zoneId: zod.z.string()
|
|
214612
|
+
}), zod.z.void(), {
|
|
214613
|
+
kind: "mutation",
|
|
214614
|
+
auth: "admin"
|
|
214615
|
+
}),
|
|
214616
|
+
updateZone: require_sleep.method(zod.z.object({
|
|
214617
|
+
deviceId: zod.z.number(),
|
|
214618
|
+
zone: ZoneSchema
|
|
214619
|
+
}), zod.z.void(), {
|
|
214620
|
+
kind: "mutation",
|
|
214621
|
+
auth: "admin"
|
|
214622
|
+
})
|
|
214623
|
+
},
|
|
214624
|
+
/**
|
|
214625
|
+
* Runtime-state slice — the live zone catalogue mirrored by the
|
|
214626
|
+
* orchestrator on every CRUD mutation. Consumers read via
|
|
214627
|
+
* `device.state.zones.value` / `.watch(...)` without round-tripping
|
|
214628
|
+
* the cap, and the codegen DeviceProxy auto-wires the reactive
|
|
214629
|
+
* handle. Slice shape is `{ zones: Zone[] }` so future extensions
|
|
214630
|
+
* (e.g. zone groupings) can sit alongside the polygon list.
|
|
214631
|
+
*/
|
|
214632
|
+
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() }),
|
|
214633
|
+
/**
|
|
214634
|
+
* Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
|
|
214635
|
+
*
|
|
214636
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
214637
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
214638
|
+
*/
|
|
214639
|
+
durability: "restored"
|
|
214640
|
+
};
|
|
213542
214641
|
var TrackStateSchema = zod.z.enum([
|
|
213543
214642
|
"new",
|
|
213544
214643
|
"entered",
|
|
@@ -214359,6 +215458,25 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
214359
215458
|
/** Present when the pass ended by throwing. */
|
|
214360
215459
|
error: zod.z.string().nullable()
|
|
214361
215460
|
});
|
|
215461
|
+
var ReplayFrameInputSchema = zod.z.object({
|
|
215462
|
+
timestamp: zod.z.number(),
|
|
215463
|
+
frame: PipelineRunResultBridge
|
|
215464
|
+
});
|
|
215465
|
+
var ReplayTrackSchema = zod.z.object({
|
|
215466
|
+
className: zod.z.string(),
|
|
215467
|
+
firstSeenMs: zod.z.number(),
|
|
215468
|
+
lastSeenMs: zod.z.number(),
|
|
215469
|
+
/** Bbox of the track's FIRST matched detection, pixel-space in the clip's
|
|
215470
|
+
* frame — a representative box for the diff's `(className, window, IoU)`
|
|
215471
|
+
* pairing (`replay-diff.ts`). A replay does not need the full per-frame
|
|
215472
|
+
* trajectory production's `Track.positions` keeps. */
|
|
215473
|
+
bbox: BoundingBoxSchema,
|
|
215474
|
+
/** How many of the input frames this track matched a real detection on
|
|
215475
|
+
* (never a coasted/extrapolated frame) — the replay's own signal for "how
|
|
215476
|
+
* solid is this track", cheaper than re-deriving it from a trajectory. */
|
|
215477
|
+
framesMatched: zod.z.number().int()
|
|
215478
|
+
});
|
|
215479
|
+
var RunReplayFrameProcessorResultSchema = zod.z.object({ tracks: zod.z.array(ReplayTrackSchema).readonly() });
|
|
214362
215480
|
var pipelineAnalyticsCapability = {
|
|
214363
215481
|
name: "pipeline-analytics",
|
|
214364
215482
|
scope: "device",
|
|
@@ -214849,6 +215967,32 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
214849
215967
|
kind: "mutation",
|
|
214850
215968
|
auth: "admin"
|
|
214851
215969
|
}),
|
|
215970
|
+
/**
|
|
215971
|
+
* The FrameProcessor pass of a replay run — see the `Replay` section
|
|
215972
|
+
* above this capability's definition for why this is not the
|
|
215973
|
+
* `processFrame` method this file's header says pipeline-analytics does
|
|
215974
|
+
* not have.
|
|
215975
|
+
*
|
|
215976
|
+
* Constructs a FRESH `FrameProcessor` for `(deviceId, source)`, feeds it
|
|
215977
|
+
* `frames` IN THE ORDER GIVEN (the caller is responsible for time
|
|
215978
|
+
* ordering — this method does not sort), and returns the tracks it
|
|
215979
|
+
* produced. Zero persistence: no `TrackStore`, no event bus, no media
|
|
215980
|
+
* capture. `zones` / `detectionRules` are the run's OWN zone set —
|
|
215981
|
+
* typically the camera's real zones plus an ephemeral overlay
|
|
215982
|
+
* (`addon-benchmark`'s `replay-plan.ts`), never read from or written to
|
|
215983
|
+
* the `zones` capability by this method itself.
|
|
215984
|
+
*/
|
|
215985
|
+
runReplayFrameProcessor: require_sleep.method(zod.z.object({
|
|
215986
|
+
deviceId: zod.z.number(),
|
|
215987
|
+
source: DetectionSourceSchema,
|
|
215988
|
+
zones: zod.z.array(ZoneSchema).readonly().optional(),
|
|
215989
|
+
detectionRules: zod.z.array(ZoneRuleSchema).readonly().optional(),
|
|
215990
|
+
zoneMembershipMinOverlap: zod.z.number().min(0).max(1).optional(),
|
|
215991
|
+
frames: zod.z.array(ReplayFrameInputSchema).min(1)
|
|
215992
|
+
}), RunReplayFrameProcessorResultSchema, {
|
|
215993
|
+
kind: "mutation",
|
|
215994
|
+
auth: "admin"
|
|
215995
|
+
}),
|
|
214852
215996
|
/** Every annotation on a track, oldest first. */
|
|
214853
215997
|
listRetrainAnnotations: require_sleep.method(zod.z.object({ trackId: zod.z.string() }), zod.z.array(RetrainAnnotationSchema).readonly(), {
|
|
214854
215998
|
kind: "query",
|
|
@@ -215015,559 +216159,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
215015
216159
|
}) }
|
|
215016
216160
|
}
|
|
215017
216161
|
};
|
|
215018
|
-
var NativeCropRefSchema = zod.z.object({
|
|
215019
|
-
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
215020
|
-
handle: require_sleep.FrameHandleSchema,
|
|
215021
|
-
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
215022
|
-
cropFrameSpace: zod.z.object({
|
|
215023
|
-
x: zod.z.number(),
|
|
215024
|
-
y: zod.z.number(),
|
|
215025
|
-
w: zod.z.number(),
|
|
215026
|
-
h: zod.z.number()
|
|
215027
|
-
})
|
|
215028
|
-
});
|
|
215029
|
-
zod.z.object({
|
|
215030
|
-
crop: zod.z.object({
|
|
215031
|
-
left: zod.z.number(),
|
|
215032
|
-
top: zod.z.number(),
|
|
215033
|
-
width: zod.z.number().positive(),
|
|
215034
|
-
height: zod.z.number().positive()
|
|
215035
|
-
}).optional(),
|
|
215036
|
-
content: zod.z.object({
|
|
215037
|
-
width: zod.z.number().int().positive(),
|
|
215038
|
-
height: zod.z.number().int().positive()
|
|
215039
|
-
}),
|
|
215040
|
-
fit: zod.z.enum(["stretch", "contain"]),
|
|
215041
|
-
format: zod.z.enum([
|
|
215042
|
-
"rgb",
|
|
215043
|
-
"gray",
|
|
215044
|
-
"jpeg"
|
|
215045
|
-
])
|
|
215046
|
-
});
|
|
215047
|
-
var FrameRefSchema = zod.z.object({
|
|
215048
|
-
registryId: zod.z.string().min(1),
|
|
215049
|
-
id: zod.z.string().min(1),
|
|
215050
|
-
width: zod.z.number().int().positive(),
|
|
215051
|
-
height: zod.z.number().int().positive(),
|
|
215052
|
-
format: zod.z.enum(["rgb", "gray"]),
|
|
215053
|
-
timestamp: zod.z.number(),
|
|
215054
|
-
capturedAt: zod.z.number().optional()
|
|
215055
|
-
});
|
|
215056
|
-
var ModelFormatSchema$1 = zod.z.enum([
|
|
215057
|
-
"onnx",
|
|
215058
|
-
"coreml",
|
|
215059
|
-
"openvino",
|
|
215060
|
-
"tflite",
|
|
215061
|
-
"pt",
|
|
215062
|
-
"gguf"
|
|
215063
|
-
]);
|
|
215064
|
-
var PipelineSlotSchema = zod.z.enum([
|
|
215065
|
-
"detector",
|
|
215066
|
-
"cropper",
|
|
215067
|
-
"classifier",
|
|
215068
|
-
"refiner",
|
|
215069
|
-
"audio-classifier"
|
|
215070
|
-
]);
|
|
215071
|
-
var PipelineEngineChoiceSchema = zod.z.object({
|
|
215072
|
-
runtime: zod.z.enum(["node", "python"]),
|
|
215073
|
-
backend: zod.z.string(),
|
|
215074
|
-
format: ModelFormatSchema$1,
|
|
215075
|
-
device: zod.z.string().optional()
|
|
215076
|
-
});
|
|
215077
|
-
var EngineDeviceInfoSchema = zod.z.object({
|
|
215078
|
-
id: zod.z.string(),
|
|
215079
|
-
label: zod.z.string(),
|
|
215080
|
-
description: zod.z.string().optional()
|
|
215081
|
-
});
|
|
215082
|
-
var AvailableEngineSchema = zod.z.object({
|
|
215083
|
-
engine: PipelineEngineChoiceSchema,
|
|
215084
|
-
devices: zod.z.array(EngineDeviceInfoSchema).readonly(),
|
|
215085
|
-
defaultDevice: zod.z.string()
|
|
215086
|
-
});
|
|
215087
|
-
var PipelineDefaultStepSchema = zod.z.lazy(() => zod.z.object({
|
|
215088
|
-
addonId: zod.z.string(),
|
|
215089
|
-
addonName: zod.z.string(),
|
|
215090
|
-
slot: PipelineSlotSchema,
|
|
215091
|
-
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
215092
|
-
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
215093
|
-
enabled: zod.z.boolean(),
|
|
215094
|
-
modelId: zod.z.string(),
|
|
215095
|
-
children: zod.z.array(PipelineDefaultStepSchema).readonly(),
|
|
215096
|
-
group: zod.z.string().optional(),
|
|
215097
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
215098
|
-
}));
|
|
215099
|
-
var PipelineTemplateStepSchema = zod.z.lazy(() => zod.z.object({
|
|
215100
|
-
addonId: zod.z.string(),
|
|
215101
|
-
enabled: zod.z.boolean(),
|
|
215102
|
-
modelId: zod.z.string(),
|
|
215103
|
-
children: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
215104
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
215105
|
-
}));
|
|
215106
|
-
var PipelineTemplateSchema$1 = zod.z.object({
|
|
215107
|
-
id: zod.z.string(),
|
|
215108
|
-
name: zod.z.string(),
|
|
215109
|
-
createdAt: zod.z.string(),
|
|
215110
|
-
updatedAt: zod.z.string(),
|
|
215111
|
-
engine: PipelineEngineChoiceSchema,
|
|
215112
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly()
|
|
215113
|
-
});
|
|
215114
|
-
var PipelineModelOptionSchema = zod.z.object({
|
|
215115
|
-
id: zod.z.string(),
|
|
215116
|
-
name: zod.z.string(),
|
|
215117
|
-
formats: zod.z.record(zod.z.string(), zod.z.object({
|
|
215118
|
-
downloaded: zod.z.boolean(),
|
|
215119
|
-
sizeMB: zod.z.number()
|
|
215120
|
-
})),
|
|
215121
|
-
group: ModelVariantGroupSchema.optional(),
|
|
215122
|
-
legacy: zod.z.boolean().optional(),
|
|
215123
|
-
provider: ModelProviderIdSchema.optional()
|
|
215124
|
-
});
|
|
215125
|
-
var ConfigFieldBridge = zod.z.custom();
|
|
215126
|
-
var PipelineAddonSchemaSchema = zod.z.object({
|
|
215127
|
-
id: zod.z.string(),
|
|
215128
|
-
name: zod.z.string(),
|
|
215129
|
-
slot: PipelineSlotSchema,
|
|
215130
|
-
inputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
215131
|
-
outputClasses: zod.z.array(zod.z.string()).readonly(),
|
|
215132
|
-
childSlots: zod.z.array(PipelineSlotSchema).readonly(),
|
|
215133
|
-
models: zod.z.array(PipelineModelOptionSchema).readonly(),
|
|
215134
|
-
defaultModelId: zod.z.string(),
|
|
215135
|
-
defaultModelIdByFormat: zod.z.record(zod.z.string(), zod.z.string()).optional(),
|
|
215136
|
-
enabledByDefault: zod.z.boolean().optional(),
|
|
215137
|
-
backfillIntoExistingOverrides: zod.z.boolean().optional(),
|
|
215138
|
-
defaultConfidence: zod.z.number(),
|
|
215139
|
-
group: zod.z.string().optional(),
|
|
215140
|
-
configSchema: zod.z.array(ConfigFieldBridge).readonly().optional()
|
|
215141
|
-
});
|
|
215142
|
-
var PipelineSlotSchemaSchema = zod.z.object({
|
|
215143
|
-
id: PipelineSlotSchema,
|
|
215144
|
-
label: zod.z.string(),
|
|
215145
|
-
priority: zod.z.number(),
|
|
215146
|
-
parentSlot: PipelineSlotSchema.nullable(),
|
|
215147
|
-
addons: zod.z.array(PipelineAddonSchemaSchema).readonly()
|
|
215148
|
-
});
|
|
215149
|
-
var PipelineSchemaSchema = zod.z.object({
|
|
215150
|
-
availableEngines: zod.z.array(AvailableEngineSchema).readonly(),
|
|
215151
|
-
selectedEngine: PipelineEngineChoiceSchema,
|
|
215152
|
-
slots: zod.z.array(PipelineSlotSchemaSchema).readonly()
|
|
215153
|
-
});
|
|
215154
|
-
var EngineProvisioningSchema = zod.z.object({
|
|
215155
|
-
runtimeId: zod.z.enum([
|
|
215156
|
-
"onnx",
|
|
215157
|
-
"openvino",
|
|
215158
|
-
"coreml",
|
|
215159
|
-
"edgetpu"
|
|
215160
|
-
]).nullable(),
|
|
215161
|
-
device: zod.z.string().nullable(),
|
|
215162
|
-
state: zod.z.enum([
|
|
215163
|
-
"idle",
|
|
215164
|
-
"installing",
|
|
215165
|
-
"verifying",
|
|
215166
|
-
"ready",
|
|
215167
|
-
"failed"
|
|
215168
|
-
]),
|
|
215169
|
-
progress: zod.z.number().optional(),
|
|
215170
|
-
error: zod.z.string().optional(),
|
|
215171
|
-
nextRetryAt: zod.z.number().optional(),
|
|
215172
|
-
/**
|
|
215173
|
-
* Gate A (config-correctness gate at engine change): human-readable
|
|
215174
|
-
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
215175
|
-
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
215176
|
-
* has a <format> build"). Additive/optional: informational only, never
|
|
215177
|
-
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
215178
|
-
* Absent/empty when the node-default tree resolves cleanly.
|
|
215179
|
-
*/
|
|
215180
|
-
configIssues: zod.z.array(zod.z.string()).optional()
|
|
215181
|
-
});
|
|
215182
|
-
var PipelineStepInputSchema = zod.z.lazy(() => zod.z.object({
|
|
215183
|
-
addonId: zod.z.string(),
|
|
215184
|
-
modelId: zod.z.string().optional(),
|
|
215185
|
-
enabled: zod.z.boolean().default(true),
|
|
215186
|
-
children: zod.z.array(PipelineStepInputSchema).optional(),
|
|
215187
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
|
|
215188
|
-
jumpDeviceKey: zod.z.string().optional()
|
|
215189
|
-
}));
|
|
215190
|
-
var ModelSubstitutionSchema = zod.z.object({
|
|
215191
|
-
addonId: zod.z.string(),
|
|
215192
|
-
chosen: zod.z.string(),
|
|
215193
|
-
running: zod.z.string(),
|
|
215194
|
-
format: zod.z.string()
|
|
215195
|
-
});
|
|
215196
|
-
var PipelineValidationIssueSchema = zod.z.object({
|
|
215197
|
-
addonId: zod.z.string(),
|
|
215198
|
-
kind: zod.z.enum(["unknown-addon", "no-format-build"]),
|
|
215199
|
-
detail: zod.z.string()
|
|
215200
|
-
});
|
|
215201
|
-
var PipelineValidationResultSchema = zod.z.object({
|
|
215202
|
-
ok: zod.z.boolean(),
|
|
215203
|
-
issues: zod.z.array(PipelineValidationIssueSchema).readonly(),
|
|
215204
|
-
substitutions: zod.z.array(ModelSubstitutionSchema).readonly(),
|
|
215205
|
-
/** The node's `currentEngine.format` this validation ran against. */
|
|
215206
|
-
format: zod.z.string()
|
|
215207
|
-
});
|
|
215208
|
-
var ReferenceImageEntrySchema = zod.z.object({
|
|
215209
|
-
filename: zod.z.string(),
|
|
215210
|
-
stepIds: zod.z.array(zod.z.string()).readonly().optional()
|
|
215211
|
-
});
|
|
215212
|
-
var ReferenceImageBodySchema = zod.z.object({
|
|
215213
|
-
base64: zod.z.string(),
|
|
215214
|
-
filename: zod.z.string()
|
|
215215
|
-
});
|
|
215216
|
-
var ReferenceAudioEntrySchema = zod.z.object({
|
|
215217
|
-
filename: zod.z.string(),
|
|
215218
|
-
sizeKb: zod.z.number()
|
|
215219
|
-
});
|
|
215220
|
-
var ReferenceAudioBodySchema = zod.z.object({ base64: zod.z.string() });
|
|
215221
|
-
var AudioBackendSchema = zod.z.object({
|
|
215222
|
-
id: zod.z.string(),
|
|
215223
|
-
name: zod.z.string(),
|
|
215224
|
-
description: zod.z.string(),
|
|
215225
|
-
available: zod.z.boolean(),
|
|
215226
|
-
/**
|
|
215227
|
-
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
215228
|
-
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
215229
|
-
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
215230
|
-
* specific to the selected backend without a separate fetch.
|
|
215231
|
-
*/
|
|
215232
|
-
rawLabels: zod.z.array(zod.z.string()).readonly().optional()
|
|
215233
|
-
});
|
|
215234
|
-
var AudioCapabilitiesSchema = zod.z.object({
|
|
215235
|
-
activeBackend: zod.z.string(),
|
|
215236
|
-
availableBackends: zod.z.array(AudioBackendSchema).readonly(),
|
|
215237
|
-
sampleRate: zod.z.number(),
|
|
215238
|
-
chunkDurationMs: zod.z.number()
|
|
215239
|
-
});
|
|
215240
|
-
var DownloadModelResultSchema = zod.z.object({
|
|
215241
|
-
filePath: zod.z.string(),
|
|
215242
|
-
sizeMB: zod.z.number(),
|
|
215243
|
-
durationMs: zod.z.number()
|
|
215244
|
-
});
|
|
215245
|
-
var AudioTestResultSchema = zod.z.object({
|
|
215246
|
-
success: zod.z.boolean(),
|
|
215247
|
-
error: zod.z.string().optional(),
|
|
215248
|
-
frame: zod.z.custom().optional()
|
|
215249
|
-
});
|
|
215250
|
-
var PipelineConfigBridge = zod.z.custom();
|
|
215251
|
-
var ConfigUISchemaBridge = zod.z.custom();
|
|
215252
|
-
var ConfigUISchemaNullableBridge = zod.z.custom();
|
|
215253
|
-
var InferenceCapabilitiesBridge = zod.z.custom();
|
|
215254
|
-
var ModelAvailabilityListBridge = zod.z.custom();
|
|
215255
|
-
var PipelineRunResultBridge = zod.z.custom();
|
|
215256
|
-
var pipelineExecutorCapability = {
|
|
215257
|
-
name: "pipeline-executor",
|
|
215258
|
-
scope: "system",
|
|
215259
|
-
mode: "singleton",
|
|
215260
|
-
methods: {
|
|
215261
|
-
getAvailableEngines: require_sleep.method(zod.z.void(), zod.z.array(PipelineEngineChoiceSchema)),
|
|
215262
|
-
getSelectedEngine: require_sleep.method(zod.z.void(), PipelineEngineChoiceSchema),
|
|
215263
|
-
getDefaultSteps: require_sleep.method(PipelineEngineChoiceSchema, zod.z.array(PipelineDefaultStepSchema)),
|
|
215264
|
-
/**
|
|
215265
|
-
* Per-node detection-engine provisioning snapshot. Returns the live
|
|
215266
|
-
* state of the lazy runtime-provisioning machine on `nodeId`
|
|
215267
|
-
* (idle / installing / verifying / ready / failed). The UI pairs this
|
|
215268
|
-
* one-shot query with the `pipeline.engine-provisioning` live event
|
|
215269
|
-
* (emitted on every transition) to drive a per-node "engine ready?"
|
|
215270
|
-
* indicator without polling. Phase 2.
|
|
215271
|
-
*/
|
|
215272
|
-
getEngineProvisioning: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), EngineProvisioningSchema),
|
|
215273
|
-
getVideoPipelineSteps: require_sleep.method(zod.z.void(), zod.z.record(zod.z.string(), zod.z.object({
|
|
215274
|
-
modelId: zod.z.string(),
|
|
215275
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
215276
|
-
}))),
|
|
215277
|
-
setVideoPipelineSteps: require_sleep.method(zod.z.object({ steps: zod.z.record(zod.z.string(), zod.z.object({
|
|
215278
|
-
modelId: zod.z.string(),
|
|
215279
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).readonly()
|
|
215280
|
-
})) }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
215281
|
-
kind: "mutation",
|
|
215282
|
-
auth: "admin"
|
|
215283
|
-
}),
|
|
215284
|
-
/**
|
|
215285
|
-
* Clear THIS node's executor-side PER-DEVICE settings stores (the
|
|
215286
|
-
* per-camera step overrides the object-detection root reads via
|
|
215287
|
-
* `applyDeviceOverridesToTree`). `nodeId` is the ROUTING key — the
|
|
215288
|
-
* generated cap-router strips it (default `nodeIdMode: 'routing'`) and
|
|
215289
|
-
* dispatches to that node, so the provider method runs ON the target
|
|
215290
|
-
* node and receives no `nodeId`.
|
|
215291
|
-
*
|
|
215292
|
-
* This is the slimmed executor leg of the orchestrator's
|
|
215293
|
-
* `resetNodePipelineDefaults` flow (which owns the real reset: node
|
|
215294
|
-
* addonDefaults pins + per-camera orchestrator overrides). The legacy
|
|
215295
|
-
* `resetToDefault` — which reset a persisted global step-tree seed
|
|
215296
|
-
* nothing in the live per-camera path read — was removed together with
|
|
215297
|
-
* that seed.
|
|
215298
|
-
*/
|
|
215299
|
-
clearDeviceOverrides: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), zod.z.object({
|
|
215300
|
-
success: zod.z.literal(true),
|
|
215301
|
-
clearedDevices: zod.z.number()
|
|
215302
|
-
}), {
|
|
215303
|
-
kind: "mutation",
|
|
215304
|
-
auth: "admin"
|
|
215305
|
-
}),
|
|
215306
|
-
getSchema: require_sleep.method(zod.z.void(), PipelineSchemaSchema),
|
|
215307
|
-
getGlobalSteps: require_sleep.method(zod.z.void(), zod.z.array(PipelineDefaultStepSchema).readonly().nullable()),
|
|
215308
|
-
getGlobalPipelineConfig: require_sleep.method(zod.z.void(), PipelineConfigBridge),
|
|
215309
|
-
getOrchestratorConfigSchema: require_sleep.method(zod.z.void(), ConfigUISchemaBridge),
|
|
215310
|
-
/**
|
|
215311
|
-
* Gate B (pre-init config-correctness gate). PURE COMPUTE against this
|
|
215312
|
-
* node's `currentEngine.format` — resolves `steps` the same way the
|
|
215313
|
-
* runtime dispatch path would, and reports what WOULD happen without
|
|
215314
|
-
* touching any node-global state. Called by the orchestrator at attach
|
|
215315
|
-
* time (`attachOn`), node-pinned to the TARGET node, so config problems
|
|
215316
|
-
* surface BEFORE `pipelineRunner.attachCamera` rather than at the first
|
|
215317
|
-
* per-frame resolve. `ok` is false iff `issues` is non-empty (both
|
|
215318
|
-
* `unknown-addon` and `no-format-build` are HARD issues); `substitutions`
|
|
215319
|
-
* is informational (a degraded-but-loadable model swap) and never
|
|
215320
|
-
* affects `ok`. Never throws.
|
|
215321
|
-
*/
|
|
215322
|
-
validatePipeline: require_sleep.method(zod.z.object({ steps: zod.z.array(PipelineStepInputSchema) }), PipelineValidationResultSchema),
|
|
215323
|
-
listTemplates: require_sleep.method(zod.z.void(), zod.z.array(PipelineTemplateSchema$1).readonly()),
|
|
215324
|
-
saveTemplate: require_sleep.method(zod.z.object({
|
|
215325
|
-
name: zod.z.string(),
|
|
215326
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly(),
|
|
215327
|
-
engine: PipelineEngineChoiceSchema
|
|
215328
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
215329
|
-
updateTemplate: require_sleep.method(zod.z.object({
|
|
215330
|
-
id: zod.z.string(),
|
|
215331
|
-
name: zod.z.string().optional(),
|
|
215332
|
-
steps: zod.z.array(PipelineTemplateStepSchema).readonly().optional()
|
|
215333
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
215334
|
-
deleteTemplate: require_sleep.method(zod.z.object({ id: zod.z.string() }), zod.z.void(), { kind: "mutation" }),
|
|
215335
|
-
getCapabilities: require_sleep.method(zod.z.void(), InferenceCapabilitiesBridge),
|
|
215336
|
-
getAddonModels: require_sleep.method(zod.z.object({ addonId: zod.z.string() }), ModelAvailabilityListBridge),
|
|
215337
|
-
downloadModel: require_sleep.method(zod.z.object({
|
|
215338
|
-
addonId: zod.z.string(),
|
|
215339
|
-
modelId: zod.z.string(),
|
|
215340
|
-
format: ModelFormatSchema$1
|
|
215341
|
-
}), DownloadModelResultSchema, { kind: "mutation" }),
|
|
215342
|
-
deleteModel: require_sleep.method(zod.z.object({
|
|
215343
|
-
addonId: zod.z.string(),
|
|
215344
|
-
modelId: zod.z.string(),
|
|
215345
|
-
format: ModelFormatSchema$1
|
|
215346
|
-
}), zod.z.object({ success: zod.z.literal(true) }), { kind: "mutation" }),
|
|
215347
|
-
/**
|
|
215348
|
-
* Stateless single-frame execution. Callers (runner, benchmark) pass
|
|
215349
|
-
* the complete `engine` + `steps` tree; the executor holds no state
|
|
215350
|
-
* about cameras or saved pipelines.
|
|
215351
|
-
*
|
|
215352
|
-
* `engine` is optional during the migration window to preserve the
|
|
215353
|
-
* legacy call shape used by existing benchmark code; once all
|
|
215354
|
-
* callers pass it explicitly we make it required.
|
|
215355
|
-
*
|
|
215356
|
-
* Exactly one of `frame`, `frameRef`, `frameHandle`, `imageBase64`,
|
|
215357
|
-
* `referenceImage` must be provided:
|
|
215358
|
-
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
215359
|
-
* Carries the raw buffer, dimensions, and format; the executor
|
|
215360
|
-
* uses it directly without base64 round-tripping.
|
|
215361
|
-
* - `frameHandle` (CB5): a zero-pixel shm `FrameHandle` for the SAME
|
|
215362
|
-
* decoded frame. Both runner and executor are hub-local processes
|
|
215363
|
-
* sharing `/dev/shm`, so the executor maps the named segment and
|
|
215364
|
-
* reads the pixels back zero-copy — eliminating the ~1.2MB
|
|
215365
|
-
* re-serialisation over UDS/MsgPack the `frame` path pays per call.
|
|
215366
|
-
* High-risk: the FrameRing is a latest-wins seqlock with no
|
|
215367
|
-
* refcount, so a recycled slot yields a null read; the executor
|
|
215368
|
-
* then degrades to an empty result and the runner ships pixels via
|
|
215369
|
-
* `frame` as the fallback (queue-depth gated on the runner side).
|
|
215370
|
-
* - `imageBase64`: one-shot test path (benchmark ImageTab).
|
|
215371
|
-
* - `referenceImage`: named file from the reference-image store.
|
|
215372
|
-
*/
|
|
215373
|
-
runPipeline: require_sleep.method(zod.z.object({
|
|
215374
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
215375
|
-
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
215376
|
-
frame: FrameInputSchema.optional(),
|
|
215377
|
-
/**
|
|
215378
|
-
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
215379
|
-
* in the same execution-group process; split/cross-node callers use
|
|
215380
|
-
* `frame`/`image` inline compatibility instead.
|
|
215381
|
-
*/
|
|
215382
|
-
frameRef: FrameRefSchema.optional(),
|
|
215383
|
-
/**
|
|
215384
|
-
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
215385
|
-
* the decoded pixels live in. One more member of the one-of
|
|
215386
|
-
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
215387
|
-
*/
|
|
215388
|
-
frameHandle: require_sleep.FrameHandleSchema.optional(),
|
|
215389
|
-
imageBase64: zod.z.string().optional(),
|
|
215390
|
-
/**
|
|
215391
|
-
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
215392
|
-
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
215393
|
-
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
215394
|
-
* the detection-pipeline worker. Callers can pass either; exactly
|
|
215395
|
-
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
215396
|
-
*/
|
|
215397
|
-
image: zod.z.instanceof(Uint8Array).optional(),
|
|
215398
|
-
referenceImage: zod.z.string().optional(),
|
|
215399
|
-
deviceId: zod.z.number().optional(),
|
|
215400
|
-
sessionId: zod.z.string().optional(),
|
|
215401
|
-
/**
|
|
215402
|
-
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
215403
|
-
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
215404
|
-
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
215405
|
-
* (inputClasses ≠ null) are skipped and served per-track via
|
|
215406
|
-
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
215407
|
-
*/
|
|
215408
|
-
plane: zod.z.enum(["full", "frame"]).optional(),
|
|
215409
|
-
/**
|
|
215410
|
-
* Inference-device selector (Phase 2 multi-device). Format
|
|
215411
|
-
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
215412
|
-
* Omitted ⇒ the runner's default device (current single-engine
|
|
215413
|
-
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
215414
|
-
*/
|
|
215415
|
-
deviceKey: zod.z.string().optional(),
|
|
215416
|
-
/**
|
|
215417
|
-
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
215418
|
-
* when the parent crop was resolved from the frame's retained NATIVE
|
|
215419
|
-
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
215420
|
-
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
215421
|
-
* resolution from that surface — the SAME quality path faces already
|
|
215422
|
-
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
215423
|
-
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
215424
|
-
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
215425
|
-
* the executor's crop-normalized child ROI back into frame-normalized
|
|
215426
|
-
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
215427
|
-
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
215428
|
-
* (today's behaviour on the fallback path).
|
|
215429
|
-
*/
|
|
215430
|
-
nativeCropRef: NativeCropRefSchema.optional()
|
|
215431
|
-
}), PipelineRunResultBridge, { kind: "mutation" }),
|
|
215432
|
-
/**
|
|
215433
|
-
* Batched run — N raw frames packed into one cap call. The provider
|
|
215434
|
-
* routes the batch through `SharedInferencePool.inferBatch`
|
|
215435
|
-
* (`MSG_INFER_BATCH = 0x03`) so the IPC framing and JSON response
|
|
215436
|
-
* envelope cost is amortised N:1 vs N concurrent `runPipeline`
|
|
215437
|
-
* calls. Single root step + uniform model assumed; trees with crop
|
|
215438
|
-
* children fall back to sequential execution.
|
|
215439
|
-
*
|
|
215440
|
-
* Used by `scripts/bench-batch-style.mts` for batch benchmarking —
|
|
215441
|
-
* N frames in one call to amortise per-call IPC overhead.
|
|
215442
|
-
*/
|
|
215443
|
-
runPipelineBatch: require_sleep.method(zod.z.object({
|
|
215444
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
215445
|
-
steps: zod.z.array(PipelineStepInputSchema).min(1),
|
|
215446
|
-
frames: zod.z.array(FrameInputSchema).min(1).max(255),
|
|
215447
|
-
deviceId: zod.z.number().optional(),
|
|
215448
|
-
sessionId: zod.z.string().optional(),
|
|
215449
|
-
/**
|
|
215450
|
-
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
215451
|
-
* the batch to the Python pool's bench preprocess cache
|
|
215452
|
-
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
215453
|
-
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
215454
|
-
* hit — the sustained-throughput run measures inference, not
|
|
215455
|
-
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
215456
|
-
* full preprocess every call, correct). Fresh per sustained run;
|
|
215457
|
-
* released via `uncacheFrame`.
|
|
215458
|
-
*/
|
|
215459
|
-
frameId: zod.z.number().int().nonnegative().optional(),
|
|
215460
|
-
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
215461
|
-
deviceKey: zod.z.string().optional()
|
|
215462
|
-
}), zod.z.object({ results: zod.z.array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }),
|
|
215463
|
-
/**
|
|
215464
|
-
* Cache a raw frame inside the Python inference pool's memory.
|
|
215465
|
-
* Returns a numeric `frameId` that `inferCached` references —
|
|
215466
|
-
* subsequent calls send only 5 bytes through the pipe instead of
|
|
215467
|
-
* 1.2MB raw data, eliminating the pipe transfer bottleneck.
|
|
215468
|
-
*/
|
|
215469
|
-
cacheFrameInPool: require_sleep.method(zod.z.object({
|
|
215470
|
-
data: zod.z.instanceof(Uint8Array),
|
|
215471
|
-
width: zod.z.number().int().positive(),
|
|
215472
|
-
height: zod.z.number().int().positive(),
|
|
215473
|
-
format: zod.z.enum([
|
|
215474
|
-
"rgb",
|
|
215475
|
-
"bgr",
|
|
215476
|
-
"gray"
|
|
215477
|
-
])
|
|
215478
|
-
}), zod.z.object({
|
|
215479
|
-
frameId: zod.z.number(),
|
|
215480
|
-
width: zod.z.number(),
|
|
215481
|
-
height: zod.z.number()
|
|
215482
|
-
}), { kind: "mutation" }),
|
|
215483
|
-
/**
|
|
215484
|
-
* Run inference on a previously cached frame. Sends only 5 bytes
|
|
215485
|
-
* (model_idx + frameId) through the IPC pipe — eliminates the
|
|
215486
|
-
* ~35ms per-call overhead of transferring 1.2MB raw data.
|
|
215487
|
-
*/
|
|
215488
|
-
inferCached: require_sleep.method(zod.z.object({
|
|
215489
|
-
stepId: zod.z.string(),
|
|
215490
|
-
frameId: zod.z.number().int()
|
|
215491
|
-
}), zod.z.record(zod.z.string(), zod.z.unknown()), { kind: "mutation" }),
|
|
215492
|
-
/**
|
|
215493
|
-
* Release a cached frame from the Python pool's memory.
|
|
215494
|
-
*/
|
|
215495
|
-
uncacheFrame: require_sleep.method(zod.z.object({ frameId: zod.z.number().int() }), zod.z.void(), { kind: "mutation" }),
|
|
215496
|
-
/** Returns the effective pool tuning (resolved from user overrides + backend defaults). */
|
|
215497
|
-
getEffectiveTuning: require_sleep.method(zod.z.void(), zod.z.object({
|
|
215498
|
-
batchMode: zod.z.string(),
|
|
215499
|
-
windowMs: zod.z.number(),
|
|
215500
|
-
maxBatchSize: zod.z.number(),
|
|
215501
|
-
concurrency: zod.z.number()
|
|
215502
|
-
})),
|
|
215503
|
-
/**
|
|
215504
|
-
* List every EngineFactory currently loaded in this executor's RAM,
|
|
215505
|
-
* with the models resident and a coarse "in use" marker derived from
|
|
215506
|
-
* ongoing inference activity. Used by the Pipeline page Engines tab.
|
|
215507
|
-
*/
|
|
215508
|
-
listLoadedEngines: require_sleep.method(zod.z.void(), zod.z.array(zod.z.object({
|
|
215509
|
-
engineKey: zod.z.string(),
|
|
215510
|
-
engine: PipelineEngineChoiceSchema,
|
|
215511
|
-
modelsLoaded: zod.z.array(zod.z.string()).readonly(),
|
|
215512
|
-
inUseByCameras: zod.z.array(zod.z.number()).readonly(),
|
|
215513
|
-
/**
|
|
215514
|
-
* Origin of this resident factory.
|
|
215515
|
-
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
215516
|
-
* - `warm-override` — benchmark/test override held in the warm
|
|
215517
|
-
* cache; auto-disposed after the idle TTL.
|
|
215518
|
-
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
215519
|
-
* multi-device, keyed by `deviceKey`) resolved
|
|
215520
|
-
* via `resolveDeviceFactory`. Runs alongside the
|
|
215521
|
-
* `runtime` engine on a DIFFERENT accelerator
|
|
215522
|
-
* (NPU / iGPU / Coral) — this is how the
|
|
215523
|
-
* Engines tab shows all pools running at once.
|
|
215524
|
-
*/
|
|
215525
|
-
kind: zod.z.enum([
|
|
215526
|
-
"runtime",
|
|
215527
|
-
"warm-override",
|
|
215528
|
-
"device-pool"
|
|
215529
|
-
]),
|
|
215530
|
-
/** Native pid of the underlying Python pool (null when no pool). */
|
|
215531
|
-
poolPid: zod.z.number().nullable(),
|
|
215532
|
-
/** ms since this factory was last used (null when not warm-tracked). */
|
|
215533
|
-
idleMs: zod.z.number().nullable(),
|
|
215534
|
-
/** Idle TTL after which `warm-override` factories self-evict (null when not applicable). */
|
|
215535
|
-
idleTtlMs: zod.z.number().nullable()
|
|
215536
|
-
})).readonly()),
|
|
215537
|
-
/** Warm up an engine without running a frame. No-op if already loaded. */
|
|
215538
|
-
spinEngine: require_sleep.method(zod.z.object({ engine: PipelineEngineChoiceSchema }), zod.z.object({ success: zod.z.literal(true) }), {
|
|
215539
|
-
kind: "mutation",
|
|
215540
|
-
auth: "admin"
|
|
215541
|
-
}),
|
|
215542
|
-
/**
|
|
215543
|
-
* Unload an engine from RAM. `force:true` unloads even when cameras
|
|
215544
|
-
* are actively using it (they re-spin on next frame). Default is
|
|
215545
|
-
* gated — returns `{success:false, reason}` when in use.
|
|
215546
|
-
*/
|
|
215547
|
-
killEngine: require_sleep.method(zod.z.object({
|
|
215548
|
-
engine: PipelineEngineChoiceSchema,
|
|
215549
|
-
force: zod.z.boolean().optional()
|
|
215550
|
-
}), zod.z.object({
|
|
215551
|
-
success: zod.z.boolean(),
|
|
215552
|
-
reason: zod.z.string().optional()
|
|
215553
|
-
}), {
|
|
215554
|
-
kind: "mutation",
|
|
215555
|
-
auth: "admin"
|
|
215556
|
-
}),
|
|
215557
|
-
listReferenceImages: require_sleep.method(zod.z.void(), zod.z.array(ReferenceImageEntrySchema).readonly()),
|
|
215558
|
-
getReferenceImage: require_sleep.method(zod.z.object({ filename: zod.z.string() }), ReferenceImageBodySchema.nullable()),
|
|
215559
|
-
getReferenceAudioFiles: require_sleep.method(zod.z.void(), zod.z.array(ReferenceAudioEntrySchema).readonly()),
|
|
215560
|
-
getReferenceAudio: require_sleep.method(zod.z.object({ filename: zod.z.string() }), ReferenceAudioBodySchema.nullable()),
|
|
215561
|
-
getAudioCapabilities: require_sleep.method(zod.z.void(), AudioCapabilitiesSchema),
|
|
215562
|
-
runAudioTest: require_sleep.method(zod.z.object({
|
|
215563
|
-
addonId: zod.z.string(),
|
|
215564
|
-
modelId: zod.z.string(),
|
|
215565
|
-
filename: zod.z.string().optional(),
|
|
215566
|
-
settings: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
215567
|
-
}), AudioTestResultSchema, { kind: "mutation" }),
|
|
215568
|
-
getDetectionConfigSchema: require_sleep.method(zod.z.void(), ConfigUISchemaNullableBridge)
|
|
215569
|
-
}
|
|
215570
|
-
};
|
|
215571
216162
|
var OrchestratorMetricsSchema = zod.z.object({
|
|
215572
216163
|
activeCameras: zod.z.number(),
|
|
215573
216164
|
throttledCameras: zod.z.number(),
|
|
@@ -215592,66 +216183,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
215592
216183
|
])
|
|
215593
216184
|
});
|
|
215594
216185
|
var CameraMetricsWithDeviceIdSchema = CameraMetricsSchema.extend({ deviceId: zod.z.number() });
|
|
215595
|
-
var ZoneKindEnum = zod.z.enum(["polygon", "tripwire"]);
|
|
215596
|
-
var PolygonPointSchema = zod.z.object({
|
|
215597
|
-
x: zod.z.number(),
|
|
215598
|
-
y: zod.z.number()
|
|
215599
|
-
});
|
|
215600
|
-
var ZoneSchema = zod.z.object({
|
|
215601
|
-
id: zod.z.string(),
|
|
215602
|
-
name: zod.z.string(),
|
|
215603
|
-
kind: ZoneKindEnum.default("polygon"),
|
|
215604
|
-
/** Polygon vertices, fraction of frame (0–1). */
|
|
215605
|
-
polygon: zod.z.array(PolygonPointSchema).readonly(),
|
|
215606
|
-
/** Visual color for UI rendering. */
|
|
215607
|
-
color: zod.z.string().default("#3b82f6")
|
|
215608
|
-
});
|
|
215609
|
-
var zonesCapability = {
|
|
215610
|
-
name: "zones",
|
|
215611
|
-
scope: "device",
|
|
215612
|
-
mode: "singleton",
|
|
215613
|
-
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
215614
|
-
methods: {
|
|
215615
|
-
listZones: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.array(ZoneSchema).readonly()),
|
|
215616
|
-
addZone: require_sleep.method(zod.z.object({
|
|
215617
|
-
deviceId: zod.z.number(),
|
|
215618
|
-
zone: ZoneSchema
|
|
215619
|
-
}), zod.z.void(), {
|
|
215620
|
-
kind: "mutation",
|
|
215621
|
-
auth: "admin"
|
|
215622
|
-
}),
|
|
215623
|
-
removeZone: require_sleep.method(zod.z.object({
|
|
215624
|
-
deviceId: zod.z.number(),
|
|
215625
|
-
zoneId: zod.z.string()
|
|
215626
|
-
}), zod.z.void(), {
|
|
215627
|
-
kind: "mutation",
|
|
215628
|
-
auth: "admin"
|
|
215629
|
-
}),
|
|
215630
|
-
updateZone: require_sleep.method(zod.z.object({
|
|
215631
|
-
deviceId: zod.z.number(),
|
|
215632
|
-
zone: ZoneSchema
|
|
215633
|
-
}), zod.z.void(), {
|
|
215634
|
-
kind: "mutation",
|
|
215635
|
-
auth: "admin"
|
|
215636
|
-
})
|
|
215637
|
-
},
|
|
215638
|
-
/**
|
|
215639
|
-
* Runtime-state slice — the live zone catalogue mirrored by the
|
|
215640
|
-
* orchestrator on every CRUD mutation. Consumers read via
|
|
215641
|
-
* `device.state.zones.value` / `.watch(...)` without round-tripping
|
|
215642
|
-
* the cap, and the codegen DeviceProxy auto-wires the reactive
|
|
215643
|
-
* handle. Slice shape is `{ zones: Zone[] }` so future extensions
|
|
215644
|
-
* (e.g. zone groupings) can sit alongside the polygon list.
|
|
215645
|
-
*/
|
|
215646
|
-
runtimeState: zod.z.object({ zones: zod.z.array(ZoneSchema).readonly() }),
|
|
215647
|
-
/**
|
|
215648
|
-
* Runtime-state durability: **restored** — written only on operator mutation, so a camera that never had one has nothing to re-derive from. This is the slice `zone-mirror-hydration.ts` exists to paper over.
|
|
215649
|
-
*
|
|
215650
|
-
* See `RuntimeStateDurability`. Enforced by
|
|
215651
|
-
* `scripts/check-runtime-state-durability.ts`.
|
|
215652
|
-
*/
|
|
215653
|
-
durability: "restored"
|
|
215654
|
-
};
|
|
215655
216186
|
var NativeCropBboxSchema = zod.z.object({
|
|
215656
216187
|
x: zod.z.number(),
|
|
215657
216188
|
y: zod.z.number(),
|
|
@@ -224617,6 +225148,23 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
224617
225148
|
/** Media ms the returned fragment covers. */
|
|
224618
225149
|
gopDurMs: zod.z.number()
|
|
224619
225150
|
});
|
|
225151
|
+
var ReadWindowBytesResultSchema = zod.z.discriminatedUnion("kind", [zod.z.object({
|
|
225152
|
+
kind: zod.z.literal("ok"),
|
|
225153
|
+
data: zod.z.instanceof(Uint8Array),
|
|
225154
|
+
/** Absolute epoch ms of the returned bytes' first sample — at or before
|
|
225155
|
+
* the requested `fromMs` (anchored on the nearest keyframe). */
|
|
225156
|
+
gopStartMs: zod.z.number(),
|
|
225157
|
+
/** Media ms the returned bytes cover, from `gopStartMs`. */
|
|
225158
|
+
gopDurMs: zod.z.number(),
|
|
225159
|
+
/** `false` ⇒ the safety byte cap cut the read short before it reached
|
|
225160
|
+
* the requested `toMs`; the caller got fewer frames than asked for. */
|
|
225161
|
+
reachesRequestedEnd: zod.z.boolean()
|
|
225162
|
+
}), zod.z.object({
|
|
225163
|
+
kind: zod.z.literal("spans-multiple-segments"),
|
|
225164
|
+
/** Where the covering segment's own footage runs out — informational,
|
|
225165
|
+
* not a retry hint (retrying the same window would refuse again). */
|
|
225166
|
+
segmentEndMs: zod.z.number()
|
|
225167
|
+
})]);
|
|
224620
225168
|
var recordingCapability = {
|
|
224621
225169
|
name: "recording",
|
|
224622
225170
|
scope: "system",
|
|
@@ -224696,6 +225244,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
224696
225244
|
kind: "query",
|
|
224697
225245
|
auth: "admin"
|
|
224698
225246
|
}),
|
|
225247
|
+
/** Read a WINDOW `[fromMs, toMs)` of segment `startMs`, by mfra byte
|
|
225248
|
+
* range — the multi-GOP twin of `readGopBytes`. Refuses (does not
|
|
225249
|
+
* degrade) when the window runs past the covering segment. Used by the
|
|
225250
|
+
* replay clip's `recording` source to fetch several seconds of native
|
|
225251
|
+
* footage for its single ffmpeg decode pass. */
|
|
225252
|
+
readWindowBytes: require_sleep.method(zod.z.object({
|
|
225253
|
+
deviceId: zod.z.number(),
|
|
225254
|
+
profile: zod.z.string(),
|
|
225255
|
+
startMs: zod.z.number(),
|
|
225256
|
+
fromMs: zod.z.number(),
|
|
225257
|
+
toMs: zod.z.number()
|
|
225258
|
+
}), ReadWindowBytesResultSchema, {
|
|
225259
|
+
kind: "query",
|
|
225260
|
+
auth: "admin"
|
|
225261
|
+
}),
|
|
224699
225262
|
setDeviceConfig: require_sleep.method(zod.z.object({
|
|
224700
225263
|
deviceId: zod.z.number(),
|
|
224701
225264
|
config: RecordingConfigSchema
|
|
@@ -225275,59 +225838,6 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
225275
225838
|
*/
|
|
225276
225839
|
durability: "session"
|
|
225277
225840
|
};
|
|
225278
|
-
var ZoneRuleModeEnum = zod.z.enum(["include", "exclude"]);
|
|
225279
|
-
var ZoneRuleSchema = zod.z.object({
|
|
225280
|
-
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
225281
|
-
id: zod.z.string(),
|
|
225282
|
-
/** Optional human-readable label rendered in the rule editor. */
|
|
225283
|
-
name: zod.z.string().optional(),
|
|
225284
|
-
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
225285
|
-
* listed zones (OR-set: a detection in any one of them counts).
|
|
225286
|
-
* At least one zone id required — a rule with no targets is a
|
|
225287
|
-
* configuration mistake and the form validator rejects it. */
|
|
225288
|
-
zoneIds: zod.z.array(zod.z.string()).min(1).readonly(),
|
|
225289
|
-
mode: ZoneRuleModeEnum,
|
|
225290
|
-
/**
|
|
225291
|
-
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
225292
|
-
* applies to every class. Class strings match the `macroClass`
|
|
225293
|
-
* field on detections (e.g. `person`, `car`, `dog`).
|
|
225294
|
-
*/
|
|
225295
|
-
classFilter: zod.z.array(zod.z.string()).readonly().optional(),
|
|
225296
|
-
/**
|
|
225297
|
-
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
225298
|
-
* required to consider an entity "in the zone". Defaults to the
|
|
225299
|
-
* consumer's stage default when omitted. Kept for back-compat with
|
|
225300
|
-
* existing per-rule overrides; new operators pick the value via
|
|
225301
|
-
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
225302
|
-
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
225303
|
-
*/
|
|
225304
|
-
overlapThreshold: zod.z.number().min(0).max(1).optional(),
|
|
225305
|
-
/**
|
|
225306
|
-
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
225307
|
-
* of the detection's bbox that must lie inside the zone for the
|
|
225308
|
-
* rule to match. Documented default is 85%; the engine substitutes
|
|
225309
|
-
* that when the field is omitted (kept optional so existing rules
|
|
225310
|
-
* stored without it stay valid).
|
|
225311
|
-
*
|
|
225312
|
-
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
225313
|
-
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
225314
|
-
* field exposed in the UI. Internally both feed the same gate.
|
|
225315
|
-
*/
|
|
225316
|
-
bboxInclusionPct: zod.z.number().min(0).max(100).optional(),
|
|
225317
|
-
/**
|
|
225318
|
-
* When `true` and a detection has a segmentation mask, use the
|
|
225319
|
-
* mask for overlap instead of the bbox. Detection-stage only;
|
|
225320
|
-
* motion rules ignore this field.
|
|
225321
|
-
*/
|
|
225322
|
-
preferMask: zod.z.boolean().optional(),
|
|
225323
|
-
/**
|
|
225324
|
-
* Soft-toggle: `false` disables the rule without deleting it.
|
|
225325
|
-
* Defaults to `true` so operators creating a rule via the UI
|
|
225326
|
-
* see it active immediately.
|
|
225327
|
-
*/
|
|
225328
|
-
enabled: zod.z.boolean().default(true)
|
|
225329
|
-
});
|
|
225330
|
-
var ZoneRulesArraySchema = zod.z.array(ZoneRuleSchema).readonly();
|
|
225331
225841
|
var ScriptRunnerStatusSchema = zod.z.object({
|
|
225332
225842
|
/** Whether the script is currently executing. */
|
|
225333
225843
|
isRunning: zod.z.boolean(),
|
|
@@ -233176,6 +233686,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233176
233686
|
addonId: null,
|
|
233177
233687
|
access: "view"
|
|
233178
233688
|
},
|
|
233689
|
+
"notificationRules.resolveArtifactUrl": {
|
|
233690
|
+
capName: "notification-rules",
|
|
233691
|
+
capScope: "system",
|
|
233692
|
+
addonId: null,
|
|
233693
|
+
access: "view"
|
|
233694
|
+
},
|
|
233179
233695
|
"notificationRules.setAlarmConfig": {
|
|
233180
233696
|
capName: "notification-rules",
|
|
233181
233697
|
capScope: "system",
|
|
@@ -233620,6 +234136,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233620
234136
|
addonId: null,
|
|
233621
234137
|
access: "create"
|
|
233622
234138
|
},
|
|
234139
|
+
"pipelineAnalytics.runReplayFrameProcessor": {
|
|
234140
|
+
capName: "pipeline-analytics",
|
|
234141
|
+
capScope: "device",
|
|
234142
|
+
addonId: null,
|
|
234143
|
+
access: "create"
|
|
234144
|
+
},
|
|
233623
234145
|
"pipelineAnalytics.saveRetrainAnnotations": {
|
|
233624
234146
|
capName: "pipeline-analytics",
|
|
233625
234147
|
capScope: "device",
|
|
@@ -233752,6 +234274,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233752
234274
|
addonId: null,
|
|
233753
234275
|
access: "view"
|
|
233754
234276
|
},
|
|
234277
|
+
"pipelineExecutor.getInferenceDeviceHealth": {
|
|
234278
|
+
capName: "pipeline-executor",
|
|
234279
|
+
capScope: "system",
|
|
234280
|
+
addonId: null,
|
|
234281
|
+
access: "view"
|
|
234282
|
+
},
|
|
233755
234283
|
"pipelineExecutor.getOrchestratorConfigSchema": {
|
|
233756
234284
|
capName: "pipeline-executor",
|
|
233757
234285
|
capScope: "system",
|
|
@@ -233824,6 +234352,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233824
234352
|
addonId: null,
|
|
233825
234353
|
access: "view"
|
|
233826
234354
|
},
|
|
234355
|
+
"pipelineExecutor.rearmInferenceDevice": {
|
|
234356
|
+
capName: "pipeline-executor",
|
|
234357
|
+
capScope: "system",
|
|
234358
|
+
addonId: null,
|
|
234359
|
+
access: "create"
|
|
234360
|
+
},
|
|
233827
234361
|
"pipelineExecutor.runAudioTest": {
|
|
233828
234362
|
capName: "pipeline-executor",
|
|
233829
234363
|
capScope: "system",
|
|
@@ -234562,6 +235096,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
234562
235096
|
addonId: null,
|
|
234563
235097
|
access: "view"
|
|
234564
235098
|
},
|
|
235099
|
+
"recording.readWindowBytes": {
|
|
235100
|
+
capName: "recording",
|
|
235101
|
+
capScope: "system",
|
|
235102
|
+
addonId: null,
|
|
235103
|
+
access: "view"
|
|
235104
|
+
},
|
|
234565
235105
|
"recording.refreshStorageLocationsForMigration": {
|
|
234566
235106
|
capName: "recording",
|
|
234567
235107
|
capScope: "system",
|
|
@@ -237324,6 +237864,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
237324
237864
|
form: "single",
|
|
237325
237865
|
optional: false
|
|
237326
237866
|
}],
|
|
237867
|
+
"pipelineAnalytics.runReplayFrameProcessor": [{
|
|
237868
|
+
name: "deviceId",
|
|
237869
|
+
form: "single",
|
|
237870
|
+
optional: false
|
|
237871
|
+
}],
|
|
237327
237872
|
"pipelineAnalytics.saveRetrainAnnotations": [{
|
|
237328
237873
|
name: "deviceId",
|
|
237329
237874
|
form: "single",
|
|
@@ -237639,6 +238184,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
237639
238184
|
form: "single",
|
|
237640
238185
|
optional: false
|
|
237641
238186
|
}],
|
|
238187
|
+
"recording.readWindowBytes": [{
|
|
238188
|
+
name: "deviceId",
|
|
238189
|
+
form: "single",
|
|
238190
|
+
optional: false
|
|
238191
|
+
}],
|
|
237642
238192
|
"recording.relocateFootage": [{
|
|
237643
238193
|
name: "deviceId",
|
|
237644
238194
|
form: "single",
|
|
@@ -238115,6 +238665,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
238115
238665
|
"recording.pruneFootage",
|
|
238116
238666
|
"recording.readGopBytes",
|
|
238117
238667
|
"recording.readSegmentBytes",
|
|
238668
|
+
"recording.readWindowBytes",
|
|
238118
238669
|
"recording.relocateFootage",
|
|
238119
238670
|
"recording.renderClip",
|
|
238120
238671
|
"recording.renderGif",
|
|
@@ -238900,6 +239451,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
238900
239451
|
getVideoPipelineSteps: (input) => dispatch("pipelineExecutor", "getVideoPipelineSteps", "query", input),
|
|
238901
239452
|
setVideoPipelineSteps: (input) => dispatch("pipelineExecutor", "setVideoPipelineSteps", "mutation", input),
|
|
238902
239453
|
clearDeviceOverrides: (input) => dispatch("pipelineExecutor", "clearDeviceOverrides", "mutation", input),
|
|
239454
|
+
getInferenceDeviceHealth: (input) => dispatch("pipelineExecutor", "getInferenceDeviceHealth", "query", input),
|
|
239455
|
+
rearmInferenceDevice: (input) => dispatch("pipelineExecutor", "rearmInferenceDevice", "mutation", input),
|
|
238903
239456
|
getSchema: (input) => dispatch("pipelineExecutor", "getSchema", "query", input),
|
|
238904
239457
|
getGlobalSteps: (input) => dispatch("pipelineExecutor", "getGlobalSteps", "query", input),
|
|
238905
239458
|
getGlobalPipelineConfig: (input) => dispatch("pipelineExecutor", "getGlobalPipelineConfig", "query", input),
|
|
@@ -242434,6 +242987,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
242434
242987
|
exports.RawStateResultSchema = require_sleep.RawStateResultSchema;
|
|
242435
242988
|
exports.ReadGopBytesResultSchema = ReadGopBytesResultSchema;
|
|
242436
242989
|
exports.ReadSegmentBytesResultSchema = ReadSegmentBytesResultSchema;
|
|
242990
|
+
exports.ReadWindowBytesResultSchema = ReadWindowBytesResultSchema;
|
|
242437
242991
|
exports.ReadinessRegistry = require_sleep.ReadinessRegistry;
|
|
242438
242992
|
exports.ReadinessTimeoutError = require_sleep.ReadinessTimeoutError;
|
|
242439
242993
|
exports.RecentTracksPageSchema = RecentTracksPageSchema;
|