@camstack/addon-admin-ui 1.2.270 → 1.2.272
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{AddonCollectionPage-B6Y9A4N6.js → AddonCollectionPage-D6fy7dpj.js} +1 -1
- package/dist/assets/{Addons-DKsfeLYq.js → Addons-BsQHKMWG.js} +1 -1
- package/dist/assets/{AdminTabs-Dja8Mk-W.js → AdminTabs-V9k1QuVP.js} +1 -1
- package/dist/assets/{AiProfiles-DTlmdt6r.js → AiProfiles-DiPkD_fk.js} +1 -1
- package/dist/assets/{BrokerForm-CfgRH6tY.js → BrokerForm-CYGBfbxr.js} +1 -1
- package/dist/assets/{Build-DpV-cPL8.js → Build-CBeEDpy5.js} +3 -3
- package/dist/assets/{Capabilities-BXUesCYR.js → Capabilities-D1KT-ivA.js} +1 -1
- package/dist/assets/{CapabilityBadges-BZvkOTYZ.js → CapabilityBadges-DS8SoWoz.js} +1 -1
- package/dist/assets/{Cluster-CeHjzcdf.js → Cluster-gJW9vP03.js} +1 -1
- package/dist/assets/{Data-BrXED5lV.js → Data-Bh0bzESu.js} +1 -1
- package/dist/assets/{DetectionIntelligence-Vv7Tt8E9.js → DetectionIntelligence-Cv2fg-SI.js} +1 -1
- package/dist/assets/{DeviceAggregateSection-DPGr5GdW.js → DeviceAggregateSection-DHALwPAJ.js} +1 -1
- package/dist/assets/{DeviceDetail-C1iH5aa7.js → DeviceDetail-Cj4upIZ8.js} +2 -2
- package/dist/assets/{Devices-Csoa2iXv.js → Devices-HDneMnHi.js} +1 -1
- package/dist/assets/{EmbedPlayerPage-ClmVSRaH.js → EmbedPlayerPage-B_wGVEK0.js} +1 -1
- package/dist/assets/{Events-CCyJIOrV.js → Events-BPXFJIla.js} +1 -1
- package/dist/assets/{FormBuilder-xcf2zSPO.js → FormBuilder-BXtojpHF.js} +1 -1
- package/dist/assets/{Identity-BBYRbHQy.js → Identity-_IPjFsQw.js} +1 -1
- package/dist/assets/{IntegrationDetail-BPRFG_x7.js → IntegrationDetail-DIY7Jywc.js} +1 -1
- package/dist/assets/{Integrations-TvUDY480.js → Integrations-DXOrcEGt.js} +1 -1
- package/dist/assets/{Integrations-BLiNhwOc.js → Integrations-mJpIsz9F.js} +1 -1
- package/dist/assets/{Locations-DVLRdub1.js → Locations-wB0U93K4.js} +2 -2
- package/dist/assets/{Logs-CsA6OluL.js → Logs-BYTo71Yt.js} +1 -1
- package/dist/assets/{MotionZonesSettings-Bb8Cm9Bc.js → MotionZonesSettings-DDf16JDF.js} +1 -1
- package/dist/assets/{MyAccess-B1LK0w2i.js → MyAccess-BbWITi4N.js} +1 -1
- package/dist/assets/{Network-Damirh81.js → Network-30R4cY39.js} +1 -1
- package/dist/assets/{NodeAddonsSettingsPanel-Bxfkk4PN.js → NodeAddonsSettingsPanel-UySNHnGf.js} +1 -1
- package/dist/assets/{NodeInferenceDevices-BqrhKAV8.js → NodeInferenceDevices-B3VEAQWr.js} +1 -1
- package/dist/assets/Notifications-C1yukm6c.js +1 -0
- package/dist/assets/Pipeline-DXl1Hzdu.js +1 -0
- package/dist/assets/{Plates--8DdSua6.js → Plates-BIhVH_IZ.js} +1 -1
- package/dist/assets/{PrivacyMaskSettings-BV83k182.js → PrivacyMaskSettings-C0HZcbXR.js} +1 -1
- package/dist/assets/{ProviderIcon-CWNMbs3U.js → ProviderIcon-DXK0cuQe.js} +1 -1
- package/dist/assets/{Recordings-tsT7ZoWd.js → Recordings-CfpOjuow.js} +1 -1
- package/dist/assets/{ScanNetworkModal-D3naTRQ3.js → ScanNetworkModal-B3CQ1S3f.js} +1 -1
- package/dist/assets/{SceneMonitorEditor-BuqQ30uy.js → SceneMonitorEditor-BN7kLz08.js} +1 -1
- package/dist/assets/{Scenes-B7QGDpEK.js → Scenes-Dbko4G3U.js} +1 -1
- package/dist/assets/{Settings-BlG7mCfA.js → Settings-eB6bRRQ2.js} +1 -1
- package/dist/assets/{Showroom-T_5DsEVl.js → Showroom-D7VNR9sm.js} +1 -1
- package/dist/assets/{StorageLocationsPanel-BOZm_gD6.js → StorageLocationsPanel-CfOU5MKV.js} +1 -1
- package/dist/assets/{Terminal-Dob1RVmO.js → Terminal-DJ13Ptlg.js} +1 -1
- package/dist/assets/{Viewer-CSyausau.js → Viewer-DSNI0gBQ.js} +1 -1
- package/dist/assets/{_virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-DzkxahtX.js → _virtual_mf-localSharedImportMap___mfe_internal__admin_ui_host-CHnD_XCi.js} +1 -1
- package/dist/assets/{archive-BOh2m678.js → archive-CfPc3zmd.js} +1 -1
- package/dist/assets/{authed-media-BVflovlM.js → authed-media-D0FYWdWm.js} +1 -1
- package/dist/assets/{boxes-BKD7ctjv.js → boxes-Bziwj8sB.js} +1 -1
- package/dist/assets/circle-slash-DNDn3yid.js +1 -0
- package/dist/assets/{debounced-invalidate-CMQlPGE8.js → debounced-invalidate-Bpjoo47a.js} +1 -1
- package/dist/assets/dist-CRVdBpiI.js +349 -0
- package/dist/assets/{dist-BIL8T-y8.js → dist-CnCHhuKr.js} +1 -1
- package/dist/assets/{face-bbox-1CwrB3Hs.js → face-bbox-CTW2Ql-L.js} +1 -1
- package/dist/assets/{hard-drive-download-Kzh5K7rR.js → hard-drive-download-D69_02_z.js} +1 -1
- package/dist/assets/{hostInit-CwLFw7vK.js → hostInit-Duev9E28.js} +1 -1
- package/dist/assets/{index-DNU21ztY.js → index-BjhxGD-m.js} +3 -3
- package/dist/assets/{layers-C9GOKidf.js → layers-dj0W-5PD.js} +1 -1
- package/dist/assets/{location-owned-usage-DveepH5t.js → location-owned-usage-Dd31wc7R.js} +1 -1
- package/dist/assets/{mf-entry-bootstrap-0-46ea76f9.js → mf-entry-bootstrap-0-f2ee65db.js} +2 -2
- package/dist/assets/{player-overlays-EeJrynNb.js → player-overlays-BCwjKg6p.js} +1 -1
- package/dist/assets/remoteEntry-DUHRclu_.js +1 -0
- package/dist/assets/{send-N7ccgjhP.js → send-DI8RyAAG.js} +1 -1
- package/dist/assets/{settings-2-CHKxEaPE.js → settings-2-pQ157vcG.js} +1 -1
- package/dist/assets/{square-check-big-XOX8oOer.js → square-check-big-CluVAeV_.js} +1 -1
- package/dist/assets/{src-B-lfEnzH.js → src-BI1z_AYO.js} +7 -7
- package/dist/assets/src-D2MUU060.js +349 -0
- package/dist/assets/{use-scenes-feed-BIrOB2ti.js → use-scenes-feed-Do31SA2K.js} +1 -1
- package/dist/assets/{use-stationary-objects-C00pz2bM.js → use-stationary-objects-DqcSiA8T.js} +1 -1
- package/dist/assets/useEventInvalidation-GeG-PeIJ.js +1 -0
- package/dist/assets/{useNodeUrlSelection-taqMJccO.js → useNodeUrlSelection-BsR42Cfa.js} +1 -1
- package/dist/assets/user-round-DG8UupM9.js +1 -0
- package/dist/assets/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-BEogBfBZ.js → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__admin_ui_host__remoteEntry-_hash_-CwUNfWUA.js} +2 -2
- package/dist/index.html +5 -5
- package/dist/server/addon.js +1095 -729
- package/package.json +1 -1
- package/dist/assets/Notifications-CbMHkusP.js +0 -1
- package/dist/assets/Pipeline-D11oz9uM.js +0 -1
- package/dist/assets/circle-slash-LwJaRs4o.js +0 -1
- package/dist/assets/dist-BJS_Szr8.js +0 -349
- package/dist/assets/remoteEntry-Ow3355ft.js +0 -1
- package/dist/assets/src-BEtfCXVH.js +0 -349
- package/dist/assets/useEventInvalidation-DdzMajse.js +0 -1
- package/dist/assets/user-round-ggNS5VOL.js +0 -1
package/dist/server/addon.js
CHANGED
|
@@ -5361,7 +5361,7 @@ var ZodIssueCode = {
|
|
|
5361
5361
|
var ZodFirstPartyTypeKind;
|
|
5362
5362
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5363
5363
|
//#endregion
|
|
5364
|
-
//#region ../types/dist/sleep-
|
|
5364
|
+
//#region ../types/dist/sleep-BaRu0bS5.mjs
|
|
5365
5365
|
/**
|
|
5366
5366
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5367
5367
|
* window to float samples (D455).
|
|
@@ -9434,7 +9434,7 @@ var ModelFormatEntrySchema = object({
|
|
|
9434
9434
|
/** Multi-file payload (directory members or sibling files). */
|
|
9435
9435
|
files: array(string()).readonly().optional(),
|
|
9436
9436
|
/** Runtime(s) that can use this format. If omitted, inferred from ModelFormat key */
|
|
9437
|
-
runtimes: array(_enum(["
|
|
9437
|
+
runtimes: array(_enum(["python"])).readonly().optional()
|
|
9438
9438
|
});
|
|
9439
9439
|
/**
|
|
9440
9440
|
* Extra file that must be downloaded alongside the model (e.g., labels JSON, dict.txt).
|
|
@@ -17046,6 +17046,29 @@ var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
|
|
|
17046
17046
|
]);
|
|
17047
17047
|
NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
|
|
17048
17048
|
/**
|
|
17049
|
+
* The panel's transitions, as ONE list.
|
|
17050
|
+
*
|
|
17051
|
+
* Named here rather than spelled out at each of the four sites that need them
|
|
17052
|
+
* (the emitter, the intake, the editor group, the combined-notification gate),
|
|
17053
|
+
* because a transition added to the enum and forgotten at one of them is an
|
|
17054
|
+
* alarm state nobody can be notified about. That is exactly what this list
|
|
17055
|
+
* failed to prevent while it held three: `alarm-arming` was the fourth.
|
|
17056
|
+
*
|
|
17057
|
+
* In LIFECYCLE order, which is the order an editor lists them in and the order
|
|
17058
|
+
* a person experiences them — not the order they were added.
|
|
17059
|
+
*/
|
|
17060
|
+
var NC_ALARM_SYSTEM_EVENT_KINDS = [
|
|
17061
|
+
"alarm-arm-refused",
|
|
17062
|
+
"alarm-check-failed",
|
|
17063
|
+
"alarm-arming",
|
|
17064
|
+
"alarm-armed",
|
|
17065
|
+
"alarm-pending",
|
|
17066
|
+
"alarm-triggered",
|
|
17067
|
+
"alarm-rearmed",
|
|
17068
|
+
"alarm-sensor-bypass",
|
|
17069
|
+
"alarm-disarmed"
|
|
17070
|
+
];
|
|
17071
|
+
/**
|
|
17049
17072
|
* One coherent system-event condition. `kinds` is the required opt-in safety
|
|
17050
17073
|
* gate; the remaining lists are optional narrowing filters relevant to the
|
|
17051
17074
|
* selected kinds.
|
|
@@ -17112,6 +17135,25 @@ var NcScheduleSchema = object({
|
|
|
17112
17135
|
/** Active OUTSIDE the windows (e.g. "only outside business hours"). */
|
|
17113
17136
|
invert: boolean().optional()
|
|
17114
17137
|
});
|
|
17138
|
+
/**
|
|
17139
|
+
* How a system-event rule of the `device-events` or `system` family speaks
|
|
17140
|
+
* (D647): at once, per event (`instant`, the only behaviour before D647), or
|
|
17141
|
+
* as a STATE SUMMARY at the end of each window of `schedule`.
|
|
17142
|
+
*/
|
|
17143
|
+
var NcSystemEventDeliveryModeSchema = _enum(["instant", "summary"]);
|
|
17144
|
+
/**
|
|
17145
|
+
* `summary`: the rule sends NOTHING per event. When a window of `schedule`
|
|
17146
|
+
* CLOSES, it sends one notification with the current state of its kinds
|
|
17147
|
+
* (low batteries, consumables to replace, devices offline, updates
|
|
17148
|
+
* available, ...), after its own filters. Nothing to report sends nothing.
|
|
17149
|
+
* The schedule is the ordinary `NcSchedule` (weekly windows, IANA timezone,
|
|
17150
|
+
* midnight crossing); the send time is each window's END. Refused on the
|
|
17151
|
+
* `alarm` family, which stays instant (`systemEventDeliveryProblems`).
|
|
17152
|
+
*/
|
|
17153
|
+
var NcSystemEventDeliverySchema = discriminatedUnion("mode", [object({ mode: literal("instant") }), object({
|
|
17154
|
+
mode: literal("summary"),
|
|
17155
|
+
schedule: NcScheduleSchema
|
|
17156
|
+
})]);
|
|
17115
17157
|
/** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
|
|
17116
17158
|
var NcPlateMatcherSchema = object({
|
|
17117
17159
|
/**
|
|
@@ -17847,6 +17889,16 @@ var NcRuleInputSchema = object({
|
|
|
17847
17889
|
delivery: NcDeliverySchema,
|
|
17848
17890
|
conditions: NcConditionsSchema.default({}),
|
|
17849
17891
|
schedule: NcScheduleSchema.optional(),
|
|
17892
|
+
/**
|
|
17893
|
+
* A `device-events` / `system` rule's delivery (D647): absent or `instant`
|
|
17894
|
+
* is a notification per event; `summary` is one state summary per closed
|
|
17895
|
+
* window of its schedule. `.optional()` and never defaulted: absent must
|
|
17896
|
+
* keep meaning what every rule authored before D647 meant, with no
|
|
17897
|
+
* migration. Top-level rather than inside `conditions.systemEvent`, so a
|
|
17898
|
+
* client that does not know it (an older viewer re-sending `conditions`
|
|
17899
|
+
* whole) leaves it standing through the store's patch merge.
|
|
17900
|
+
*/
|
|
17901
|
+
systemEventDelivery: NcSystemEventDeliverySchema.optional(),
|
|
17850
17902
|
/** May be empty when `targetUsers` addresses at least one user — the
|
|
17851
17903
|
* "at least one addressee" invariant is enforced by the provider, because
|
|
17852
17904
|
* a cross-field refine here would break `NcRulePatchSchema.partial()`. */
|
|
@@ -18075,6 +18127,28 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
18075
18127
|
*/
|
|
18076
18128
|
disabledTargetIds: array(string()).default([])
|
|
18077
18129
|
});
|
|
18130
|
+
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
18131
|
+
var NcStateSummaryPreviewSectionSchema = object({
|
|
18132
|
+
id: string(),
|
|
18133
|
+
status: _enum(["read", "unavailable"]),
|
|
18134
|
+
items: number().int().nonnegative(),
|
|
18135
|
+
reason: string().optional()
|
|
18136
|
+
});
|
|
18137
|
+
/**
|
|
18138
|
+
* The summary a rule would send now. `empty` = nothing to report and every
|
|
18139
|
+
* section read: such a summary is NOT sent. `dropped` counts the open states
|
|
18140
|
+
* the rule's own filters (or a camera mute) left out, by reason.
|
|
18141
|
+
* `excludedGroups` names the kind groups selected that have no state to report
|
|
18142
|
+
* (backups & exports).
|
|
18143
|
+
*/
|
|
18144
|
+
var NcStateSummaryPreviewSchema = object({
|
|
18145
|
+
empty: boolean(),
|
|
18146
|
+
count: number().int().nonnegative(),
|
|
18147
|
+
text: string(),
|
|
18148
|
+
sections: array(NcStateSummaryPreviewSectionSchema),
|
|
18149
|
+
dropped: record(string(), number().int().nonnegative()),
|
|
18150
|
+
excludedGroups: array(string())
|
|
18151
|
+
});
|
|
18078
18152
|
var NcTestResultSchema = object({
|
|
18079
18153
|
recordId: string(),
|
|
18080
18154
|
recordKind: _enum([
|
|
@@ -18166,6 +18240,13 @@ var NcTemplateVarDescriptorSchema = object({
|
|
|
18166
18240
|
kinds: array(NcTemplateVarKindSchema).optional(),
|
|
18167
18241
|
deliveries: array(NcDeliverySchema).optional(),
|
|
18168
18242
|
systemEventKinds: array(NcSystemEventKindSchema).optional(),
|
|
18243
|
+
/**
|
|
18244
|
+
* Which system-event DELIVERY has a value for it (D647). Absent = an
|
|
18245
|
+
* instant row only when the descriptor names `systemEventKinds` (a
|
|
18246
|
+
* per-event fact: a summary row has no single device), and both otherwise.
|
|
18247
|
+
* `['summary']` marks the state-summary vocabulary (`{{summaryText}}`, ...).
|
|
18248
|
+
*/
|
|
18249
|
+
systemEventDeliveries: array(NcSystemEventDeliveryModeSchema).optional(),
|
|
18169
18250
|
dynamic: object({
|
|
18170
18251
|
prefix: literal("count_"),
|
|
18171
18252
|
from: literal("classes")
|
|
@@ -18178,7 +18259,9 @@ var NcTemplatePreviewInputSchema = object({
|
|
|
18178
18259
|
field: NcTemplateFieldSchema,
|
|
18179
18260
|
kind: NcRuleKindSchema.optional(),
|
|
18180
18261
|
delivery: NcDeliverySchema.optional(),
|
|
18181
|
-
systemEventKinds: array(NcSystemEventKindSchema).optional()
|
|
18262
|
+
systemEventKinds: array(NcSystemEventKindSchema).optional(),
|
|
18263
|
+
/** The rule's system-event delivery (D647); absent = instant. */
|
|
18264
|
+
systemEventDelivery: NcSystemEventDeliveryModeSchema.optional()
|
|
18182
18265
|
}),
|
|
18183
18266
|
template: object({
|
|
18184
18267
|
title: string().max(500).optional(),
|
|
@@ -18712,6 +18795,10 @@ method(object({}), object({ rules: array(NcRuleSchema) }), { auth: "admin" }), m
|
|
|
18712
18795
|
}), object({ results: array(NcTestResultSchema) }), {
|
|
18713
18796
|
kind: "mutation",
|
|
18714
18797
|
auth: "admin"
|
|
18798
|
+
}), method(object({ rule: NcRuleInputSchema }), NcStateSummaryPreviewSchema, {
|
|
18799
|
+
kind: "mutation",
|
|
18800
|
+
auth: "admin",
|
|
18801
|
+
access: "view"
|
|
18715
18802
|
}), method(object({}), object({
|
|
18716
18803
|
catalog: array(NcConditionDescriptorSchema),
|
|
18717
18804
|
taxonomy: NcTaxonomySchema.optional()
|
|
@@ -19058,606 +19145,6 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
19058
19145
|
});
|
|
19059
19146
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
19060
19147
|
/**
|
|
19061
|
-
* Reference to the frame's retained NATIVE surface + the parent crop's placement
|
|
19062
|
-
* within the frame, so the executor can re-cut a leaf child ROI at native
|
|
19063
|
-
* resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
|
|
19064
|
-
*/
|
|
19065
|
-
var NativeCropRefSchema = object({
|
|
19066
|
-
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
19067
|
-
handle: FrameHandleSchema,
|
|
19068
|
-
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
19069
|
-
cropFrameSpace: object({
|
|
19070
|
-
x: number(),
|
|
19071
|
-
y: number(),
|
|
19072
|
-
w: number(),
|
|
19073
|
-
h: number()
|
|
19074
|
-
})
|
|
19075
|
-
});
|
|
19076
|
-
object({
|
|
19077
|
-
crop: object({
|
|
19078
|
-
left: number(),
|
|
19079
|
-
top: number(),
|
|
19080
|
-
width: number().positive(),
|
|
19081
|
-
height: number().positive()
|
|
19082
|
-
}).optional(),
|
|
19083
|
-
content: object({
|
|
19084
|
-
width: number().int().positive(),
|
|
19085
|
-
height: number().int().positive()
|
|
19086
|
-
}),
|
|
19087
|
-
fit: _enum(["stretch", "contain"]),
|
|
19088
|
-
format: _enum([
|
|
19089
|
-
"rgb",
|
|
19090
|
-
"gray",
|
|
19091
|
-
"jpeg"
|
|
19092
|
-
])
|
|
19093
|
-
});
|
|
19094
|
-
/**
|
|
19095
|
-
* Process-local frame identity. It is serializable so it can ride an in-process
|
|
19096
|
-
* capability call, but `registryId` deliberately prevents resolution in any
|
|
19097
|
-
* other process or execution group.
|
|
19098
|
-
*/
|
|
19099
|
-
var FrameRefSchema = object({
|
|
19100
|
-
registryId: string().min(1),
|
|
19101
|
-
id: string().min(1),
|
|
19102
|
-
width: number().int().positive(),
|
|
19103
|
-
height: number().int().positive(),
|
|
19104
|
-
format: _enum(["rgb", "gray"]),
|
|
19105
|
-
timestamp: number(),
|
|
19106
|
-
capturedAt: number().optional()
|
|
19107
|
-
});
|
|
19108
|
-
var ModelFormatSchema$1 = _enum([
|
|
19109
|
-
"onnx",
|
|
19110
|
-
"coreml",
|
|
19111
|
-
"openvino",
|
|
19112
|
-
"tflite",
|
|
19113
|
-
"pt",
|
|
19114
|
-
"gguf"
|
|
19115
|
-
]);
|
|
19116
|
-
var PipelineSlotSchema = _enum([
|
|
19117
|
-
"detector",
|
|
19118
|
-
"cropper",
|
|
19119
|
-
"classifier",
|
|
19120
|
-
"refiner",
|
|
19121
|
-
"audio-classifier"
|
|
19122
|
-
]);
|
|
19123
|
-
var PipelineEngineChoiceSchema = object({
|
|
19124
|
-
runtime: _enum(["node", "python"]),
|
|
19125
|
-
backend: string(),
|
|
19126
|
-
format: ModelFormatSchema$1,
|
|
19127
|
-
device: string().optional()
|
|
19128
|
-
});
|
|
19129
|
-
var AvailableEngineSchema = object({
|
|
19130
|
-
engine: PipelineEngineChoiceSchema,
|
|
19131
|
-
devices: array(object({
|
|
19132
|
-
id: string(),
|
|
19133
|
-
label: string(),
|
|
19134
|
-
description: string().optional()
|
|
19135
|
-
})).readonly(),
|
|
19136
|
-
defaultDevice: string()
|
|
19137
|
-
});
|
|
19138
|
-
var PipelineDefaultStepSchema = lazy(() => object({
|
|
19139
|
-
addonId: string(),
|
|
19140
|
-
addonName: string(),
|
|
19141
|
-
slot: PipelineSlotSchema,
|
|
19142
|
-
inputClasses: array(string()).readonly(),
|
|
19143
|
-
outputClasses: array(string()).readonly(),
|
|
19144
|
-
enabled: boolean(),
|
|
19145
|
-
modelId: string(),
|
|
19146
|
-
children: array(PipelineDefaultStepSchema).readonly(),
|
|
19147
|
-
group: string().optional(),
|
|
19148
|
-
settings: record(string(), unknown()).optional()
|
|
19149
|
-
}));
|
|
19150
|
-
var PipelineTemplateStepSchema = lazy(() => object({
|
|
19151
|
-
addonId: string(),
|
|
19152
|
-
enabled: boolean(),
|
|
19153
|
-
modelId: string(),
|
|
19154
|
-
children: array(PipelineTemplateStepSchema).readonly(),
|
|
19155
|
-
settings: record(string(), unknown()).optional()
|
|
19156
|
-
}));
|
|
19157
|
-
var PipelineTemplateSchema$1 = object({
|
|
19158
|
-
id: string(),
|
|
19159
|
-
name: string(),
|
|
19160
|
-
createdAt: string(),
|
|
19161
|
-
updatedAt: string(),
|
|
19162
|
-
engine: PipelineEngineChoiceSchema,
|
|
19163
|
-
steps: array(PipelineTemplateStepSchema).readonly()
|
|
19164
|
-
});
|
|
19165
|
-
var PipelineModelOptionSchema = object({
|
|
19166
|
-
id: string(),
|
|
19167
|
-
name: string(),
|
|
19168
|
-
formats: record(string(), object({
|
|
19169
|
-
downloaded: boolean(),
|
|
19170
|
-
sizeMB: number()
|
|
19171
|
-
})),
|
|
19172
|
-
group: ModelVariantGroupSchema.optional(),
|
|
19173
|
-
legacy: boolean().optional(),
|
|
19174
|
-
provider: ModelProviderIdSchema.optional()
|
|
19175
|
-
});
|
|
19176
|
-
var ConfigFieldBridge = custom();
|
|
19177
|
-
var PipelineAddonSchemaSchema = object({
|
|
19178
|
-
id: string(),
|
|
19179
|
-
name: string(),
|
|
19180
|
-
slot: PipelineSlotSchema,
|
|
19181
|
-
inputClasses: array(string()).readonly(),
|
|
19182
|
-
outputClasses: array(string()).readonly(),
|
|
19183
|
-
childSlots: array(PipelineSlotSchema).readonly(),
|
|
19184
|
-
models: array(PipelineModelOptionSchema).readonly(),
|
|
19185
|
-
defaultModelId: string(),
|
|
19186
|
-
defaultModelIdByFormat: record(string(), string()).optional(),
|
|
19187
|
-
enabledByDefault: boolean().optional(),
|
|
19188
|
-
backfillIntoExistingOverrides: boolean().optional(),
|
|
19189
|
-
defaultConfidence: number(),
|
|
19190
|
-
group: string().optional(),
|
|
19191
|
-
configSchema: array(ConfigFieldBridge).readonly().optional()
|
|
19192
|
-
});
|
|
19193
|
-
var PipelineSlotSchemaSchema = object({
|
|
19194
|
-
id: PipelineSlotSchema,
|
|
19195
|
-
label: string(),
|
|
19196
|
-
priority: number(),
|
|
19197
|
-
parentSlot: PipelineSlotSchema.nullable(),
|
|
19198
|
-
addons: array(PipelineAddonSchemaSchema).readonly()
|
|
19199
|
-
});
|
|
19200
|
-
var PipelineSchemaSchema = object({
|
|
19201
|
-
availableEngines: array(AvailableEngineSchema).readonly(),
|
|
19202
|
-
selectedEngine: PipelineEngineChoiceSchema,
|
|
19203
|
-
slots: array(PipelineSlotSchemaSchema).readonly()
|
|
19204
|
-
});
|
|
19205
|
-
var EngineProvisioningSchema = object({
|
|
19206
|
-
runtimeId: _enum([
|
|
19207
|
-
"onnx",
|
|
19208
|
-
"openvino",
|
|
19209
|
-
"coreml",
|
|
19210
|
-
"edgetpu"
|
|
19211
|
-
]).nullable(),
|
|
19212
|
-
device: string().nullable(),
|
|
19213
|
-
state: _enum([
|
|
19214
|
-
"idle",
|
|
19215
|
-
"installing",
|
|
19216
|
-
"verifying",
|
|
19217
|
-
"ready",
|
|
19218
|
-
"failed"
|
|
19219
|
-
]),
|
|
19220
|
-
progress: number().optional(),
|
|
19221
|
-
error: string().optional(),
|
|
19222
|
-
nextRetryAt: number().optional(),
|
|
19223
|
-
/**
|
|
19224
|
-
* Gate A (config-correctness gate at engine change): human-readable
|
|
19225
|
-
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
19226
|
-
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
19227
|
-
* has a <format> build"). Additive/optional: informational only, never
|
|
19228
|
-
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
19229
|
-
* Absent/empty when the node-default tree resolves cleanly.
|
|
19230
|
-
*/
|
|
19231
|
-
configIssues: array(string()).optional()
|
|
19232
|
-
});
|
|
19233
|
-
var PipelineStepInputSchema = lazy(() => object({
|
|
19234
|
-
addonId: string(),
|
|
19235
|
-
modelId: string().optional(),
|
|
19236
|
-
enabled: boolean().default(true),
|
|
19237
|
-
children: array(PipelineStepInputSchema).optional(),
|
|
19238
|
-
settings: record(string(), unknown()).optional(),
|
|
19239
|
-
jumpDeviceKey: string().optional()
|
|
19240
|
-
}));
|
|
19241
|
-
var ModelSubstitutionSchema = object({
|
|
19242
|
-
addonId: string(),
|
|
19243
|
-
chosen: string(),
|
|
19244
|
-
running: string(),
|
|
19245
|
-
format: string()
|
|
19246
|
-
});
|
|
19247
|
-
var PipelineValidationIssueSchema = object({
|
|
19248
|
-
addonId: string(),
|
|
19249
|
-
kind: _enum(["unknown-addon", "no-format-build"]),
|
|
19250
|
-
detail: string()
|
|
19251
|
-
});
|
|
19252
|
-
var PipelineValidationResultSchema = object({
|
|
19253
|
-
ok: boolean(),
|
|
19254
|
-
issues: array(PipelineValidationIssueSchema).readonly(),
|
|
19255
|
-
substitutions: array(ModelSubstitutionSchema).readonly(),
|
|
19256
|
-
/** The node's `currentEngine.format` this validation ran against. */
|
|
19257
|
-
format: string()
|
|
19258
|
-
});
|
|
19259
|
-
var ReferenceImageEntrySchema = object({
|
|
19260
|
-
filename: string(),
|
|
19261
|
-
stepIds: array(string()).readonly().optional()
|
|
19262
|
-
});
|
|
19263
|
-
var ReferenceImageBodySchema = object({
|
|
19264
|
-
base64: string(),
|
|
19265
|
-
filename: string()
|
|
19266
|
-
});
|
|
19267
|
-
var ReferenceAudioEntrySchema = object({
|
|
19268
|
-
filename: string(),
|
|
19269
|
-
sizeKb: number()
|
|
19270
|
-
});
|
|
19271
|
-
var ReferenceAudioBodySchema = object({ base64: string() });
|
|
19272
|
-
var AudioBackendSchema = object({
|
|
19273
|
-
id: string(),
|
|
19274
|
-
name: string(),
|
|
19275
|
-
description: string(),
|
|
19276
|
-
available: boolean(),
|
|
19277
|
-
/**
|
|
19278
|
-
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
19279
|
-
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
19280
|
-
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
19281
|
-
* specific to the selected backend without a separate fetch.
|
|
19282
|
-
*/
|
|
19283
|
-
rawLabels: array(string()).readonly().optional()
|
|
19284
|
-
});
|
|
19285
|
-
var AudioCapabilitiesSchema = object({
|
|
19286
|
-
activeBackend: string(),
|
|
19287
|
-
availableBackends: array(AudioBackendSchema).readonly(),
|
|
19288
|
-
sampleRate: number(),
|
|
19289
|
-
chunkDurationMs: number()
|
|
19290
|
-
});
|
|
19291
|
-
var DownloadModelResultSchema = object({
|
|
19292
|
-
filePath: string(),
|
|
19293
|
-
sizeMB: number(),
|
|
19294
|
-
durationMs: number()
|
|
19295
|
-
});
|
|
19296
|
-
/**
|
|
19297
|
-
* Wrapper carrying a single test run's result. Replaces the legacy
|
|
19298
|
-
* ad-hoc `{labels: [{className, originalClass, score}]}` shape with the
|
|
19299
|
-
* canonical `AudioResult` from the Phase 6 output rework: one
|
|
19300
|
-
* `AudioDetection` per class above `minScore`, top-N candidates in
|
|
19301
|
-
* `debug.alternateLabels['audio-classifier']`, per-source timings in
|
|
19302
|
-
* `debug.stepTimings`. The outer `success`/`error` fields stay so the
|
|
19303
|
-
* benchmark UI can still report a clean failure when the classifier
|
|
19304
|
-
* cap isn't available.
|
|
19305
|
-
*/
|
|
19306
|
-
var AudioTestResultSchema = object({
|
|
19307
|
-
success: boolean(),
|
|
19308
|
-
error: string().optional(),
|
|
19309
|
-
frame: custom().optional()
|
|
19310
|
-
});
|
|
19311
|
-
var PipelineConfigBridge = custom();
|
|
19312
|
-
var ConfigUISchemaBridge = custom();
|
|
19313
|
-
var ConfigUISchemaNullableBridge = custom();
|
|
19314
|
-
var InferenceCapabilitiesBridge = custom();
|
|
19315
|
-
var ModelAvailabilityListBridge = custom();
|
|
19316
|
-
var PipelineRunResultBridge = custom();
|
|
19317
|
-
method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
|
|
19318
|
-
modelId: string(),
|
|
19319
|
-
settings: record(string(), unknown()).readonly()
|
|
19320
|
-
}))), method(object({ steps: record(string(), object({
|
|
19321
|
-
modelId: string(),
|
|
19322
|
-
settings: record(string(), unknown()).readonly()
|
|
19323
|
-
})) }), object({ success: literal(true) }), {
|
|
19324
|
-
kind: "mutation",
|
|
19325
|
-
auth: "admin"
|
|
19326
|
-
}), method(object({ nodeId: string() }), object({
|
|
19327
|
-
success: literal(true),
|
|
19328
|
-
clearedDevices: number()
|
|
19329
|
-
}), {
|
|
19330
|
-
kind: "mutation",
|
|
19331
|
-
auth: "admin"
|
|
19332
|
-
}), method(object({ nodeId: string() }), object({ unhealthy: array(object({
|
|
19333
|
-
/** `<backend>:<device>`, e.g. `openvino:gpu`. */
|
|
19334
|
-
deviceKey: string(),
|
|
19335
|
-
/**
|
|
19336
|
-
* `failed` — the per-device restart budget is exhausted; no pool
|
|
19337
|
-
* will be spawned until an operator re-arms it or the runner
|
|
19338
|
-
* respawns. `backoff` — under budget, waiting out the backoff (or
|
|
19339
|
-
* a cached pool observed dead and not yet condemned).
|
|
19340
|
-
*/
|
|
19341
|
-
state: _enum(["failed", "backoff"]),
|
|
19342
|
-
/** Epoch ms of the death that produced this state. */
|
|
19343
|
-
since: number(),
|
|
19344
|
-
/** Pool deaths inside the current window. */
|
|
19345
|
-
deaths: number(),
|
|
19346
|
-
/** The last death's message. */
|
|
19347
|
-
lastError: string()
|
|
19348
|
-
})).readonly() })), method(object({
|
|
19349
|
-
nodeId: string(),
|
|
19350
|
-
deviceKey: string()
|
|
19351
|
-
}), object({ rearmed: boolean() }), {
|
|
19352
|
-
kind: "mutation",
|
|
19353
|
-
auth: "admin"
|
|
19354
|
-
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
19355
|
-
name: string(),
|
|
19356
|
-
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
19357
|
-
engine: PipelineEngineChoiceSchema
|
|
19358
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
|
|
19359
|
-
id: string(),
|
|
19360
|
-
name: string().optional(),
|
|
19361
|
-
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
19362
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
19363
|
-
addonId: string(),
|
|
19364
|
-
modelId: string(),
|
|
19365
|
-
format: ModelFormatSchema$1
|
|
19366
|
-
}), DownloadModelResultSchema, { kind: "mutation" }), method(object({
|
|
19367
|
-
addonId: string(),
|
|
19368
|
-
modelId: string(),
|
|
19369
|
-
format: ModelFormatSchema$1
|
|
19370
|
-
}), object({ success: literal(true) }), { kind: "mutation" }), method(object({
|
|
19371
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
19372
|
-
steps: array(PipelineStepInputSchema).min(1),
|
|
19373
|
-
frame: FrameInputSchema.optional(),
|
|
19374
|
-
/**
|
|
19375
|
-
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
19376
|
-
* in the same execution-group process; split/cross-node callers use
|
|
19377
|
-
* `frame`/`image` inline compatibility instead.
|
|
19378
|
-
*/
|
|
19379
|
-
frameRef: FrameRefSchema.optional(),
|
|
19380
|
-
/**
|
|
19381
|
-
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
19382
|
-
* the decoded pixels live in. One more member of the one-of
|
|
19383
|
-
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
19384
|
-
*/
|
|
19385
|
-
frameHandle: FrameHandleSchema.optional(),
|
|
19386
|
-
imageBase64: string().optional(),
|
|
19387
|
-
/**
|
|
19388
|
-
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
19389
|
-
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
19390
|
-
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
19391
|
-
* the detection-pipeline worker. Callers can pass either; exactly
|
|
19392
|
-
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
19393
|
-
*/
|
|
19394
|
-
image: _instanceof(Uint8Array).optional(),
|
|
19395
|
-
referenceImage: string().optional(),
|
|
19396
|
-
deviceId: number().optional(),
|
|
19397
|
-
sessionId: string().optional(),
|
|
19398
|
-
/**
|
|
19399
|
-
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
19400
|
-
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
19401
|
-
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
19402
|
-
* (inputClasses ≠ null) are skipped and served per-track via
|
|
19403
|
-
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
19404
|
-
*/
|
|
19405
|
-
plane: _enum(["full", "frame"]).optional(),
|
|
19406
|
-
/**
|
|
19407
|
-
* Inference-device selector (Phase 2 multi-device). Format
|
|
19408
|
-
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
19409
|
-
* Omitted ⇒ the runner's default device (current single-engine
|
|
19410
|
-
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
19411
|
-
*/
|
|
19412
|
-
deviceKey: string().optional(),
|
|
19413
|
-
/**
|
|
19414
|
-
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
19415
|
-
* when the parent crop was resolved from the frame's retained NATIVE
|
|
19416
|
-
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
19417
|
-
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
19418
|
-
* resolution from that surface — the SAME quality path faces already
|
|
19419
|
-
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
19420
|
-
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
19421
|
-
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
19422
|
-
* the executor's crop-normalized child ROI back into frame-normalized
|
|
19423
|
-
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
19424
|
-
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
19425
|
-
* (today's behaviour on the fallback path).
|
|
19426
|
-
*/
|
|
19427
|
-
nativeCropRef: NativeCropRefSchema.optional()
|
|
19428
|
-
}), PipelineRunResultBridge, { kind: "mutation" }), method(object({
|
|
19429
|
-
engine: PipelineEngineChoiceSchema.optional(),
|
|
19430
|
-
steps: array(PipelineStepInputSchema).min(1),
|
|
19431
|
-
frames: array(FrameInputSchema).min(1).max(255),
|
|
19432
|
-
deviceId: number().optional(),
|
|
19433
|
-
sessionId: string().optional(),
|
|
19434
|
-
/**
|
|
19435
|
-
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
19436
|
-
* the batch to the Python pool's bench preprocess cache
|
|
19437
|
-
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
19438
|
-
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
19439
|
-
* hit — the sustained-throughput run measures inference, not
|
|
19440
|
-
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
19441
|
-
* full preprocess every call, correct). Fresh per sustained run;
|
|
19442
|
-
* released via `uncacheFrame`.
|
|
19443
|
-
*/
|
|
19444
|
-
frameId: number().int().nonnegative().optional(),
|
|
19445
|
-
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
19446
|
-
deviceKey: string().optional()
|
|
19447
|
-
}), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
|
|
19448
|
-
data: _instanceof(Uint8Array),
|
|
19449
|
-
width: number().int().positive(),
|
|
19450
|
-
height: number().int().positive(),
|
|
19451
|
-
format: _enum([
|
|
19452
|
-
"rgb",
|
|
19453
|
-
"bgr",
|
|
19454
|
-
"gray"
|
|
19455
|
-
])
|
|
19456
|
-
}), object({
|
|
19457
|
-
frameId: number(),
|
|
19458
|
-
width: number(),
|
|
19459
|
-
height: number()
|
|
19460
|
-
}), { kind: "mutation" }), method(object({
|
|
19461
|
-
stepId: string(),
|
|
19462
|
-
frameId: number().int()
|
|
19463
|
-
}), record(string(), unknown()), { kind: "mutation" }), method(object({ frameId: number().int() }), _void(), { kind: "mutation" }), method(_void(), object({
|
|
19464
|
-
batchMode: string(),
|
|
19465
|
-
windowMs: number(),
|
|
19466
|
-
maxBatchSize: number(),
|
|
19467
|
-
concurrency: number()
|
|
19468
|
-
})), method(_void(), array(object({
|
|
19469
|
-
engineKey: string(),
|
|
19470
|
-
engine: PipelineEngineChoiceSchema,
|
|
19471
|
-
modelsLoaded: array(string()).readonly(),
|
|
19472
|
-
inUseByCameras: array(number()).readonly(),
|
|
19473
|
-
/**
|
|
19474
|
-
* Origin of this resident factory.
|
|
19475
|
-
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
19476
|
-
* - `warm-override` — benchmark/test override held in the warm
|
|
19477
|
-
* cache; auto-disposed after the idle TTL.
|
|
19478
|
-
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
19479
|
-
* multi-device, keyed by `deviceKey`) resolved
|
|
19480
|
-
* via `resolveDeviceFactory`. Runs alongside the
|
|
19481
|
-
* `runtime` engine on a DIFFERENT accelerator
|
|
19482
|
-
* (NPU / iGPU / Coral) — this is how the
|
|
19483
|
-
* Engines tab shows all pools running at once.
|
|
19484
|
-
*/
|
|
19485
|
-
kind: _enum([
|
|
19486
|
-
"runtime",
|
|
19487
|
-
"warm-override",
|
|
19488
|
-
"device-pool"
|
|
19489
|
-
]),
|
|
19490
|
-
/** Native pid of the underlying Python pool (null when no pool). */
|
|
19491
|
-
poolPid: number().nullable(),
|
|
19492
|
-
/** ms since this factory was last used (null when not warm-tracked). */
|
|
19493
|
-
idleMs: number().nullable(),
|
|
19494
|
-
/** Idle TTL after which `warm-override` factories self-evict (null when not applicable). */
|
|
19495
|
-
idleTtlMs: number().nullable()
|
|
19496
|
-
})).readonly()), method(object({ engine: PipelineEngineChoiceSchema }), object({ success: literal(true) }), {
|
|
19497
|
-
kind: "mutation",
|
|
19498
|
-
auth: "admin"
|
|
19499
|
-
}), method(object({
|
|
19500
|
-
engine: PipelineEngineChoiceSchema,
|
|
19501
|
-
force: boolean().optional()
|
|
19502
|
-
}), object({
|
|
19503
|
-
success: boolean(),
|
|
19504
|
-
reason: string().optional()
|
|
19505
|
-
}), {
|
|
19506
|
-
kind: "mutation",
|
|
19507
|
-
auth: "admin"
|
|
19508
|
-
}), method(_void(), array(ReferenceImageEntrySchema).readonly()), method(object({ filename: string() }), ReferenceImageBodySchema.nullable()), method(_void(), array(ReferenceAudioEntrySchema).readonly()), method(object({ filename: string() }), ReferenceAudioBodySchema.nullable()), method(_void(), AudioCapabilitiesSchema), method(object({
|
|
19509
|
-
addonId: string(),
|
|
19510
|
-
modelId: string(),
|
|
19511
|
-
filename: string().optional(),
|
|
19512
|
-
settings: record(string(), unknown()).optional()
|
|
19513
|
-
}), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
|
|
19514
|
-
/**
|
|
19515
|
-
* Per-stage gating mode applied to the zones a rule references.
|
|
19516
|
-
*
|
|
19517
|
-
* - `include`: the rule contributes to a **whitelist** for its stage.
|
|
19518
|
-
* When at least one `include` rule fires for a stage, only entities
|
|
19519
|
-
* inside one of those zones pass that stage.
|
|
19520
|
-
* - `exclude`: the rule contributes to a **blacklist** for its stage.
|
|
19521
|
-
* Entities inside one of those zones are dropped at that stage.
|
|
19522
|
-
*
|
|
19523
|
-
* `monitor`-style observation (count without filtering) is not a rule
|
|
19524
|
-
* mode — zones without any matching rule are observed naturally by
|
|
19525
|
-
* `zone-analytics` (live snapshot + history), so an "I just want to
|
|
19526
|
-
* count, not filter" use case needs no rule at all.
|
|
19527
|
-
*/
|
|
19528
|
-
var ZoneRuleModeEnum = _enum(["include", "exclude"]);
|
|
19529
|
-
/**
|
|
19530
|
-
* Per-consumer rule that references existing zones (geometry) and
|
|
19531
|
-
* defines how a specific pipeline stage should treat them. Each
|
|
19532
|
-
* consumer addon owns its own `ZoneRule[]` array in its per-device
|
|
19533
|
-
* settings:
|
|
19534
|
-
*
|
|
19535
|
-
* - `addon-motion-wasm` → `motionZoneRules: ZoneRule[]` (motion stage)
|
|
19536
|
-
* - `addon-detection-pipeline` → `detectionZoneRules: ZoneRule[]` (detection stage)
|
|
19537
|
-
* - future: notification rules, audio gating, etc.
|
|
19538
|
-
*
|
|
19539
|
-
* One rule applies to N zones (`zoneIds[]`) so the operator can
|
|
19540
|
-
* express "ignore motion in ALL of {garden, street}" with a single
|
|
19541
|
-
* rule. `classFilter` narrows the rule to specific object classes —
|
|
19542
|
-
* "drop person detections in the street, but keep cars" is one
|
|
19543
|
-
* `exclude` rule with `classFilter: ['person']`.
|
|
19544
|
-
*
|
|
19545
|
-
* `enabled` is a soft toggle — the operator can keep the rule
|
|
19546
|
-
* configured but inert without deleting it.
|
|
19547
|
-
*/
|
|
19548
|
-
var ZoneRuleSchema = object({
|
|
19549
|
-
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
19550
|
-
id: string(),
|
|
19551
|
-
/** Optional human-readable label rendered in the rule editor. */
|
|
19552
|
-
name: string().optional(),
|
|
19553
|
-
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
19554
|
-
* listed zones (OR-set: a detection in any one of them counts).
|
|
19555
|
-
* At least one zone id required — a rule with no targets is a
|
|
19556
|
-
* configuration mistake and the form validator rejects it. */
|
|
19557
|
-
zoneIds: array(string()).min(1).readonly(),
|
|
19558
|
-
mode: ZoneRuleModeEnum,
|
|
19559
|
-
/**
|
|
19560
|
-
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
19561
|
-
* applies to every class. Class strings match the `macroClass`
|
|
19562
|
-
* field on detections (e.g. `person`, `car`, `dog`).
|
|
19563
|
-
*/
|
|
19564
|
-
classFilter: array(string()).readonly().optional(),
|
|
19565
|
-
/**
|
|
19566
|
-
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
19567
|
-
* required to consider an entity "in the zone". Defaults to the
|
|
19568
|
-
* consumer's stage default when omitted. Kept for back-compat with
|
|
19569
|
-
* existing per-rule overrides; new operators pick the value via
|
|
19570
|
-
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
19571
|
-
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
19572
|
-
*/
|
|
19573
|
-
overlapThreshold: number().min(0).max(1).optional(),
|
|
19574
|
-
/**
|
|
19575
|
-
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
19576
|
-
* of the detection's bbox that must lie inside the zone for the
|
|
19577
|
-
* rule to match. Documented default is 85%; the engine substitutes
|
|
19578
|
-
* that when the field is omitted (kept optional so existing rules
|
|
19579
|
-
* stored without it stay valid).
|
|
19580
|
-
*
|
|
19581
|
-
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
19582
|
-
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
19583
|
-
* field exposed in the UI. Internally both feed the same gate.
|
|
19584
|
-
*/
|
|
19585
|
-
bboxInclusionPct: number().min(0).max(100).optional(),
|
|
19586
|
-
/**
|
|
19587
|
-
* When `true` and a detection has a segmentation mask, use the
|
|
19588
|
-
* mask for overlap instead of the bbox. Detection-stage only;
|
|
19589
|
-
* motion rules ignore this field.
|
|
19590
|
-
*/
|
|
19591
|
-
preferMask: boolean().optional(),
|
|
19592
|
-
/**
|
|
19593
|
-
* Soft-toggle: `false` disables the rule without deleting it.
|
|
19594
|
-
* Defaults to `true` so operators creating a rule via the UI
|
|
19595
|
-
* see it active immediately.
|
|
19596
|
-
*/
|
|
19597
|
-
enabled: boolean().default(true)
|
|
19598
|
-
});
|
|
19599
|
-
array(ZoneRuleSchema).readonly();
|
|
19600
|
-
/**
|
|
19601
|
-
* Zone — pure geometry + identity. NO filtering behaviour.
|
|
19602
|
-
*
|
|
19603
|
-
* Zones describe **where** in the frame the operator wants to flag
|
|
19604
|
-
* something; consumer-owned {@link ZoneRule} arrays describe **how**
|
|
19605
|
-
* each pipeline stage uses them. Splitting the two means a single
|
|
19606
|
-
* polygon "Driveway" can simultaneously back a motion-exclude rule,
|
|
19607
|
-
* a detection-include rule on `['car']`, and an occupancy aggregate
|
|
19608
|
-
* — without three duplicated polygons.
|
|
19609
|
-
*
|
|
19610
|
-
* Owned by the orchestrator addon (provider) and mirrored into the
|
|
19611
|
-
* `zones` device-state slice on every mutation. Consumers
|
|
19612
|
-
* (motion-wasm, pipeline-executor, analytics, admin UI) read either
|
|
19613
|
-
* via `api.zones.listZones` (one-shot) or via `dev.state.zones` (live
|
|
19614
|
-
* mirror with `onChanged`).
|
|
19615
|
-
*
|
|
19616
|
-
* Coordinates are normalised fractions of the frame (0–1) so zones
|
|
19617
|
-
* survive resolution changes and stream profile switches.
|
|
19618
|
-
*
|
|
19619
|
-
* `kind` discriminates between full polygons (closed regions used
|
|
19620
|
-
* for intrusion / occupancy filters) and tripwires (open 2-point
|
|
19621
|
-
* line segments used for cross events). Onboard / firmware-reported
|
|
19622
|
-
* zones (Reolink, ONVIF) are out of scope for now — see the deferred
|
|
19623
|
-
* task list.
|
|
19624
|
-
*/
|
|
19625
|
-
var ZoneKindEnum = _enum(["polygon", "tripwire"]);
|
|
19626
|
-
/** Polygon vertex in fraction-of-frame coordinates (0–1). */
|
|
19627
|
-
var PolygonPointSchema = object({
|
|
19628
|
-
x: number(),
|
|
19629
|
-
y: number()
|
|
19630
|
-
});
|
|
19631
|
-
/** A camera detection zone — pure geometry/identity. */
|
|
19632
|
-
var ZoneSchema = object({
|
|
19633
|
-
id: string(),
|
|
19634
|
-
name: string(),
|
|
19635
|
-
kind: ZoneKindEnum.default("polygon"),
|
|
19636
|
-
/** Polygon vertices, fraction of frame (0–1). */
|
|
19637
|
-
polygon: array(PolygonPointSchema).readonly(),
|
|
19638
|
-
/** Visual color for UI rendering. */
|
|
19639
|
-
color: string().default("#3b82f6")
|
|
19640
|
-
});
|
|
19641
|
-
DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).readonly()), method(object({
|
|
19642
|
-
deviceId: number(),
|
|
19643
|
-
zone: ZoneSchema
|
|
19644
|
-
}), _void(), {
|
|
19645
|
-
kind: "mutation",
|
|
19646
|
-
auth: "admin"
|
|
19647
|
-
}), method(object({
|
|
19648
|
-
deviceId: number(),
|
|
19649
|
-
zoneId: string()
|
|
19650
|
-
}), _void(), {
|
|
19651
|
-
kind: "mutation",
|
|
19652
|
-
auth: "admin"
|
|
19653
|
-
}), method(object({
|
|
19654
|
-
deviceId: number(),
|
|
19655
|
-
zone: ZoneSchema
|
|
19656
|
-
}), _void(), {
|
|
19657
|
-
kind: "mutation",
|
|
19658
|
-
auth: "admin"
|
|
19659
|
-
}), object({ zones: array(ZoneSchema).readonly() });
|
|
19660
|
-
/**
|
|
19661
19148
|
* pipeline-analytics — device-scoped wrapper cap. Refines raw
|
|
19662
19149
|
* per-frame detections emitted by the pipeline runner into tracked
|
|
19663
19150
|
* objects, per-kind event collections (motion / object / audio), and
|
|
@@ -20228,6 +19715,22 @@ var TrackSchema = object({
|
|
|
20228
19715
|
* omit it. Render nothing when absent.
|
|
20229
19716
|
*/
|
|
20230
19717
|
previewMissReason: string().optional(),
|
|
19718
|
+
/**
|
|
19719
|
+
* The ROOT model that produced this track — the `FrameResult.rootModelId` of
|
|
19720
|
+
* the frame it was BORN on (D646). What a later replay compares against, so
|
|
19721
|
+
* "the original model" is named rather than assumed. A birth fact: never
|
|
19722
|
+
* rewritten by a later frame. **Absent ≠ unknown-model**: a row from before
|
|
19723
|
+
* the column, and a track the camera's own detector produced, carry none.
|
|
19724
|
+
*/
|
|
19725
|
+
modelId: string().optional(),
|
|
19726
|
+
/**
|
|
19727
|
+
* Size (px) of the detection frame this track's `positions[].bbox` live in —
|
|
19728
|
+
* the frame it was born on, else the camera's latest analysis frame at
|
|
19729
|
+
* persist time. Divide a position by these to normalise it. Absent when the
|
|
19730
|
+
* size was never known.
|
|
19731
|
+
*/
|
|
19732
|
+
frameWidth: number().optional(),
|
|
19733
|
+
frameHeight: number().optional(),
|
|
20231
19734
|
...TrackFlagFields,
|
|
20232
19735
|
...TrackRetrainFields
|
|
20233
19736
|
});
|
|
@@ -21234,24 +20737,6 @@ var MediaReclaimStatusSchema = object({
|
|
|
21234
20737
|
finishedAtMs: number().nullable(),
|
|
21235
20738
|
error: string().nullable()
|
|
21236
20739
|
});
|
|
21237
|
-
var ReplayFrameInputSchema = object({
|
|
21238
|
-
timestamp: number(),
|
|
21239
|
-
frame: PipelineRunResultBridge
|
|
21240
|
-
});
|
|
21241
|
-
var RunReplayFrameProcessorResultSchema = object({ tracks: array(object({
|
|
21242
|
-
className: string(),
|
|
21243
|
-
firstSeenMs: number(),
|
|
21244
|
-
lastSeenMs: number(),
|
|
21245
|
-
/** Bbox of the track's FIRST matched detection, pixel-space in the clip's
|
|
21246
|
-
* frame — a representative box for the diff's `(className, window, IoU)`
|
|
21247
|
-
* pairing (`replay-diff.ts`). A replay does not need the full per-frame
|
|
21248
|
-
* trajectory production's `Track.positions` keeps. */
|
|
21249
|
-
bbox: BoundingBoxSchema,
|
|
21250
|
-
/** How many of the input frames this track matched a real detection on
|
|
21251
|
-
* (never a coasted/extrapolated frame) — the replay's own signal for "how
|
|
21252
|
-
* solid is this track", cheaper than re-deriving it from a trajectory. */
|
|
21253
|
-
framesMatched: number().int()
|
|
21254
|
-
})).readonly() });
|
|
21255
20740
|
/**
|
|
21256
20741
|
* The long-term series a camera produces. A closed union so a typo cannot
|
|
21257
20742
|
* invent one, and the ONE declaration of it — the addon's `AnalyticsLtsSeries`
|
|
@@ -21465,108 +20950,570 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21465
20950
|
}), {
|
|
21466
20951
|
kind: "mutation",
|
|
21467
20952
|
auth: "admin"
|
|
21468
|
-
}), method(object({ frameId: string() }), object({
|
|
21469
|
-
base64: string(),
|
|
21470
|
-
width: number().int(),
|
|
21471
|
-
height: number().int()
|
|
20953
|
+
}), method(object({ frameId: string() }), object({
|
|
20954
|
+
base64: string(),
|
|
20955
|
+
width: number().int(),
|
|
20956
|
+
height: number().int()
|
|
20957
|
+
}), {
|
|
20958
|
+
kind: "query",
|
|
20959
|
+
auth: "admin"
|
|
20960
|
+
}), method(object({
|
|
20961
|
+
deviceId: number(),
|
|
20962
|
+
trackId: string(),
|
|
20963
|
+
frameId: string(),
|
|
20964
|
+
subject: RetrainAssistSubjectSchema,
|
|
20965
|
+
/** Which node runs it. Absent ⇒ wherever an unowned call lands. */
|
|
20966
|
+
nodeId: string().optional()
|
|
20967
|
+
}), RetrainAssistResultSchema, {
|
|
20968
|
+
kind: "mutation",
|
|
20969
|
+
auth: "admin"
|
|
20970
|
+
}), method(object({ trackId: string() }), array(RetrainAnnotationSchema).readonly(), {
|
|
20971
|
+
kind: "query",
|
|
20972
|
+
auth: "admin"
|
|
20973
|
+
}), method(object({
|
|
20974
|
+
deviceId: number(),
|
|
20975
|
+
trackId: string(),
|
|
20976
|
+
frameId: string(),
|
|
20977
|
+
annotations: array(RetrainAnnotationDraftSchema)
|
|
20978
|
+
}), array(RetrainAnnotationSchema).readonly(), {
|
|
20979
|
+
kind: "mutation",
|
|
20980
|
+
auth: "admin"
|
|
20981
|
+
}), method(object({
|
|
20982
|
+
deviceId: number(),
|
|
20983
|
+
trackId: string()
|
|
20984
|
+
}), RetrainTransitionResultSchema, {
|
|
20985
|
+
kind: "mutation",
|
|
20986
|
+
auth: "admin"
|
|
20987
|
+
}), method(object({
|
|
20988
|
+
deviceId: number(),
|
|
20989
|
+
trackId: string()
|
|
20990
|
+
}), RetrainTransitionResultSchema, {
|
|
20991
|
+
kind: "mutation",
|
|
20992
|
+
auth: "admin"
|
|
20993
|
+
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
20994
|
+
kind: "query",
|
|
20995
|
+
auth: "admin"
|
|
20996
|
+
}), method(object({
|
|
20997
|
+
/** Which of the three event tables owns the row. */
|
|
20998
|
+
ownerType: EventOwnerTypeSchema,
|
|
20999
|
+
/** The event's rowid in that table (D474: an event id is a number). */
|
|
21000
|
+
eventId: number().int(),
|
|
21001
|
+
kind: MediaFileKindEnum.optional(),
|
|
21002
|
+
deviceId: number()
|
|
21003
|
+
}), array(MediaFileSchema).readonly()), method(object({
|
|
21004
|
+
trackId: string(),
|
|
21005
|
+
kinds: array(MediaFileKindEnum).optional(),
|
|
21006
|
+
deviceId: number()
|
|
21007
|
+
}), array(MediaFileSchema).readonly()), method(object({
|
|
21008
|
+
trackId: string(),
|
|
21009
|
+
deviceId: number()
|
|
21010
|
+
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21011
|
+
ownerType: EventOwnerTypeSchema,
|
|
21012
|
+
eventId: number().int(),
|
|
21013
|
+
deviceId: number()
|
|
21014
|
+
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21015
|
+
deviceId: number(),
|
|
21016
|
+
ownerKind: MediaPresenceOwnerKindSchema,
|
|
21017
|
+
ownerIds: array(string()).max(5e3)
|
|
21018
|
+
}), array(string()).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
|
|
21019
|
+
kind: "mutation",
|
|
21020
|
+
auth: "admin"
|
|
21021
|
+
}), method(RebuildObjectEmbeddingsInput, RebuildObjectEmbeddingsResultSchema, {
|
|
21022
|
+
kind: "mutation",
|
|
21023
|
+
auth: "admin"
|
|
21024
|
+
}), method(object({}), RebuildStatusSchema), object({
|
|
21025
|
+
deviceId: number(),
|
|
21026
|
+
timestamp: number(),
|
|
21027
|
+
frameWidth: number(),
|
|
21028
|
+
frameHeight: number(),
|
|
21029
|
+
detections: array(OverlayDetectionSchema).readonly()
|
|
21030
|
+
}), object({
|
|
21031
|
+
deviceId: number(),
|
|
21032
|
+
trackId: string(),
|
|
21033
|
+
className: string()
|
|
21034
|
+
}), object({
|
|
21035
|
+
deviceId: number(),
|
|
21036
|
+
trackId: string(),
|
|
21037
|
+
className: string(),
|
|
21038
|
+
durationMs: number()
|
|
21039
|
+
}), object({
|
|
21040
|
+
deviceId: number(),
|
|
21041
|
+
kind: EventKindSchema,
|
|
21042
|
+
eventId: string(),
|
|
21043
|
+
timestamp: number()
|
|
21044
|
+
});
|
|
21045
|
+
/**
|
|
21046
|
+
* Reference to the frame's retained NATIVE surface + the parent crop's placement
|
|
21047
|
+
* within the frame, so the executor can re-cut a leaf child ROI at native
|
|
21048
|
+
* resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
|
|
21049
|
+
*/
|
|
21050
|
+
var NativeCropRefSchema = object({
|
|
21051
|
+
/** Handle keying the retained native surface (node-pinned to its owner). */
|
|
21052
|
+
handle: FrameHandleSchema,
|
|
21053
|
+
/** The parent crop's padded/clamped rectangle in FRAME-space pixels. */
|
|
21054
|
+
cropFrameSpace: object({
|
|
21055
|
+
x: number(),
|
|
21056
|
+
y: number(),
|
|
21057
|
+
w: number(),
|
|
21058
|
+
h: number()
|
|
21059
|
+
})
|
|
21060
|
+
});
|
|
21061
|
+
object({
|
|
21062
|
+
crop: object({
|
|
21063
|
+
left: number(),
|
|
21064
|
+
top: number(),
|
|
21065
|
+
width: number().positive(),
|
|
21066
|
+
height: number().positive()
|
|
21067
|
+
}).optional(),
|
|
21068
|
+
content: object({
|
|
21069
|
+
width: number().int().positive(),
|
|
21070
|
+
height: number().int().positive()
|
|
21071
|
+
}),
|
|
21072
|
+
fit: _enum(["stretch", "contain"]),
|
|
21073
|
+
format: _enum([
|
|
21074
|
+
"rgb",
|
|
21075
|
+
"gray",
|
|
21076
|
+
"jpeg"
|
|
21077
|
+
])
|
|
21078
|
+
});
|
|
21079
|
+
/**
|
|
21080
|
+
* Process-local frame identity. It is serializable so it can ride an in-process
|
|
21081
|
+
* capability call, but `registryId` deliberately prevents resolution in any
|
|
21082
|
+
* other process or execution group.
|
|
21083
|
+
*/
|
|
21084
|
+
var FrameRefSchema = object({
|
|
21085
|
+
registryId: string().min(1),
|
|
21086
|
+
id: string().min(1),
|
|
21087
|
+
width: number().int().positive(),
|
|
21088
|
+
height: number().int().positive(),
|
|
21089
|
+
format: _enum(["rgb", "gray"]),
|
|
21090
|
+
timestamp: number(),
|
|
21091
|
+
capturedAt: number().optional()
|
|
21092
|
+
});
|
|
21093
|
+
var ModelFormatSchema$1 = _enum([
|
|
21094
|
+
"onnx",
|
|
21095
|
+
"coreml",
|
|
21096
|
+
"openvino",
|
|
21097
|
+
"tflite",
|
|
21098
|
+
"pt",
|
|
21099
|
+
"gguf"
|
|
21100
|
+
]);
|
|
21101
|
+
var PipelineSlotSchema = _enum([
|
|
21102
|
+
"detector",
|
|
21103
|
+
"cropper",
|
|
21104
|
+
"classifier",
|
|
21105
|
+
"refiner",
|
|
21106
|
+
"audio-classifier"
|
|
21107
|
+
]);
|
|
21108
|
+
var PipelineEngineChoiceSchema = object({
|
|
21109
|
+
runtime: literal("python"),
|
|
21110
|
+
backend: string(),
|
|
21111
|
+
format: ModelFormatSchema$1,
|
|
21112
|
+
device: string().optional()
|
|
21113
|
+
});
|
|
21114
|
+
/**
|
|
21115
|
+
* One pool's resolved provisioning (`getEffectiveTuning`). `numWorkers` is the
|
|
21116
|
+
* knob that lifts a saturated pool (`inference-devices.md`); `concurrency` is
|
|
21117
|
+
* per-worker in-flight requests. `deviceKey` echoes the pool asked about —
|
|
21118
|
+
* `null` for the node-default pool.
|
|
21119
|
+
*/
|
|
21120
|
+
var EffectiveTuningSchema = object({
|
|
21121
|
+
deviceKey: string().nullable(),
|
|
21122
|
+
runtime: string(),
|
|
21123
|
+
batchMode: string(),
|
|
21124
|
+
windowMs: number(),
|
|
21125
|
+
maxBatchSize: number(),
|
|
21126
|
+
concurrency: number(),
|
|
21127
|
+
numWorkers: number()
|
|
21128
|
+
});
|
|
21129
|
+
var AvailableEngineSchema = object({
|
|
21130
|
+
engine: PipelineEngineChoiceSchema,
|
|
21131
|
+
devices: array(object({
|
|
21132
|
+
id: string(),
|
|
21133
|
+
label: string(),
|
|
21134
|
+
description: string().optional()
|
|
21135
|
+
})).readonly(),
|
|
21136
|
+
defaultDevice: string()
|
|
21137
|
+
});
|
|
21138
|
+
var PipelineDefaultStepSchema = lazy(() => object({
|
|
21139
|
+
addonId: string(),
|
|
21140
|
+
addonName: string(),
|
|
21141
|
+
slot: PipelineSlotSchema,
|
|
21142
|
+
inputClasses: array(string()).readonly(),
|
|
21143
|
+
outputClasses: array(string()).readonly(),
|
|
21144
|
+
enabled: boolean(),
|
|
21145
|
+
modelId: string(),
|
|
21146
|
+
children: array(PipelineDefaultStepSchema).readonly(),
|
|
21147
|
+
group: string().optional(),
|
|
21148
|
+
settings: record(string(), unknown()).optional()
|
|
21149
|
+
}));
|
|
21150
|
+
var PipelineTemplateStepSchema = lazy(() => object({
|
|
21151
|
+
addonId: string(),
|
|
21152
|
+
enabled: boolean(),
|
|
21153
|
+
modelId: string(),
|
|
21154
|
+
children: array(PipelineTemplateStepSchema).readonly(),
|
|
21155
|
+
settings: record(string(), unknown()).optional()
|
|
21156
|
+
}));
|
|
21157
|
+
var PipelineTemplateSchema$1 = object({
|
|
21158
|
+
id: string(),
|
|
21159
|
+
name: string(),
|
|
21160
|
+
createdAt: string(),
|
|
21161
|
+
updatedAt: string(),
|
|
21162
|
+
engine: PipelineEngineChoiceSchema,
|
|
21163
|
+
steps: array(PipelineTemplateStepSchema).readonly()
|
|
21164
|
+
});
|
|
21165
|
+
var PipelineModelOptionSchema = object({
|
|
21166
|
+
id: string(),
|
|
21167
|
+
name: string(),
|
|
21168
|
+
formats: record(string(), object({
|
|
21169
|
+
downloaded: boolean(),
|
|
21170
|
+
sizeMB: number()
|
|
21171
|
+
})),
|
|
21172
|
+
group: ModelVariantGroupSchema.optional(),
|
|
21173
|
+
legacy: boolean().optional(),
|
|
21174
|
+
provider: ModelProviderIdSchema.optional()
|
|
21175
|
+
});
|
|
21176
|
+
var ConfigFieldBridge = custom();
|
|
21177
|
+
var PipelineAddonSchemaSchema = object({
|
|
21178
|
+
id: string(),
|
|
21179
|
+
name: string(),
|
|
21180
|
+
slot: PipelineSlotSchema,
|
|
21181
|
+
inputClasses: array(string()).readonly(),
|
|
21182
|
+
outputClasses: array(string()).readonly(),
|
|
21183
|
+
childSlots: array(PipelineSlotSchema).readonly(),
|
|
21184
|
+
models: array(PipelineModelOptionSchema).readonly(),
|
|
21185
|
+
defaultModelId: string(),
|
|
21186
|
+
defaultModelIdByFormat: record(string(), string()).optional(),
|
|
21187
|
+
enabledByDefault: boolean().optional(),
|
|
21188
|
+
backfillIntoExistingOverrides: boolean().optional(),
|
|
21189
|
+
defaultConfidence: number(),
|
|
21190
|
+
group: string().optional(),
|
|
21191
|
+
configSchema: array(ConfigFieldBridge).readonly().optional()
|
|
21192
|
+
});
|
|
21193
|
+
var PipelineSlotSchemaSchema = object({
|
|
21194
|
+
id: PipelineSlotSchema,
|
|
21195
|
+
label: string(),
|
|
21196
|
+
priority: number(),
|
|
21197
|
+
parentSlot: PipelineSlotSchema.nullable(),
|
|
21198
|
+
addons: array(PipelineAddonSchemaSchema).readonly()
|
|
21199
|
+
});
|
|
21200
|
+
var PipelineSchemaSchema = object({
|
|
21201
|
+
availableEngines: array(AvailableEngineSchema).readonly(),
|
|
21202
|
+
selectedEngine: PipelineEngineChoiceSchema,
|
|
21203
|
+
slots: array(PipelineSlotSchemaSchema).readonly()
|
|
21204
|
+
});
|
|
21205
|
+
var EngineProvisioningSchema = object({
|
|
21206
|
+
runtimeId: _enum([
|
|
21207
|
+
"onnx",
|
|
21208
|
+
"openvino",
|
|
21209
|
+
"coreml",
|
|
21210
|
+
"edgetpu"
|
|
21211
|
+
]).nullable(),
|
|
21212
|
+
device: string().nullable(),
|
|
21213
|
+
state: _enum([
|
|
21214
|
+
"idle",
|
|
21215
|
+
"installing",
|
|
21216
|
+
"verifying",
|
|
21217
|
+
"ready",
|
|
21218
|
+
"failed"
|
|
21219
|
+
]),
|
|
21220
|
+
progress: number().optional(),
|
|
21221
|
+
error: string().optional(),
|
|
21222
|
+
nextRetryAt: number().optional(),
|
|
21223
|
+
/**
|
|
21224
|
+
* Gate A (config-correctness gate at engine change): human-readable
|
|
21225
|
+
* config issues surfaced EAGERLY when the node's engine changes — model
|
|
21226
|
+
* substitutions ("chose X, running Y") and zero-build steps ("no model
|
|
21227
|
+
* has a <format> build"). Additive/optional: informational only, never
|
|
21228
|
+
* enforced here — `assertEngineReady` (readiness) still gates inference.
|
|
21229
|
+
* Absent/empty when the node-default tree resolves cleanly.
|
|
21230
|
+
*/
|
|
21231
|
+
configIssues: array(string()).optional()
|
|
21232
|
+
});
|
|
21233
|
+
var PipelineStepInputSchema = lazy(() => object({
|
|
21234
|
+
addonId: string(),
|
|
21235
|
+
modelId: string().optional(),
|
|
21236
|
+
enabled: boolean().default(true),
|
|
21237
|
+
children: array(PipelineStepInputSchema).optional(),
|
|
21238
|
+
settings: record(string(), unknown()).optional(),
|
|
21239
|
+
jumpDeviceKey: string().optional()
|
|
21240
|
+
}));
|
|
21241
|
+
var ModelSubstitutionSchema = object({
|
|
21242
|
+
addonId: string(),
|
|
21243
|
+
chosen: string(),
|
|
21244
|
+
running: string(),
|
|
21245
|
+
format: string()
|
|
21246
|
+
});
|
|
21247
|
+
var PipelineValidationIssueSchema = object({
|
|
21248
|
+
addonId: string(),
|
|
21249
|
+
kind: _enum([
|
|
21250
|
+
"unknown-addon",
|
|
21251
|
+
"no-format-build",
|
|
21252
|
+
"unknown-device"
|
|
21253
|
+
]),
|
|
21254
|
+
detail: string()
|
|
21255
|
+
});
|
|
21256
|
+
var PipelineValidationResultSchema = object({
|
|
21257
|
+
ok: boolean(),
|
|
21258
|
+
issues: array(PipelineValidationIssueSchema).readonly(),
|
|
21259
|
+
substitutions: array(ModelSubstitutionSchema).readonly(),
|
|
21260
|
+
/** The node's `currentEngine.format` this validation ran against. */
|
|
21261
|
+
format: string()
|
|
21262
|
+
});
|
|
21263
|
+
var ReferenceImageEntrySchema = object({
|
|
21264
|
+
filename: string(),
|
|
21265
|
+
stepIds: array(string()).readonly().optional()
|
|
21266
|
+
});
|
|
21267
|
+
var ReferenceImageBodySchema = object({
|
|
21268
|
+
base64: string(),
|
|
21269
|
+
filename: string()
|
|
21270
|
+
});
|
|
21271
|
+
var ReferenceAudioEntrySchema = object({
|
|
21272
|
+
filename: string(),
|
|
21273
|
+
sizeKb: number()
|
|
21274
|
+
});
|
|
21275
|
+
var ReferenceAudioBodySchema = object({ base64: string() });
|
|
21276
|
+
var AudioBackendSchema = object({
|
|
21277
|
+
id: string(),
|
|
21278
|
+
name: string(),
|
|
21279
|
+
description: string(),
|
|
21280
|
+
available: boolean(),
|
|
21281
|
+
/**
|
|
21282
|
+
* Raw classifier labels this backend can emit (e.g. YAMNet's
|
|
21283
|
+
* 521-class set or Apple SoundAnalysis's 303-class set). Used by
|
|
21284
|
+
* the benchmark UI to populate the `enabledMicroClasses` filter
|
|
21285
|
+
* specific to the selected backend without a separate fetch.
|
|
21286
|
+
*/
|
|
21287
|
+
rawLabels: array(string()).readonly().optional()
|
|
21288
|
+
});
|
|
21289
|
+
var AudioCapabilitiesSchema = object({
|
|
21290
|
+
activeBackend: string(),
|
|
21291
|
+
availableBackends: array(AudioBackendSchema).readonly(),
|
|
21292
|
+
sampleRate: number(),
|
|
21293
|
+
chunkDurationMs: number()
|
|
21294
|
+
});
|
|
21295
|
+
var DownloadModelResultSchema = object({
|
|
21296
|
+
filePath: string(),
|
|
21297
|
+
sizeMB: number(),
|
|
21298
|
+
durationMs: number()
|
|
21299
|
+
});
|
|
21300
|
+
/**
|
|
21301
|
+
* Wrapper carrying a single test run's result. Replaces the legacy
|
|
21302
|
+
* ad-hoc `{labels: [{className, originalClass, score}]}` shape with the
|
|
21303
|
+
* canonical `AudioResult` from the Phase 6 output rework: one
|
|
21304
|
+
* `AudioDetection` per class above `minScore`, top-N candidates in
|
|
21305
|
+
* `debug.alternateLabels['audio-classifier']`, per-source timings in
|
|
21306
|
+
* `debug.stepTimings`. The outer `success`/`error` fields stay so the
|
|
21307
|
+
* benchmark UI can still report a clean failure when the classifier
|
|
21308
|
+
* cap isn't available.
|
|
21309
|
+
*/
|
|
21310
|
+
var AudioTestResultSchema = object({
|
|
21311
|
+
success: boolean(),
|
|
21312
|
+
error: string().optional(),
|
|
21313
|
+
frame: custom().optional()
|
|
21314
|
+
});
|
|
21315
|
+
var PipelineConfigBridge = custom();
|
|
21316
|
+
var ConfigUISchemaBridge = custom();
|
|
21317
|
+
var ConfigUISchemaNullableBridge = custom();
|
|
21318
|
+
var InferenceCapabilitiesBridge = custom();
|
|
21319
|
+
var ModelAvailabilityListBridge = custom();
|
|
21320
|
+
var PipelineRunResultBridge = custom();
|
|
21321
|
+
method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngineChoiceSchema), method(PipelineEngineChoiceSchema, array(PipelineDefaultStepSchema)), method(object({ nodeId: string() }), EngineProvisioningSchema), method(_void(), record(string(), object({
|
|
21322
|
+
modelId: string(),
|
|
21323
|
+
settings: record(string(), unknown()).readonly()
|
|
21324
|
+
}))), method(object({ steps: record(string(), object({
|
|
21325
|
+
modelId: string(),
|
|
21326
|
+
settings: record(string(), unknown()).readonly()
|
|
21327
|
+
})) }), object({ success: literal(true) }), {
|
|
21328
|
+
kind: "mutation",
|
|
21329
|
+
auth: "admin"
|
|
21330
|
+
}), method(object({ nodeId: string() }), object({
|
|
21331
|
+
success: literal(true),
|
|
21332
|
+
clearedDevices: number()
|
|
21472
21333
|
}), {
|
|
21473
|
-
kind: "query",
|
|
21474
|
-
auth: "admin"
|
|
21475
|
-
}), method(object({
|
|
21476
|
-
deviceId: number(),
|
|
21477
|
-
trackId: string(),
|
|
21478
|
-
frameId: string(),
|
|
21479
|
-
subject: RetrainAssistSubjectSchema,
|
|
21480
|
-
/** Which node runs it. Absent ⇒ wherever an unowned call lands. */
|
|
21481
|
-
nodeId: string().optional()
|
|
21482
|
-
}), RetrainAssistResultSchema, {
|
|
21483
|
-
kind: "mutation",
|
|
21484
|
-
auth: "admin"
|
|
21485
|
-
}), method(object({
|
|
21486
|
-
deviceId: number(),
|
|
21487
|
-
source: DetectionSourceSchema,
|
|
21488
|
-
zones: array(ZoneSchema).readonly().optional(),
|
|
21489
|
-
detectionRules: array(ZoneRuleSchema).readonly().optional(),
|
|
21490
|
-
zoneMembershipMinOverlap: number().min(0).max(1).optional(),
|
|
21491
|
-
frames: array(ReplayFrameInputSchema).min(1)
|
|
21492
|
-
}), RunReplayFrameProcessorResultSchema, {
|
|
21493
|
-
kind: "mutation",
|
|
21494
|
-
auth: "admin"
|
|
21495
|
-
}), method(object({ trackId: string() }), array(RetrainAnnotationSchema).readonly(), {
|
|
21496
|
-
kind: "query",
|
|
21497
|
-
auth: "admin"
|
|
21498
|
-
}), method(object({
|
|
21499
|
-
deviceId: number(),
|
|
21500
|
-
trackId: string(),
|
|
21501
|
-
frameId: string(),
|
|
21502
|
-
annotations: array(RetrainAnnotationDraftSchema)
|
|
21503
|
-
}), array(RetrainAnnotationSchema).readonly(), {
|
|
21504
21334
|
kind: "mutation",
|
|
21505
21335
|
auth: "admin"
|
|
21506
|
-
}), method(object({
|
|
21507
|
-
|
|
21508
|
-
|
|
21509
|
-
|
|
21336
|
+
}), method(object({ nodeId: string() }), object({ unhealthy: array(object({
|
|
21337
|
+
/** `<backend>:<device>`, e.g. `openvino:gpu`. */
|
|
21338
|
+
deviceKey: string(),
|
|
21339
|
+
/**
|
|
21340
|
+
* `failed` — the per-device restart budget is exhausted; no pool
|
|
21341
|
+
* will be spawned until an operator re-arms it or the runner
|
|
21342
|
+
* respawns. `backoff` — under budget, waiting out the backoff (or
|
|
21343
|
+
* a cached pool observed dead and not yet condemned).
|
|
21344
|
+
*/
|
|
21345
|
+
state: _enum(["failed", "backoff"]),
|
|
21346
|
+
/** Epoch ms of the death that produced this state. */
|
|
21347
|
+
since: number(),
|
|
21348
|
+
/** Pool deaths inside the current window. */
|
|
21349
|
+
deaths: number(),
|
|
21350
|
+
/** The last death's message. */
|
|
21351
|
+
lastError: string()
|
|
21352
|
+
})).readonly() })), method(object({
|
|
21353
|
+
nodeId: string(),
|
|
21354
|
+
deviceKey: string()
|
|
21355
|
+
}), object({ rearmed: boolean() }), {
|
|
21510
21356
|
kind: "mutation",
|
|
21511
21357
|
auth: "admin"
|
|
21512
|
-
}), method(object({
|
|
21513
|
-
|
|
21514
|
-
|
|
21515
|
-
}),
|
|
21358
|
+
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
|
|
21359
|
+
steps: array(PipelineStepInputSchema),
|
|
21360
|
+
deviceKey: string().optional()
|
|
21361
|
+
}), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
21362
|
+
name: string(),
|
|
21363
|
+
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
21364
|
+
engine: PipelineEngineChoiceSchema
|
|
21365
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
|
|
21366
|
+
id: string(),
|
|
21367
|
+
name: string().optional(),
|
|
21368
|
+
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
21369
|
+
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
21370
|
+
addonId: string(),
|
|
21371
|
+
modelId: string(),
|
|
21372
|
+
format: ModelFormatSchema$1
|
|
21373
|
+
}), DownloadModelResultSchema, { kind: "mutation" }), method(object({
|
|
21374
|
+
addonId: string(),
|
|
21375
|
+
modelId: string(),
|
|
21376
|
+
format: ModelFormatSchema$1
|
|
21377
|
+
}), object({ success: literal(true) }), { kind: "mutation" }), method(object({
|
|
21378
|
+
steps: array(PipelineStepInputSchema).min(1),
|
|
21379
|
+
frame: FrameInputSchema.optional(),
|
|
21380
|
+
/**
|
|
21381
|
+
* Process-local lazy frame. Valid only when caller and provider resolve
|
|
21382
|
+
* in the same execution-group process; split/cross-node callers use
|
|
21383
|
+
* `frame`/`image` inline compatibility instead.
|
|
21384
|
+
*/
|
|
21385
|
+
frameRef: FrameRefSchema.optional(),
|
|
21386
|
+
/**
|
|
21387
|
+
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
21388
|
+
* the decoded pixels live in. One more member of the one-of
|
|
21389
|
+
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
21390
|
+
*/
|
|
21391
|
+
frameHandle: FrameHandleSchema.optional(),
|
|
21392
|
+
imageBase64: string().optional(),
|
|
21393
|
+
/**
|
|
21394
|
+
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
21395
|
+
* hops (hub → forked worker via Moleculer MsgPack) because it
|
|
21396
|
+
* skips the 33% base64 overhead + the per-call base64 decode on
|
|
21397
|
+
* the detection-pipeline worker. Callers can pass either; exactly
|
|
21398
|
+
* one of `frame`/`image`/`imageBase64`/`referenceImage` is required.
|
|
21399
|
+
*/
|
|
21400
|
+
image: _instanceof(Uint8Array).optional(),
|
|
21401
|
+
referenceImage: string().optional(),
|
|
21402
|
+
deviceId: number().optional(),
|
|
21403
|
+
sessionId: string().optional(),
|
|
21404
|
+
/**
|
|
21405
|
+
* Execution plane. 'full' (default) runs the whole tree — benchmark,
|
|
21406
|
+
* reference-image, and detail-subtree calls. 'frame' is the live
|
|
21407
|
+
* per-frame dispatch: ONLY root-plane steps run; crop children
|
|
21408
|
+
* (inputClasses ≠ null) are skipped and served per-track via
|
|
21409
|
+
* pipelineRunner.runDetailSubtree (two-plane design).
|
|
21410
|
+
*/
|
|
21411
|
+
plane: _enum(["full", "frame"]).optional(),
|
|
21412
|
+
/**
|
|
21413
|
+
* Inference-device selector (Phase 2 multi-device). Format
|
|
21414
|
+
* `<backend>:<device>` (e.g. `openvino:gpu`, `edgetpu:usb`, `cpu`).
|
|
21415
|
+
* Omitted ⇒ the runner's default device (current single-engine
|
|
21416
|
+
* behaviour). Selects WHICH device pool of the node runs the call.
|
|
21417
|
+
*/
|
|
21418
|
+
deviceKey: string().optional(),
|
|
21419
|
+
/**
|
|
21420
|
+
* Two-plane NATIVE child-crop reference. Set by `runDetailSubtree` ONLY
|
|
21421
|
+
* when the parent crop was resolved from the frame's retained NATIVE
|
|
21422
|
+
* surface (a frameHandle HIT). Lets the executor re-cut a LEAF crop
|
|
21423
|
+
* child's ROI (plate-ocr, face-embedding, leaf classifiers) at native
|
|
21424
|
+
* resolution from that surface — the SAME quality path faces already
|
|
21425
|
+
* had — instead of the downscaled parent tile. `handle` keys the native
|
|
21426
|
+
* surface (node-pinned to its owner); `cropFrameSpace` is the parent
|
|
21427
|
+
* crop's padded/clamped rectangle in FRAME-space pixels, used to compose
|
|
21428
|
+
* the executor's crop-normalized child ROI back into frame-normalized
|
|
21429
|
+
* coordinates. Auxiliary to the image source (`image`/`frame`/…), NOT one
|
|
21430
|
+
* of the mutually-exclusive image inputs. Absent ⇒ tile-crop children
|
|
21431
|
+
* (today's behaviour on the fallback path).
|
|
21432
|
+
*/
|
|
21433
|
+
nativeCropRef: NativeCropRefSchema.optional(),
|
|
21434
|
+
/**
|
|
21435
|
+
* Offline REPLAY of stored media for `deviceId` (D56, D646): the
|
|
21436
|
+
* camera's zone gate and overrides apply as live, every executing
|
|
21437
|
+
* step runs EXACTLY the model it names on the `deviceKey` pool it
|
|
21438
|
+
* names or the call refuses (`model-not-servable` /
|
|
21439
|
+
* `device-not-servable`), and nothing reaches the camera's live
|
|
21440
|
+
* trace stream. Absent ⇒ unchanged behaviour.
|
|
21441
|
+
*/
|
|
21442
|
+
replay: literal(true).optional()
|
|
21443
|
+
}), PipelineRunResultBridge, { kind: "mutation" }), method(object({
|
|
21444
|
+
steps: array(PipelineStepInputSchema).min(1),
|
|
21445
|
+
frames: array(FrameInputSchema).min(1).max(255),
|
|
21446
|
+
deviceId: number().optional(),
|
|
21447
|
+
sessionId: string().optional(),
|
|
21448
|
+
/**
|
|
21449
|
+
* Pure-inference benchmark hint. A NONZERO uint32 pins every frame in
|
|
21450
|
+
* the batch to the Python pool's bench preprocess cache
|
|
21451
|
+
* (`_bench_frame_id`) so a REPEATED benchmark frame is decoded +
|
|
21452
|
+
* preprocessed ONCE and every later inference is a pure-inference cache
|
|
21453
|
+
* hit — the sustained-throughput run measures inference, not
|
|
21454
|
+
* decode+preprocess+infer. Omitted/0 for live frames (all different →
|
|
21455
|
+
* full preprocess every call, correct). Fresh per sustained run;
|
|
21456
|
+
* released via `uncacheFrame`.
|
|
21457
|
+
*/
|
|
21458
|
+
frameId: number().int().nonnegative().optional(),
|
|
21459
|
+
/** Inference-device selector (Phase 2 multi-device); see runPipeline. */
|
|
21460
|
+
deviceKey: string().optional()
|
|
21461
|
+
}), object({ results: array(PipelineRunResultBridge).readonly() }), { kind: "mutation" }), method(object({
|
|
21462
|
+
data: _instanceof(Uint8Array),
|
|
21463
|
+
width: number().int().positive(),
|
|
21464
|
+
height: number().int().positive(),
|
|
21465
|
+
format: _enum([
|
|
21466
|
+
"rgb",
|
|
21467
|
+
"bgr",
|
|
21468
|
+
"gray"
|
|
21469
|
+
])
|
|
21470
|
+
}), object({
|
|
21471
|
+
frameId: number(),
|
|
21472
|
+
width: number(),
|
|
21473
|
+
height: number()
|
|
21474
|
+
}), { kind: "mutation" }), method(object({
|
|
21475
|
+
stepId: string(),
|
|
21476
|
+
frameId: number().int()
|
|
21477
|
+
}), record(string(), unknown()), { kind: "mutation" }), method(object({ frameId: number().int() }), _void(), { kind: "mutation" }), method(object({ deviceKey: string().optional() }), EffectiveTuningSchema), method(_void(), array(object({
|
|
21478
|
+
engineKey: string(),
|
|
21479
|
+
engine: PipelineEngineChoiceSchema,
|
|
21480
|
+
modelsLoaded: array(string()).readonly(),
|
|
21481
|
+
inUseByCameras: array(number()).readonly(),
|
|
21482
|
+
/**
|
|
21483
|
+
* Origin of this resident factory.
|
|
21484
|
+
* - `runtime` — main camera-serving engine (no idle TTL).
|
|
21485
|
+
* - `device-pool` — a concurrent per-device pool (Phase 2
|
|
21486
|
+
* multi-device, keyed by `deviceKey`) resolved
|
|
21487
|
+
* via `resolveDeviceFactory`. Runs alongside the
|
|
21488
|
+
* `runtime` engine on a DIFFERENT accelerator
|
|
21489
|
+
* (NPU / iGPU / Coral) — this is how the
|
|
21490
|
+
* Engines tab shows all pools running at once.
|
|
21491
|
+
*/
|
|
21492
|
+
kind: _enum(["runtime", "device-pool"]),
|
|
21493
|
+
/** Native pid of the underlying Python pool (null when no pool). */
|
|
21494
|
+
poolPid: number().nullable(),
|
|
21495
|
+
/** ms since this factory was last used (null when not warm-tracked). */
|
|
21496
|
+
idleMs: number().nullable(),
|
|
21497
|
+
/** Idle TTL after which the factory self-evicts (null when not applicable). */
|
|
21498
|
+
idleTtlMs: number().nullable()
|
|
21499
|
+
})).readonly()), method(object({ engine: PipelineEngineChoiceSchema }), object({ success: literal(true) }), {
|
|
21516
21500
|
kind: "mutation",
|
|
21517
21501
|
auth: "admin"
|
|
21518
|
-
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
21519
|
-
kind: "query",
|
|
21520
|
-
auth: "admin"
|
|
21521
21502
|
}), method(object({
|
|
21522
|
-
|
|
21523
|
-
|
|
21524
|
-
|
|
21525
|
-
|
|
21526
|
-
|
|
21527
|
-
|
|
21528
|
-
}), array(MediaFileSchema).readonly()), method(object({
|
|
21529
|
-
trackId: string(),
|
|
21530
|
-
kinds: array(MediaFileKindEnum).optional(),
|
|
21531
|
-
deviceId: number()
|
|
21532
|
-
}), array(MediaFileSchema).readonly()), method(object({
|
|
21533
|
-
trackId: string(),
|
|
21534
|
-
deviceId: number()
|
|
21535
|
-
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21536
|
-
ownerType: EventOwnerTypeSchema,
|
|
21537
|
-
eventId: number().int(),
|
|
21538
|
-
deviceId: number()
|
|
21539
|
-
}), array(MediaFileInfoSchema).readonly()), method(object({
|
|
21540
|
-
deviceId: number(),
|
|
21541
|
-
ownerKind: MediaPresenceOwnerKindSchema,
|
|
21542
|
-
ownerIds: array(string()).max(5e3)
|
|
21543
|
-
}), array(string()).readonly()), method(SearchObjectEventsInput, array(ScoredObjectEventSchema).readonly()), method(object({}), WipeObjectEmbeddingsResultSchema, {
|
|
21544
|
-
kind: "mutation",
|
|
21545
|
-
auth: "admin"
|
|
21546
|
-
}), method(RebuildObjectEmbeddingsInput, RebuildObjectEmbeddingsResultSchema, {
|
|
21503
|
+
engine: PipelineEngineChoiceSchema,
|
|
21504
|
+
force: boolean().optional()
|
|
21505
|
+
}), object({
|
|
21506
|
+
success: boolean(),
|
|
21507
|
+
reason: string().optional()
|
|
21508
|
+
}), {
|
|
21547
21509
|
kind: "mutation",
|
|
21548
21510
|
auth: "admin"
|
|
21549
|
-
}), method(object({}),
|
|
21550
|
-
|
|
21551
|
-
|
|
21552
|
-
|
|
21553
|
-
|
|
21554
|
-
|
|
21555
|
-
}), object({
|
|
21556
|
-
deviceId: number(),
|
|
21557
|
-
trackId: string(),
|
|
21558
|
-
className: string()
|
|
21559
|
-
}), object({
|
|
21560
|
-
deviceId: number(),
|
|
21561
|
-
trackId: string(),
|
|
21562
|
-
className: string(),
|
|
21563
|
-
durationMs: number()
|
|
21564
|
-
}), object({
|
|
21565
|
-
deviceId: number(),
|
|
21566
|
-
kind: EventKindSchema,
|
|
21567
|
-
eventId: string(),
|
|
21568
|
-
timestamp: number()
|
|
21569
|
-
});
|
|
21511
|
+
}), method(_void(), array(ReferenceImageEntrySchema).readonly()), method(object({ filename: string() }), ReferenceImageBodySchema.nullable()), method(_void(), array(ReferenceAudioEntrySchema).readonly()), method(object({ filename: string() }), ReferenceAudioBodySchema.nullable()), method(_void(), AudioCapabilitiesSchema), method(object({
|
|
21512
|
+
addonId: string(),
|
|
21513
|
+
modelId: string(),
|
|
21514
|
+
filename: string().optional(),
|
|
21515
|
+
settings: record(string(), unknown()).optional()
|
|
21516
|
+
}), AudioTestResultSchema, { kind: "mutation" }), method(_void(), ConfigUISchemaNullableBridge);
|
|
21570
21517
|
object({
|
|
21571
21518
|
activeCameras: number(),
|
|
21572
21519
|
throttledCameras: number(),
|
|
@@ -21592,6 +21539,66 @@ var CameraMetricsSchema = object({
|
|
|
21592
21539
|
});
|
|
21593
21540
|
var CameraMetricsWithDeviceIdSchema = CameraMetricsSchema.extend({ deviceId: number() });
|
|
21594
21541
|
/**
|
|
21542
|
+
* Zone — pure geometry + identity. NO filtering behaviour.
|
|
21543
|
+
*
|
|
21544
|
+
* Zones describe **where** in the frame the operator wants to flag
|
|
21545
|
+
* something; consumer-owned {@link ZoneRule} arrays describe **how**
|
|
21546
|
+
* each pipeline stage uses them. Splitting the two means a single
|
|
21547
|
+
* polygon "Driveway" can simultaneously back a motion-exclude rule,
|
|
21548
|
+
* a detection-include rule on `['car']`, and an occupancy aggregate
|
|
21549
|
+
* — without three duplicated polygons.
|
|
21550
|
+
*
|
|
21551
|
+
* Owned by the orchestrator addon (provider) and mirrored into the
|
|
21552
|
+
* `zones` device-state slice on every mutation. Consumers
|
|
21553
|
+
* (motion-wasm, pipeline-executor, analytics, admin UI) read either
|
|
21554
|
+
* via `api.zones.listZones` (one-shot) or via `dev.state.zones` (live
|
|
21555
|
+
* mirror with `onChanged`).
|
|
21556
|
+
*
|
|
21557
|
+
* Coordinates are normalised fractions of the frame (0–1) so zones
|
|
21558
|
+
* survive resolution changes and stream profile switches.
|
|
21559
|
+
*
|
|
21560
|
+
* `kind` discriminates between full polygons (closed regions used
|
|
21561
|
+
* for intrusion / occupancy filters) and tripwires (open 2-point
|
|
21562
|
+
* line segments used for cross events). Onboard / firmware-reported
|
|
21563
|
+
* zones (Reolink, ONVIF) are out of scope for now — see the deferred
|
|
21564
|
+
* task list.
|
|
21565
|
+
*/
|
|
21566
|
+
var ZoneKindEnum = _enum(["polygon", "tripwire"]);
|
|
21567
|
+
/** Polygon vertex in fraction-of-frame coordinates (0–1). */
|
|
21568
|
+
var PolygonPointSchema = object({
|
|
21569
|
+
x: number(),
|
|
21570
|
+
y: number()
|
|
21571
|
+
});
|
|
21572
|
+
/** A camera detection zone — pure geometry/identity. */
|
|
21573
|
+
var ZoneSchema = object({
|
|
21574
|
+
id: string(),
|
|
21575
|
+
name: string(),
|
|
21576
|
+
kind: ZoneKindEnum.default("polygon"),
|
|
21577
|
+
/** Polygon vertices, fraction of frame (0–1). */
|
|
21578
|
+
polygon: array(PolygonPointSchema).readonly(),
|
|
21579
|
+
/** Visual color for UI rendering. */
|
|
21580
|
+
color: string().default("#3b82f6")
|
|
21581
|
+
});
|
|
21582
|
+
DeviceType.Camera, method(object({ deviceId: number() }), array(ZoneSchema).readonly()), method(object({
|
|
21583
|
+
deviceId: number(),
|
|
21584
|
+
zone: ZoneSchema
|
|
21585
|
+
}), _void(), {
|
|
21586
|
+
kind: "mutation",
|
|
21587
|
+
auth: "admin"
|
|
21588
|
+
}), method(object({
|
|
21589
|
+
deviceId: number(),
|
|
21590
|
+
zoneId: string()
|
|
21591
|
+
}), _void(), {
|
|
21592
|
+
kind: "mutation",
|
|
21593
|
+
auth: "admin"
|
|
21594
|
+
}), method(object({
|
|
21595
|
+
deviceId: number(),
|
|
21596
|
+
zone: ZoneSchema
|
|
21597
|
+
}), _void(), {
|
|
21598
|
+
kind: "mutation",
|
|
21599
|
+
auth: "admin"
|
|
21600
|
+
}), object({ zones: array(ZoneSchema).readonly() });
|
|
21601
|
+
/**
|
|
21595
21602
|
* A bounding box in NORMALIZED [0,1] frame coordinates for `getNativeCrop`. The
|
|
21596
21603
|
* decode worker resolves it against the RETAINED native frame's real pixel dims,
|
|
21597
21604
|
* so the caller supplies only the detection-res bbox divided by the detection
|
|
@@ -21778,7 +21785,17 @@ var DetailResultSchema = object({
|
|
|
21778
21785
|
/** Face short side (px) measured on the NATIVE crop surface. The `bbox`
|
|
21779
21786
|
* above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
|
|
21780
21787
|
* consumers MUST prefer this when present (2026-07-22 native-gate fix). */
|
|
21781
|
-
nativeFaceShortSidePx: number().optional()
|
|
21788
|
+
nativeFaceShortSidePx: number().optional(),
|
|
21789
|
+
/**
|
|
21790
|
+
* The five facial landmarks of a `face` detail, in the SAME frame space as
|
|
21791
|
+
* `bbox` (D644). Additive and optional: post-analysis stores them beside the
|
|
21792
|
+
* face's source frame so a future alignment can be re-derived exactly; a
|
|
21793
|
+
* runner that predates the field sends none and the face is stored without.
|
|
21794
|
+
*/
|
|
21795
|
+
landmarks: array(object({
|
|
21796
|
+
x: number(),
|
|
21797
|
+
y: number()
|
|
21798
|
+
})).optional()
|
|
21782
21799
|
});
|
|
21783
21800
|
/**
|
|
21784
21801
|
* Why an executing node REFUSED a stateless step run (`runStatelessStep`).
|
|
@@ -30103,7 +30120,7 @@ var HardwareInfoSchema = object({
|
|
|
30103
30120
|
coral: CoralInfoSchema.nullable().optional()
|
|
30104
30121
|
});
|
|
30105
30122
|
var PlatformScoreSchema = object({
|
|
30106
|
-
runtime:
|
|
30123
|
+
runtime: literal("python"),
|
|
30107
30124
|
backend: string(),
|
|
30108
30125
|
format: _enum([
|
|
30109
30126
|
"onnx",
|
|
@@ -30140,7 +30157,7 @@ var ModelRequirementSchema = object({
|
|
|
30140
30157
|
});
|
|
30141
30158
|
var ResolvedInferenceConfigSchema = object({
|
|
30142
30159
|
modelId: string(),
|
|
30143
|
-
runtime:
|
|
30160
|
+
runtime: literal("python"),
|
|
30144
30161
|
backend: string(),
|
|
30145
30162
|
format: ModelFormatSchema,
|
|
30146
30163
|
reason: string()
|
|
@@ -32347,6 +32364,92 @@ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSche
|
|
|
32347
32364
|
kind: "mutation",
|
|
32348
32365
|
auth: "admin"
|
|
32349
32366
|
});
|
|
32367
|
+
/**
|
|
32368
|
+
* Per-stage gating mode applied to the zones a rule references.
|
|
32369
|
+
*
|
|
32370
|
+
* - `include`: the rule contributes to a **whitelist** for its stage.
|
|
32371
|
+
* When at least one `include` rule fires for a stage, only entities
|
|
32372
|
+
* inside one of those zones pass that stage.
|
|
32373
|
+
* - `exclude`: the rule contributes to a **blacklist** for its stage.
|
|
32374
|
+
* Entities inside one of those zones are dropped at that stage.
|
|
32375
|
+
*
|
|
32376
|
+
* `monitor`-style observation (count without filtering) is not a rule
|
|
32377
|
+
* mode — zones without any matching rule are observed naturally by
|
|
32378
|
+
* `zone-analytics` (live snapshot + history), so an "I just want to
|
|
32379
|
+
* count, not filter" use case needs no rule at all.
|
|
32380
|
+
*/
|
|
32381
|
+
var ZoneRuleModeEnum = _enum(["include", "exclude"]);
|
|
32382
|
+
/**
|
|
32383
|
+
* Per-consumer rule that references existing zones (geometry) and
|
|
32384
|
+
* defines how a specific pipeline stage should treat them. Each
|
|
32385
|
+
* consumer addon owns its own `ZoneRule[]` array in its per-device
|
|
32386
|
+
* settings:
|
|
32387
|
+
*
|
|
32388
|
+
* - `addon-motion-wasm` → `motionZoneRules: ZoneRule[]` (motion stage)
|
|
32389
|
+
* - `addon-detection-pipeline` → `detectionZoneRules: ZoneRule[]` (detection stage)
|
|
32390
|
+
* - future: notification rules, audio gating, etc.
|
|
32391
|
+
*
|
|
32392
|
+
* One rule applies to N zones (`zoneIds[]`) so the operator can
|
|
32393
|
+
* express "ignore motion in ALL of {garden, street}" with a single
|
|
32394
|
+
* rule. `classFilter` narrows the rule to specific object classes —
|
|
32395
|
+
* "drop person detections in the street, but keep cars" is one
|
|
32396
|
+
* `exclude` rule with `classFilter: ['person']`.
|
|
32397
|
+
*
|
|
32398
|
+
* `enabled` is a soft toggle — the operator can keep the rule
|
|
32399
|
+
* configured but inert without deleting it.
|
|
32400
|
+
*/
|
|
32401
|
+
var ZoneRuleSchema = object({
|
|
32402
|
+
/** Stable rule id — survives edits, used by the UI for diffing. */
|
|
32403
|
+
id: string(),
|
|
32404
|
+
/** Optional human-readable label rendered in the rule editor. */
|
|
32405
|
+
name: string().optional(),
|
|
32406
|
+
/** Zones this rule targets. The rule's `mode` applies to ALL
|
|
32407
|
+
* listed zones (OR-set: a detection in any one of them counts).
|
|
32408
|
+
* At least one zone id required — a rule with no targets is a
|
|
32409
|
+
* configuration mistake and the form validator rejects it. */
|
|
32410
|
+
zoneIds: array(string()).min(1).readonly(),
|
|
32411
|
+
mode: ZoneRuleModeEnum,
|
|
32412
|
+
/**
|
|
32413
|
+
* Class names this rule applies to. Empty / undefined ⇒ rule
|
|
32414
|
+
* applies to every class. Class strings match the `macroClass`
|
|
32415
|
+
* field on detections (e.g. `person`, `car`, `dog`).
|
|
32416
|
+
*/
|
|
32417
|
+
classFilter: array(string()).readonly().optional(),
|
|
32418
|
+
/**
|
|
32419
|
+
* Minimum bbox/mask overlap (0–1) with any of the rule's zones
|
|
32420
|
+
* required to consider an entity "in the zone". Defaults to the
|
|
32421
|
+
* consumer's stage default when omitted. Kept for back-compat with
|
|
32422
|
+
* existing per-rule overrides; new operators pick the value via
|
|
32423
|
+
* `bboxInclusionPct` (operator-friendly 0–100). Whichever field is
|
|
32424
|
+
* set, the lower-level engine reads it as a 0–1 fraction.
|
|
32425
|
+
*/
|
|
32426
|
+
overlapThreshold: number().min(0).max(1).optional(),
|
|
32427
|
+
/**
|
|
32428
|
+
* Operator-friendly version of `overlapThreshold` — the percentage
|
|
32429
|
+
* of the detection's bbox that must lie inside the zone for the
|
|
32430
|
+
* rule to match. Documented default is 85%; the engine substitutes
|
|
32431
|
+
* that when the field is omitted (kept optional so existing rules
|
|
32432
|
+
* stored without it stay valid).
|
|
32433
|
+
*
|
|
32434
|
+
* When BOTH `overlapThreshold` and `bboxInclusionPct` are set on a
|
|
32435
|
+
* rule, the engine prefers `bboxInclusionPct` because it's the
|
|
32436
|
+
* field exposed in the UI. Internally both feed the same gate.
|
|
32437
|
+
*/
|
|
32438
|
+
bboxInclusionPct: number().min(0).max(100).optional(),
|
|
32439
|
+
/**
|
|
32440
|
+
* When `true` and a detection has a segmentation mask, use the
|
|
32441
|
+
* mask for overlap instead of the bbox. Detection-stage only;
|
|
32442
|
+
* motion rules ignore this field.
|
|
32443
|
+
*/
|
|
32444
|
+
preferMask: boolean().optional(),
|
|
32445
|
+
/**
|
|
32446
|
+
* Soft-toggle: `false` disables the rule without deleting it.
|
|
32447
|
+
* Defaults to `true` so operators creating a rule via the UI
|
|
32448
|
+
* see it active immediately.
|
|
32449
|
+
*/
|
|
32450
|
+
enabled: boolean().default(true)
|
|
32451
|
+
});
|
|
32452
|
+
array(ZoneRuleSchema).readonly();
|
|
32350
32453
|
object({
|
|
32351
32454
|
/** Whether the script is currently executing. */
|
|
32352
32455
|
isRunning: boolean(),
|
|
@@ -38699,6 +38802,12 @@ Object.freeze({
|
|
|
38699
38802
|
addonId: null,
|
|
38700
38803
|
access: "view"
|
|
38701
38804
|
},
|
|
38805
|
+
"notificationRules.previewStateSummary": {
|
|
38806
|
+
capName: "notification-rules",
|
|
38807
|
+
capScope: "system",
|
|
38808
|
+
addonId: null,
|
|
38809
|
+
access: "view"
|
|
38810
|
+
},
|
|
38702
38811
|
"notificationRules.previewTemplate": {
|
|
38703
38812
|
capName: "notification-rules",
|
|
38704
38813
|
capScope: "system",
|
|
@@ -39275,12 +39384,6 @@ Object.freeze({
|
|
|
39275
39384
|
addonId: null,
|
|
39276
39385
|
access: "create"
|
|
39277
39386
|
},
|
|
39278
|
-
"pipelineAnalytics.runReplayFrameProcessor": {
|
|
39279
|
-
capName: "pipeline-analytics",
|
|
39280
|
-
capScope: "device",
|
|
39281
|
-
addonId: null,
|
|
39282
|
-
access: "create"
|
|
39283
|
-
},
|
|
39284
39387
|
"pipelineAnalytics.saveRetrainAnnotations": {
|
|
39285
39388
|
capName: "pipeline-analytics",
|
|
39286
39389
|
capScope: "device",
|
|
@@ -43378,11 +43481,6 @@ Object.freeze({
|
|
|
43378
43481
|
form: "single",
|
|
43379
43482
|
optional: false
|
|
43380
43483
|
}],
|
|
43381
|
-
"pipelineAnalytics.runReplayFrameProcessor": [{
|
|
43382
|
-
name: "deviceId",
|
|
43383
|
-
form: "single",
|
|
43384
|
-
optional: false
|
|
43385
|
-
}],
|
|
43386
43484
|
"pipelineAnalytics.saveRetrainAnnotations": [{
|
|
43387
43485
|
name: "deviceId",
|
|
43388
43486
|
form: "single",
|
|
@@ -44362,6 +44460,98 @@ new Map(Object.entries({
|
|
|
44362
44460
|
"camera-enabled": null
|
|
44363
44461
|
}));
|
|
44364
44462
|
[...NC_SYSTEM_EVENT_FILTER_KEYS];
|
|
44463
|
+
var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
44464
|
+
{
|
|
44465
|
+
id: "device-state",
|
|
44466
|
+
family: "device-events",
|
|
44467
|
+
label: "Device state",
|
|
44468
|
+
kinds: [
|
|
44469
|
+
"device-offline",
|
|
44470
|
+
"device-online",
|
|
44471
|
+
"device-disabled",
|
|
44472
|
+
"device-enabled"
|
|
44473
|
+
]
|
|
44474
|
+
},
|
|
44475
|
+
{
|
|
44476
|
+
id: "streams",
|
|
44477
|
+
family: "device-events",
|
|
44478
|
+
label: "Streams",
|
|
44479
|
+
kinds: ["stream-offline", "stream-online"]
|
|
44480
|
+
},
|
|
44481
|
+
{
|
|
44482
|
+
id: "battery",
|
|
44483
|
+
family: "device-events",
|
|
44484
|
+
label: "Battery",
|
|
44485
|
+
kinds: ["device-battery-low", "device-battery-normal"]
|
|
44486
|
+
},
|
|
44487
|
+
{
|
|
44488
|
+
id: "consumables",
|
|
44489
|
+
family: "device-events",
|
|
44490
|
+
label: "Consumables",
|
|
44491
|
+
kinds: ["device-consumable-low", "device-consumable-normal"]
|
|
44492
|
+
},
|
|
44493
|
+
{
|
|
44494
|
+
id: "tanks",
|
|
44495
|
+
family: "device-events",
|
|
44496
|
+
label: "Tanks",
|
|
44497
|
+
kinds: [
|
|
44498
|
+
"device-tank-low",
|
|
44499
|
+
"device-tank-full",
|
|
44500
|
+
"device-tank-normal"
|
|
44501
|
+
]
|
|
44502
|
+
},
|
|
44503
|
+
{
|
|
44504
|
+
id: "detection-blind",
|
|
44505
|
+
family: "device-events",
|
|
44506
|
+
label: "Detecting nothing",
|
|
44507
|
+
kinds: ["detection-blind"]
|
|
44508
|
+
},
|
|
44509
|
+
{
|
|
44510
|
+
id: "nodes",
|
|
44511
|
+
family: "system",
|
|
44512
|
+
label: "Nodes",
|
|
44513
|
+
kinds: [
|
|
44514
|
+
"node-offline",
|
|
44515
|
+
"node-online",
|
|
44516
|
+
"node-inference-unavailable"
|
|
44517
|
+
]
|
|
44518
|
+
},
|
|
44519
|
+
{
|
|
44520
|
+
id: "addons",
|
|
44521
|
+
family: "system",
|
|
44522
|
+
label: "Addons",
|
|
44523
|
+
kinds: [
|
|
44524
|
+
"addon-crash-loop",
|
|
44525
|
+
"addon-update-available",
|
|
44526
|
+
"addon-updated"
|
|
44527
|
+
]
|
|
44528
|
+
},
|
|
44529
|
+
{
|
|
44530
|
+
id: "updates",
|
|
44531
|
+
family: "system",
|
|
44532
|
+
label: "Server & container updates",
|
|
44533
|
+
kinds: [
|
|
44534
|
+
"server-update-available",
|
|
44535
|
+
"server-updated",
|
|
44536
|
+
"wrapper-update-available"
|
|
44537
|
+
]
|
|
44538
|
+
},
|
|
44539
|
+
{
|
|
44540
|
+
id: "backups-exports",
|
|
44541
|
+
family: "system",
|
|
44542
|
+
label: "Backups & exports",
|
|
44543
|
+
kinds: ["backup-completed", "export-completed"]
|
|
44544
|
+
},
|
|
44545
|
+
{
|
|
44546
|
+
id: "alarm",
|
|
44547
|
+
family: "alarm",
|
|
44548
|
+
label: "Alarm",
|
|
44549
|
+
kinds: NC_ALARM_SYSTEM_EVENT_KINDS
|
|
44550
|
+
}
|
|
44551
|
+
];
|
|
44552
|
+
function systemEventKindsOfFamily(family) {
|
|
44553
|
+
return NC_SYSTEM_EVENT_KIND_GROUP_SPECS.filter((g) => g.family === family).flatMap((g) => g.kinds);
|
|
44554
|
+
}
|
|
44365
44555
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
44366
44556
|
/**
|
|
44367
44557
|
* WHICH WAY A BOOLEAN SENSOR MOVED — read off the one slice a sensor event
|
|
@@ -44436,7 +44626,183 @@ var DEVICE_EVENTS = [
|
|
|
44436
44626
|
"detection-blind",
|
|
44437
44627
|
...ALARM
|
|
44438
44628
|
];
|
|
44439
|
-
|
|
44629
|
+
/** Every kind a summary may speak about — the two summarisable families. */
|
|
44630
|
+
var SUMMARISABLE = [...systemEventKindsOfFamily("device-events"), ...systemEventKindsOfFamily("system")];
|
|
44631
|
+
/** One per summary SECTION (`NC_STATE_SUMMARY_SECTIONS` in the notification
|
|
44632
|
+
* centre): the section's lines, offered when one of its kinds is selected. */
|
|
44633
|
+
var STATE_SUMMARY_SECTION_VARS = [
|
|
44634
|
+
{
|
|
44635
|
+
name: "summaryDevices",
|
|
44636
|
+
label: "Summary: devices offline / switched off",
|
|
44637
|
+
example: "Garage — offline since 07:12",
|
|
44638
|
+
kinds: [
|
|
44639
|
+
"device-offline",
|
|
44640
|
+
"device-online",
|
|
44641
|
+
"device-disabled",
|
|
44642
|
+
"device-enabled"
|
|
44643
|
+
]
|
|
44644
|
+
},
|
|
44645
|
+
{
|
|
44646
|
+
name: "summaryStreams",
|
|
44647
|
+
label: "Summary: streams offline",
|
|
44648
|
+
example: "Ingresso (high) — since 06:40",
|
|
44649
|
+
kinds: ["stream-offline", "stream-online"]
|
|
44650
|
+
},
|
|
44651
|
+
{
|
|
44652
|
+
name: "summaryBattery",
|
|
44653
|
+
label: "Summary: low batteries",
|
|
44654
|
+
example: "Sensore porta — 8 %",
|
|
44655
|
+
kinds: BATTERY
|
|
44656
|
+
},
|
|
44657
|
+
{
|
|
44658
|
+
name: "summaryConsumables",
|
|
44659
|
+
label: "Summary: consumables",
|
|
44660
|
+
example: "Robot — filter 10 %",
|
|
44661
|
+
kinds: CONSUMABLE
|
|
44662
|
+
},
|
|
44663
|
+
{
|
|
44664
|
+
name: "summaryTanks",
|
|
44665
|
+
label: "Summary: tanks",
|
|
44666
|
+
example: "Robot — clean water low",
|
|
44667
|
+
kinds: TANK
|
|
44668
|
+
},
|
|
44669
|
+
{
|
|
44670
|
+
name: "summaryDetection",
|
|
44671
|
+
label: "Summary: cameras detecting nothing",
|
|
44672
|
+
example: "Ingresso — since 05:10",
|
|
44673
|
+
kinds: ["detection-blind"]
|
|
44674
|
+
},
|
|
44675
|
+
{
|
|
44676
|
+
name: "summaryNodes",
|
|
44677
|
+
label: "Summary: nodes",
|
|
44678
|
+
example: "little-unraid — offline since 03:00",
|
|
44679
|
+
kinds: [
|
|
44680
|
+
"node-offline",
|
|
44681
|
+
"node-online",
|
|
44682
|
+
"node-inference-unavailable"
|
|
44683
|
+
]
|
|
44684
|
+
},
|
|
44685
|
+
{
|
|
44686
|
+
name: "summaryAddons",
|
|
44687
|
+
label: "Summary: addons",
|
|
44688
|
+
example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
44689
|
+
kinds: [
|
|
44690
|
+
"addon-crash-loop",
|
|
44691
|
+
"addon-update-available",
|
|
44692
|
+
"addon-updated"
|
|
44693
|
+
]
|
|
44694
|
+
},
|
|
44695
|
+
{
|
|
44696
|
+
name: "summaryUpdates",
|
|
44697
|
+
label: "Summary: server & container updates",
|
|
44698
|
+
example: "server 1.2.377 → 1.2.378",
|
|
44699
|
+
kinds: [
|
|
44700
|
+
"server-update-available",
|
|
44701
|
+
"server-updated",
|
|
44702
|
+
"wrapper-update-available"
|
|
44703
|
+
]
|
|
44704
|
+
}
|
|
44705
|
+
];
|
|
44706
|
+
var STATE_SUMMARY_VARS = [
|
|
44707
|
+
{
|
|
44708
|
+
name: "summaryText",
|
|
44709
|
+
label: "Summary: every section",
|
|
44710
|
+
description: "One block per section with something to report, one line per item.",
|
|
44711
|
+
example: "Batterie scariche: Sensore porta — 8 %",
|
|
44712
|
+
group: "system",
|
|
44713
|
+
families: ["rule"],
|
|
44714
|
+
fields: [...RULE_TEXT],
|
|
44715
|
+
kinds: ["system"],
|
|
44716
|
+
systemEventKinds: [...SUMMARISABLE],
|
|
44717
|
+
systemEventDeliveries: ["summary"]
|
|
44718
|
+
},
|
|
44719
|
+
{
|
|
44720
|
+
name: "summaryCount",
|
|
44721
|
+
label: "Summary: items reported",
|
|
44722
|
+
example: "3",
|
|
44723
|
+
group: "system",
|
|
44724
|
+
families: ["rule"],
|
|
44725
|
+
fields: [...RULE_TEXT],
|
|
44726
|
+
kinds: ["system"],
|
|
44727
|
+
systemEventKinds: [...SUMMARISABLE],
|
|
44728
|
+
systemEventDeliveries: ["summary"]
|
|
44729
|
+
},
|
|
44730
|
+
...STATE_SUMMARY_SECTION_VARS.map((v) => ({
|
|
44731
|
+
name: v.name,
|
|
44732
|
+
label: v.label,
|
|
44733
|
+
example: v.example,
|
|
44734
|
+
group: "system",
|
|
44735
|
+
families: ["rule"],
|
|
44736
|
+
fields: [...RULE_TEXT],
|
|
44737
|
+
kinds: ["system"],
|
|
44738
|
+
systemEventKinds: [...v.kinds],
|
|
44739
|
+
systemEventDeliveries: ["summary"]
|
|
44740
|
+
}))
|
|
44741
|
+
];
|
|
44742
|
+
[
|
|
44743
|
+
[...DEVICE_EVENTS],
|
|
44744
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44745
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44746
|
+
[...RULE_TEXT],
|
|
44747
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44748
|
+
([...RULE_TEXT], [...PACKAGE_UPDATES]),
|
|
44749
|
+
[...RULE_TEXT],
|
|
44750
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44751
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44752
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
44753
|
+
[...RULE_TEXT],
|
|
44754
|
+
[...RULE_TEXT],
|
|
44755
|
+
[...RULE_TEXT],
|
|
44756
|
+
[...RULE_TEXT],
|
|
44757
|
+
[...RULE_TEXT],
|
|
44758
|
+
[...RULE_TEXT],
|
|
44759
|
+
[...RULE_TEXT],
|
|
44760
|
+
[...RULE_TEXT],
|
|
44761
|
+
[...RULE_BODY_ONLY],
|
|
44762
|
+
[...RULE_TEXT],
|
|
44763
|
+
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
44764
|
+
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
44765
|
+
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
44766
|
+
([...RULE_TEXT], [...CONSUMABLE]),
|
|
44767
|
+
([...RULE_TEXT], [...TANK]),
|
|
44768
|
+
[...RULE_TEXT],
|
|
44769
|
+
([...RULE_TEXT], [...UPDATES]),
|
|
44770
|
+
([...RULE_TEXT], [...UPDATES]),
|
|
44771
|
+
[...RULE_TEXT],
|
|
44772
|
+
[...RULE_TEXT],
|
|
44773
|
+
[...RULE_TEXT],
|
|
44774
|
+
([...RULE_TEXT], [...UPDATES]),
|
|
44775
|
+
([...RULE_TEXT], [...PACKAGE_UPDATES]),
|
|
44776
|
+
([...RULE_TEXT], [...PACKAGE_UPDATES]),
|
|
44777
|
+
([...RULE_TEXT], [...UPDATES]),
|
|
44778
|
+
([...RULE_TEXT], [...UPDATES]),
|
|
44779
|
+
([...RULE_TEXT], [...PACKAGE_UPDATES]),
|
|
44780
|
+
[...RULE_TEXT],
|
|
44781
|
+
[...RULE_TEXT],
|
|
44782
|
+
[...RULE_TEXT],
|
|
44783
|
+
[...RULE_TEXT],
|
|
44784
|
+
[...RULE_TEXT],
|
|
44785
|
+
[...RULE_TEXT],
|
|
44786
|
+
[...RULE_TEXT],
|
|
44787
|
+
[...RULE_TEXT],
|
|
44788
|
+
[...RULE_TEXT],
|
|
44789
|
+
[...RULE_TEXT],
|
|
44790
|
+
[...RULE_TEXT],
|
|
44791
|
+
[...RULE_TEXT],
|
|
44792
|
+
[...RULE_TEXT],
|
|
44793
|
+
[...RULE_TEXT],
|
|
44794
|
+
[...RULE_TEXT],
|
|
44795
|
+
[...RULE_TEXT],
|
|
44796
|
+
[...RULE_TEXT],
|
|
44797
|
+
[...RULE_TEXT],
|
|
44798
|
+
[...RULE_TEXT],
|
|
44799
|
+
[...RULE_TEXT],
|
|
44800
|
+
[...RULE_TEXT],
|
|
44801
|
+
[...RULE_TEXT],
|
|
44802
|
+
[...RULE_TEXT],
|
|
44803
|
+
[...RULE_TEXT],
|
|
44804
|
+
...STATE_SUMMARY_VARS
|
|
44805
|
+
];
|
|
44440
44806
|
/**
|
|
44441
44807
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
44442
44808
|
*
|
|
@@ -44931,7 +45297,7 @@ var AdminUIAddon = class extends BaseAddon {
|
|
|
44931
45297
|
capability: adminUiCapability,
|
|
44932
45298
|
provider: {
|
|
44933
45299
|
getStaticDir: async () => ({ staticDir: resolveAdminUiDistDir() }),
|
|
44934
|
-
getVersion: async () => ({ version: "1.2.
|
|
45300
|
+
getVersion: async () => ({ version: "1.2.272" })
|
|
44935
45301
|
}
|
|
44936
45302
|
}];
|
|
44937
45303
|
}
|