@camstack/addon-agent-ui 1.2.155 → 1.2.157
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/addon.js +314 -203
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5371,7 +5371,7 @@ var ZodIssueCode = {
|
|
|
5371
5371
|
var ZodFirstPartyTypeKind;
|
|
5372
5372
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5373
5373
|
//#endregion
|
|
5374
|
-
//#region ../types/dist/sleep-
|
|
5374
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5375
5375
|
/**
|
|
5376
5376
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5377
5377
|
* window to float samples (D455).
|
|
@@ -7418,7 +7418,59 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
7418
7418
|
return DeviceRole;
|
|
7419
7419
|
}({});
|
|
7420
7420
|
//#endregion
|
|
7421
|
-
//#region ../types/dist/composition-
|
|
7421
|
+
//#region ../types/dist/composition-Dq42XWp0.mjs
|
|
7422
|
+
/**
|
|
7423
|
+
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
7424
|
+
*
|
|
7425
|
+
* ## Why a download, on every node, including the container
|
|
7426
|
+
*
|
|
7427
|
+
* The version of ffmpeg used to be CODE: baked into the image, changeable only
|
|
7428
|
+
* by rebuilding and rolling it. Now it is DATA — this file states the release,
|
|
7429
|
+
* and a node that boots with a different one downloads it. Changing ffmpeg is a
|
|
7430
|
+
* framework bump, not an image rebuild.
|
|
7431
|
+
*
|
|
7432
|
+
* It also settles the licence question by removing it. FFmpeg's licence is
|
|
7433
|
+
* chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
|
|
7434
|
+
* (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
|
|
7435
|
+
* makes the result undistributable. These are GPL v3 builds, and we do not
|
|
7436
|
+
* distribute them: the user's own node fetches the archive from the project
|
|
7437
|
+
* that publishes it, so we convey no GPL work and inherit none of the
|
|
7438
|
+
* obligations that come with conveying one. That is the whole reason the image
|
|
7439
|
+
* no longer installs ffmpeg at all — not a technical preference.
|
|
7440
|
+
*
|
|
7441
|
+
* ## Why jellyfin-ffmpeg
|
|
7442
|
+
*
|
|
7443
|
+
* One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
|
|
7444
|
+
* from one release, with the widest hardware surface of anything maintained:
|
|
7445
|
+
* VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
|
|
7446
|
+
* MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
|
|
7447
|
+
* so the binary is not linked against a driver stack it may not find.
|
|
7448
|
+
*
|
|
7449
|
+
* **What it still needs from the host, measured 2026-09-19.** On the Unraid
|
|
7450
|
+
* HOST, which has no libva, `-vaapi_device` aborts the process outright —
|
|
7451
|
+
* `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
|
|
7452
|
+
* "Assertion in generated code"' failed`. Inside our container, which installs
|
|
7453
|
+
* libva plus the iHD driver, the same command encodes: verified end to end with
|
|
7454
|
+
* `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
|
|
7455
|
+
* KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
|
|
7456
|
+
*
|
|
7457
|
+
* ## Why each artifact carries a checksum and a claim
|
|
7458
|
+
*
|
|
7459
|
+
* The download is now the only source, so `sha256` is verified before anything
|
|
7460
|
+
* is extracted — jellyfin publishes no checksums on its release assets, so
|
|
7461
|
+
* these are ours, taken at the version bump. And `expectedHwaccels` is what the
|
|
7462
|
+
* build is supposed to be able to do: a binary that probes short of its own
|
|
7463
|
+
* claim is a source that changed under us, which is precisely what went
|
|
7464
|
+
* unnoticed for months when a static build turned out to carry no VAAPI at all
|
|
7465
|
+
* (D536).
|
|
7466
|
+
*/
|
|
7467
|
+
/** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
|
|
7468
|
+
var FFMPEG_RELEASE = "8.1.2-5";
|
|
7469
|
+
var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
|
|
7470
|
+
function portable(target) {
|
|
7471
|
+
return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
|
|
7472
|
+
}
|
|
7473
|
+
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
7422
7474
|
/**
|
|
7423
7475
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
7424
7476
|
* valutatore puro del suo FRONTE.
|
|
@@ -8222,7 +8274,6 @@ var CompositionSchema = object({
|
|
|
8222
8274
|
});
|
|
8223
8275
|
new Set([
|
|
8224
8276
|
"track",
|
|
8225
|
-
"summary",
|
|
8226
8277
|
"face",
|
|
8227
8278
|
"identity",
|
|
8228
8279
|
"plate",
|
|
@@ -12978,6 +13029,70 @@ var CompositionBlockStateSchema = object({
|
|
|
12978
13029
|
reason: string().optional(),
|
|
12979
13030
|
fields: array(CompositionFieldStateSchema)
|
|
12980
13031
|
});
|
|
13032
|
+
var NUMBER = {
|
|
13033
|
+
kind: "fixed",
|
|
13034
|
+
result: ["number"]
|
|
13035
|
+
};
|
|
13036
|
+
var BOOLEAN = {
|
|
13037
|
+
kind: "fixed",
|
|
13038
|
+
result: ["boolean"]
|
|
13039
|
+
};
|
|
13040
|
+
Object.freeze({
|
|
13041
|
+
min: NUMBER,
|
|
13042
|
+
max: NUMBER,
|
|
13043
|
+
abs: NUMBER,
|
|
13044
|
+
floor: NUMBER,
|
|
13045
|
+
ceil: NUMBER,
|
|
13046
|
+
sqrt: NUMBER,
|
|
13047
|
+
round: NUMBER,
|
|
13048
|
+
pow: NUMBER,
|
|
13049
|
+
clamp: NUMBER,
|
|
13050
|
+
avg: NUMBER,
|
|
13051
|
+
sum: NUMBER,
|
|
13052
|
+
age: NUMBER,
|
|
13053
|
+
convert: NUMBER,
|
|
13054
|
+
coalesce: { kind: "coalesce" },
|
|
13055
|
+
any: BOOLEAN,
|
|
13056
|
+
all: BOOLEAN,
|
|
13057
|
+
within: BOOLEAN,
|
|
13058
|
+
latest: {
|
|
13059
|
+
kind: "fixed",
|
|
13060
|
+
result: ["number", "null"]
|
|
13061
|
+
},
|
|
13062
|
+
number: {
|
|
13063
|
+
kind: "fixed",
|
|
13064
|
+
result: ["number", "null"]
|
|
13065
|
+
},
|
|
13066
|
+
rose: {
|
|
13067
|
+
kind: "fixed",
|
|
13068
|
+
result: ["number", "null"]
|
|
13069
|
+
},
|
|
13070
|
+
count: NUMBER
|
|
13071
|
+
});
|
|
13072
|
+
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
13073
|
+
/**
|
|
13074
|
+
* What a composition may BUILD on a device type (G2, D676): the caps a new
|
|
13075
|
+
* device of that type, or an existing one that lacks them, can be given. The
|
|
13076
|
+
* blockers are the validator's own refusal codes, and a spec compares this
|
|
13077
|
+
* listing with `planComposition` for every capability — the editor can never
|
|
13078
|
+
* offer a feature the save would refuse for the same reason.
|
|
13079
|
+
*/
|
|
13080
|
+
var ComposableFieldSchema = object({
|
|
13081
|
+
path: string(),
|
|
13082
|
+
kind: CompositionFieldKindSchema,
|
|
13083
|
+
nullable: boolean(),
|
|
13084
|
+
required: boolean(),
|
|
13085
|
+
enumValues: array(string()).optional()
|
|
13086
|
+
});
|
|
13087
|
+
var ComposableCapabilitiesSchema = object({ caps: array(object({
|
|
13088
|
+
cap: string(),
|
|
13089
|
+
fields: array(ComposableFieldSchema),
|
|
13090
|
+
/** Present for an item-array cap (`consumables.items`). */
|
|
13091
|
+
itemArray: object({
|
|
13092
|
+
path: string(),
|
|
13093
|
+
keyField: string()
|
|
13094
|
+
}).optional()
|
|
13095
|
+
})) });
|
|
12981
13096
|
/** Where a block runs. The operator chooses — a block driving a device on an
|
|
12982
13097
|
* agent is the reason placement is not fixed to the hub. */
|
|
12983
13098
|
var CoreBlockPlacementSchema = union([literal("hub"), string().min(1)]);
|
|
@@ -13142,7 +13257,7 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
|
|
|
13142
13257
|
}), method(object({ blockId: string() }), CompositionGetReadSchema, { auth: "admin" }), method(object({}), CompositionListReadSchema, { auth: "admin" }), method(object({
|
|
13143
13258
|
addonId: string().min(1),
|
|
13144
13259
|
stableId: string().min(1)
|
|
13145
|
-
}), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({
|
|
13260
|
+
}), CompositionCustomizationReadSchema, { auth: "admin" }), method(object({ deviceType: _enum(DeviceType) }), ComposableCapabilitiesSchema, { auth: "admin" }), method(object({
|
|
13146
13261
|
composition: CompositionSchema,
|
|
13147
13262
|
blockId: string().optional()
|
|
13148
13263
|
}), CompositionValidationSchema, {
|
|
@@ -20024,6 +20139,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
20024
20139
|
});
|
|
20025
20140
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
20026
20141
|
/**
|
|
20142
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20143
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20144
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20145
|
+
*/
|
|
20146
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20147
|
+
kind: literal("sensor"),
|
|
20148
|
+
deviceId: number().int().positive()
|
|
20149
|
+
})]);
|
|
20150
|
+
Object.freeze({ kind: "camera" });
|
|
20151
|
+
var CameraSensorRefSchema = object({
|
|
20152
|
+
addonId: string().min(1),
|
|
20153
|
+
stableId: string().min(1)
|
|
20154
|
+
});
|
|
20155
|
+
function cameraSensorRefKey(ref) {
|
|
20156
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20157
|
+
}
|
|
20158
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20159
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20160
|
+
var CameraSensorsConfigSchema = object({
|
|
20161
|
+
mode: CameraSensorsModeSchema,
|
|
20162
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20163
|
+
}).superRefine((value, ctx) => {
|
|
20164
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20165
|
+
value.sensors.forEach((ref, index) => {
|
|
20166
|
+
const key = cameraSensorRefKey(ref);
|
|
20167
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20168
|
+
code: "custom",
|
|
20169
|
+
path: ["sensors", index],
|
|
20170
|
+
message: `duplicate camera sensor ${key}`
|
|
20171
|
+
});
|
|
20172
|
+
seen.add(key);
|
|
20173
|
+
});
|
|
20174
|
+
});
|
|
20175
|
+
var RefFields = {
|
|
20176
|
+
addonId: string(),
|
|
20177
|
+
stableId: string()
|
|
20178
|
+
};
|
|
20179
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20180
|
+
object({
|
|
20181
|
+
...RefFields,
|
|
20182
|
+
state: literal("ready"),
|
|
20183
|
+
deviceId: number(),
|
|
20184
|
+
name: string(),
|
|
20185
|
+
caps: array(string()).readonly()
|
|
20186
|
+
}),
|
|
20187
|
+
object({
|
|
20188
|
+
...RefFields,
|
|
20189
|
+
state: literal("offline"),
|
|
20190
|
+
deviceId: number(),
|
|
20191
|
+
name: string(),
|
|
20192
|
+
reason: _enum(["offline", "disabled"])
|
|
20193
|
+
}),
|
|
20194
|
+
object({
|
|
20195
|
+
...RefFields,
|
|
20196
|
+
state: literal("missing"),
|
|
20197
|
+
reason: string()
|
|
20198
|
+
}),
|
|
20199
|
+
object({
|
|
20200
|
+
...RefFields,
|
|
20201
|
+
state: literal("unsupported"),
|
|
20202
|
+
deviceId: number(),
|
|
20203
|
+
name: string(),
|
|
20204
|
+
reason: string()
|
|
20205
|
+
}),
|
|
20206
|
+
object({
|
|
20207
|
+
...RefFields,
|
|
20208
|
+
state: literal("unreadable"),
|
|
20209
|
+
reason: string()
|
|
20210
|
+
})
|
|
20211
|
+
]);
|
|
20212
|
+
/**
|
|
20213
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20214
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20215
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20216
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20217
|
+
* say.
|
|
20218
|
+
*/
|
|
20219
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20220
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20221
|
+
object({ state: literal("not-configured") }),
|
|
20222
|
+
object({
|
|
20223
|
+
state: literal("unreadable"),
|
|
20224
|
+
reason: string()
|
|
20225
|
+
}),
|
|
20226
|
+
object({
|
|
20227
|
+
state: literal("configured"),
|
|
20228
|
+
mode: CameraSensorsModeSchema,
|
|
20229
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20230
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20231
|
+
})
|
|
20232
|
+
]);
|
|
20233
|
+
Object.freeze({
|
|
20234
|
+
state: "unreadable",
|
|
20235
|
+
reason: "camera sensor mappings not loaded"
|
|
20236
|
+
});
|
|
20237
|
+
/**
|
|
20027
20238
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
20028
20239
|
*
|
|
20029
20240
|
* ## The two scopes
|
|
@@ -20772,6 +20983,12 @@ var MotionEventSchema = object({
|
|
|
20772
20983
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20773
20984
|
mediaUrl: string().optional(),
|
|
20774
20985
|
/**
|
|
20986
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
20987
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
20988
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
20989
|
+
*/
|
|
20990
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
20991
|
+
/**
|
|
20775
20992
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
20776
20993
|
* episode is still open — a further rising edge extends it in place rather
|
|
20777
20994
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -20930,6 +21147,21 @@ var ObjectEventSchema = object({
|
|
|
20930
21147
|
keyFrameMediaId: number().int().optional(),
|
|
20931
21148
|
/** Populated by B5 (recording playback URL for this event). */
|
|
20932
21149
|
mediaUrl: string().optional(),
|
|
21150
|
+
/**
|
|
21151
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
21152
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
21153
|
+
*
|
|
21154
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
21155
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
21156
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
21157
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
21158
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
21159
|
+
* on the same instant the live hook did.
|
|
21160
|
+
*
|
|
21161
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
21162
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
21163
|
+
*/
|
|
21164
|
+
observedAt: number().optional(),
|
|
20933
21165
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
20934
21166
|
* event of the track (so an event row can be sorted by importance without a
|
|
20935
21167
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -21265,131 +21497,6 @@ var RecentTracksQueryInput = object({
|
|
|
21265
21497
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21266
21498
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21267
21499
|
});
|
|
21268
|
-
/**
|
|
21269
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21270
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21271
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21272
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21273
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21274
|
-
* row once event ids became per-table rowids).
|
|
21275
|
-
*/
|
|
21276
|
-
var SummarySchema = object({
|
|
21277
|
-
id: string(),
|
|
21278
|
-
deviceId: number(),
|
|
21279
|
-
openedAt: number(),
|
|
21280
|
-
lastActiveAt: number(),
|
|
21281
|
-
sealedAt: number().nullable(),
|
|
21282
|
-
memberCount: number().int().nonnegative(),
|
|
21283
|
-
groupShotMediaId: number().int().nullable()
|
|
21284
|
-
});
|
|
21285
|
-
var SummariesQueryInput = object({
|
|
21286
|
-
deviceIds: array(number()).min(1),
|
|
21287
|
-
since: number().optional(),
|
|
21288
|
-
until: number().optional(),
|
|
21289
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21290
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21291
|
-
* meaning of "dog" on every summary surface. */
|
|
21292
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21293
|
-
});
|
|
21294
|
-
var SummaryDetailSchema = object({
|
|
21295
|
-
summary: SummarySchema,
|
|
21296
|
-
/** Members in absorption order, oldest join first. */
|
|
21297
|
-
members: array(object({
|
|
21298
|
-
trackId: string(),
|
|
21299
|
-
/**
|
|
21300
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21301
|
-
* and the track no longer exists to fill it.
|
|
21302
|
-
*
|
|
21303
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21304
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21305
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21306
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21307
|
-
* drift from the members it claims to describe.
|
|
21308
|
-
*/
|
|
21309
|
-
className: string().nullable(),
|
|
21310
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21311
|
-
role: _enum([
|
|
21312
|
-
"primary",
|
|
21313
|
-
"sibling",
|
|
21314
|
-
"child"
|
|
21315
|
-
]).nullable(),
|
|
21316
|
-
joinedAt: number(),
|
|
21317
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21318
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21319
|
-
label: string().optional(),
|
|
21320
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21321
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21322
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21323
|
-
subLabel: string().optional()
|
|
21324
|
-
})).readonly()
|
|
21325
|
-
});
|
|
21326
|
-
/**
|
|
21327
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21328
|
-
*
|
|
21329
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21330
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21331
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21332
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21333
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21334
|
-
* draw two hundred badges.
|
|
21335
|
-
*/
|
|
21336
|
-
var SummaryListItemSchema = object({
|
|
21337
|
-
summary: SummarySchema,
|
|
21338
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21339
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21340
|
-
classes: array(object({
|
|
21341
|
-
className: string().nullable(),
|
|
21342
|
-
count: number().int().positive()
|
|
21343
|
-
})).readonly()
|
|
21344
|
-
});
|
|
21345
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21346
|
-
/**
|
|
21347
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21348
|
-
*
|
|
21349
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21350
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21351
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21352
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21353
|
-
* "newest" means, on one screen.
|
|
21354
|
-
*/
|
|
21355
|
-
var RecentSummariesQueryInput = object({
|
|
21356
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21357
|
-
deviceIds: array(number()),
|
|
21358
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21359
|
-
since: number().optional(),
|
|
21360
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21361
|
-
until: number().optional(),
|
|
21362
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21363
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21364
|
-
cursor: string().optional(),
|
|
21365
|
-
/**
|
|
21366
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21367
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21368
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21369
|
-
* make the operator's one filter component produce two shapes.
|
|
21370
|
-
*
|
|
21371
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21372
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21373
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21374
|
-
* about its primary.
|
|
21375
|
-
*
|
|
21376
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21377
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21378
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21379
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21380
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21381
|
-
*
|
|
21382
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21383
|
-
*/
|
|
21384
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21385
|
-
});
|
|
21386
|
-
var RecentSummariesPageSchema = object({
|
|
21387
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21388
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21389
|
-
* whichever feed drew it. */
|
|
21390
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21391
|
-
nextCursor: string().nullable()
|
|
21392
|
-
});
|
|
21393
21500
|
var RecentTracksPageSchema = object({
|
|
21394
21501
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21395
21502
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -21901,7 +22008,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
21901
22008
|
classes: array(string()).optional(),
|
|
21902
22009
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21903
22010
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21904
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
22011
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
21905
22012
|
kind: "mutation",
|
|
21906
22013
|
auth: "admin"
|
|
21907
22014
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -23081,6 +23188,23 @@ var MotionSourceEnum = _enum([
|
|
|
23081
23188
|
*/
|
|
23082
23189
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23083
23190
|
/**
|
|
23191
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23192
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23193
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23194
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23195
|
+
*/
|
|
23196
|
+
var MOTION_SOURCE_LABELS = {
|
|
23197
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23198
|
+
onboard: "Camera sensors",
|
|
23199
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23200
|
+
};
|
|
23201
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23202
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23203
|
+
"analyzer",
|
|
23204
|
+
"onboard",
|
|
23205
|
+
"device-activity"
|
|
23206
|
+
];
|
|
23207
|
+
/**
|
|
23084
23208
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
23085
23209
|
*
|
|
23086
23210
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -23427,7 +23551,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
23427
23551
|
*/
|
|
23428
23552
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
23429
23553
|
});
|
|
23430
|
-
|
|
23554
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
23555
|
+
value,
|
|
23556
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
23557
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
23558
|
+
} : {
|
|
23559
|
+
value,
|
|
23560
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
23561
|
+
}), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
23431
23562
|
/**
|
|
23432
23563
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
23433
23564
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -24001,6 +24132,11 @@ var CameraStatusSchema = object({
|
|
|
24001
24132
|
*/
|
|
24002
24133
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
24003
24134
|
/**
|
|
24135
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24136
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24137
|
+
*/
|
|
24138
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24139
|
+
/**
|
|
24004
24140
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
24005
24141
|
* rejection — and whose block is therefore `null` because we could not
|
|
24006
24142
|
* READ it, not because there is nothing there.
|
|
@@ -24093,6 +24229,28 @@ var NodeInferenceDevicesSchema = object({
|
|
|
24093
24229
|
reachable: boolean(),
|
|
24094
24230
|
devices: array(NodeInferenceDeviceSchema).readonly()
|
|
24095
24231
|
});
|
|
24232
|
+
/**
|
|
24233
|
+
* Pipeline Orchestrator capability — global load balancer + camera dispatcher.
|
|
24234
|
+
*
|
|
24235
|
+
* Lives on the hub. Tracks the camera-to-agent assignment map, listens to
|
|
24236
|
+
* device lifecycle events, queries each runner's capacity + hardware
|
|
24237
|
+
* profile, and dispatches `attachCamera` / `detachCamera` cap calls to the
|
|
24238
|
+
* appropriate runner instances. Persists assignments via the multi-level
|
|
24239
|
+
* settings store so they survive hub restarts.
|
|
24240
|
+
*
|
|
24241
|
+
* Strictly the control plane: never sees a frame, never calls inference,
|
|
24242
|
+
* never drains queues. The runner does that work locally on each agent.
|
|
24243
|
+
*/
|
|
24244
|
+
/**
|
|
24245
|
+
* The input of `setCameraSensors` (G5, D676): the ONE typed write path of a
|
|
24246
|
+
* camera's attached sensors (D672). `config: null` removes the attachment —
|
|
24247
|
+
* the camera reads `not-configured` again, never `unreadable`.
|
|
24248
|
+
*/
|
|
24249
|
+
var SetCameraSensorsInputSchema = object({
|
|
24250
|
+
deviceId: number().int().nonnegative(),
|
|
24251
|
+
/** `null` removes the attachment: the camera goes back to `not-configured`. */
|
|
24252
|
+
config: CameraSensorsConfigSchema.nullable()
|
|
24253
|
+
});
|
|
24096
24254
|
method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
|
|
24097
24255
|
kind: "mutation",
|
|
24098
24256
|
auth: "admin"
|
|
@@ -24247,7 +24405,10 @@ method(StorageMigrationLeaseInputSchema, object({ paused: literal(true) }), {
|
|
|
24247
24405
|
}), CameraSwitchGroupSchema, {
|
|
24248
24406
|
kind: "mutation",
|
|
24249
24407
|
auth: "admin"
|
|
24250
|
-
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(
|
|
24408
|
+
}), method(object({ deviceId: number() }), CameraStatusSchema), method(object({ deviceIds: array(number()).optional() }), array(CameraStatusSchema).readonly()), method(SetCameraSensorsInputSchema, object({ success: literal(true) }), {
|
|
24409
|
+
kind: "mutation",
|
|
24410
|
+
auth: "admin"
|
|
24411
|
+
}), method(_void(), DiskReconcileJobSchema, {
|
|
24251
24412
|
kind: "mutation",
|
|
24252
24413
|
auth: "admin"
|
|
24253
24414
|
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" }), method(_void(), array(PipelineTemplateSchema).readonly()), method(object({
|
|
@@ -30072,7 +30233,9 @@ object({
|
|
|
30072
30233
|
detected: boolean(),
|
|
30073
30234
|
timestamp: number(),
|
|
30074
30235
|
source: MotionSourceEnum,
|
|
30075
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
30236
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
30237
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
30238
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
30076
30239
|
});
|
|
30077
30240
|
DeviceType.Camera, DeviceType.Sensor, method(object({ deviceId: number() }), boolean());
|
|
30078
30241
|
object({
|
|
@@ -35146,47 +35309,6 @@ DeviceType.Camera, method(object({
|
|
|
35146
35309
|
detection: array(ZoneRuleSchema).readonly(),
|
|
35147
35310
|
package: array(ZoneRuleSchema).readonly()
|
|
35148
35311
|
});
|
|
35149
|
-
var NUMBER = {
|
|
35150
|
-
kind: "fixed",
|
|
35151
|
-
result: ["number"]
|
|
35152
|
-
};
|
|
35153
|
-
var BOOLEAN = {
|
|
35154
|
-
kind: "fixed",
|
|
35155
|
-
result: ["boolean"]
|
|
35156
|
-
};
|
|
35157
|
-
Object.freeze({
|
|
35158
|
-
min: NUMBER,
|
|
35159
|
-
max: NUMBER,
|
|
35160
|
-
abs: NUMBER,
|
|
35161
|
-
floor: NUMBER,
|
|
35162
|
-
ceil: NUMBER,
|
|
35163
|
-
sqrt: NUMBER,
|
|
35164
|
-
round: NUMBER,
|
|
35165
|
-
pow: NUMBER,
|
|
35166
|
-
clamp: NUMBER,
|
|
35167
|
-
avg: NUMBER,
|
|
35168
|
-
sum: NUMBER,
|
|
35169
|
-
age: NUMBER,
|
|
35170
|
-
convert: NUMBER,
|
|
35171
|
-
coalesce: { kind: "coalesce" },
|
|
35172
|
-
any: BOOLEAN,
|
|
35173
|
-
all: BOOLEAN,
|
|
35174
|
-
within: BOOLEAN,
|
|
35175
|
-
latest: {
|
|
35176
|
-
kind: "fixed",
|
|
35177
|
-
result: ["number", "null"]
|
|
35178
|
-
},
|
|
35179
|
-
number: {
|
|
35180
|
-
kind: "fixed",
|
|
35181
|
-
result: ["number", "null"]
|
|
35182
|
-
},
|
|
35183
|
-
rose: {
|
|
35184
|
-
kind: "fixed",
|
|
35185
|
-
result: ["number", "null"]
|
|
35186
|
-
},
|
|
35187
|
-
count: NUMBER
|
|
35188
|
-
});
|
|
35189
|
-
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
35190
35312
|
/**
|
|
35191
35313
|
* Accessory device helpers — shared across drivers.
|
|
35192
35314
|
*
|
|
@@ -37609,6 +37731,12 @@ Object.freeze({
|
|
|
37609
37731
|
addonId: null,
|
|
37610
37732
|
access: "view"
|
|
37611
37733
|
},
|
|
37734
|
+
"coreBlocks.listComposableCaps": {
|
|
37735
|
+
capName: "core-blocks",
|
|
37736
|
+
capScope: "system",
|
|
37737
|
+
addonId: null,
|
|
37738
|
+
access: "view"
|
|
37739
|
+
},
|
|
37612
37740
|
"coreBlocks.listCompositions": {
|
|
37613
37741
|
capName: "core-blocks",
|
|
37614
37742
|
capScope: "system",
|
|
@@ -40579,12 +40707,6 @@ Object.freeze({
|
|
|
40579
40707
|
addonId: null,
|
|
40580
40708
|
access: "view"
|
|
40581
40709
|
},
|
|
40582
|
-
"pipelineAnalytics.getSummary": {
|
|
40583
|
-
capName: "pipeline-analytics",
|
|
40584
|
-
capScope: "device",
|
|
40585
|
-
addonId: null,
|
|
40586
|
-
access: "view"
|
|
40587
|
-
},
|
|
40588
40710
|
"pipelineAnalytics.getTrack": {
|
|
40589
40711
|
capName: "pipeline-analytics",
|
|
40590
40712
|
capScope: "device",
|
|
@@ -40645,12 +40767,6 @@ Object.freeze({
|
|
|
40645
40767
|
addonId: null,
|
|
40646
40768
|
access: "view"
|
|
40647
40769
|
},
|
|
40648
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
40649
|
-
capName: "pipeline-analytics",
|
|
40650
|
-
capScope: "device",
|
|
40651
|
-
addonId: null,
|
|
40652
|
-
access: "view"
|
|
40653
|
-
},
|
|
40654
40770
|
"pipelineAnalytics.listRecentTracks": {
|
|
40655
40771
|
capName: "pipeline-analytics",
|
|
40656
40772
|
capScope: "device",
|
|
@@ -40681,12 +40797,6 @@ Object.freeze({
|
|
|
40681
40797
|
addonId: null,
|
|
40682
40798
|
access: "view"
|
|
40683
40799
|
},
|
|
40684
|
-
"pipelineAnalytics.listSummaries": {
|
|
40685
|
-
capName: "pipeline-analytics",
|
|
40686
|
-
capScope: "device",
|
|
40687
|
-
addonId: null,
|
|
40688
|
-
access: "view"
|
|
40689
|
-
},
|
|
40690
40800
|
"pipelineAnalytics.listTrackMedia": {
|
|
40691
40801
|
capName: "pipeline-analytics",
|
|
40692
40802
|
capScope: "device",
|
|
@@ -41311,6 +41421,12 @@ Object.freeze({
|
|
|
41311
41421
|
addonId: null,
|
|
41312
41422
|
access: "create"
|
|
41313
41423
|
},
|
|
41424
|
+
"pipelineOrchestrator.setCameraSensors": {
|
|
41425
|
+
capName: "pipeline-orchestrator",
|
|
41426
|
+
capScope: "system",
|
|
41427
|
+
addonId: null,
|
|
41428
|
+
access: "create"
|
|
41429
|
+
},
|
|
41314
41430
|
"pipelineOrchestrator.setCameraStepOverride": {
|
|
41315
41431
|
capName: "pipeline-orchestrator",
|
|
41316
41432
|
capScope: "system",
|
|
@@ -44856,11 +44972,6 @@ Object.freeze({
|
|
|
44856
44972
|
form: "single",
|
|
44857
44973
|
optional: true
|
|
44858
44974
|
}],
|
|
44859
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
44860
|
-
name: "deviceIds",
|
|
44861
|
-
form: "array",
|
|
44862
|
-
optional: false
|
|
44863
|
-
}],
|
|
44864
44975
|
"pipelineAnalytics.listRecentTracks": [{
|
|
44865
44976
|
name: "deviceIds",
|
|
44866
44977
|
form: "array",
|
|
@@ -44871,11 +44982,6 @@ Object.freeze({
|
|
|
44871
44982
|
form: "array",
|
|
44872
44983
|
optional: true
|
|
44873
44984
|
}],
|
|
44874
|
-
"pipelineAnalytics.listSummaries": [{
|
|
44875
|
-
name: "deviceIds",
|
|
44876
|
-
form: "array",
|
|
44877
|
-
optional: false
|
|
44878
|
-
}],
|
|
44879
44985
|
"pipelineAnalytics.listTrackMedia": [{
|
|
44880
44986
|
name: "deviceId",
|
|
44881
44987
|
form: "single",
|
|
@@ -45031,6 +45137,11 @@ Object.freeze({
|
|
|
45031
45137
|
form: "single",
|
|
45032
45138
|
optional: false
|
|
45033
45139
|
}],
|
|
45140
|
+
"pipelineOrchestrator.setCameraSensors": [{
|
|
45141
|
+
name: "deviceId",
|
|
45142
|
+
form: "single",
|
|
45143
|
+
optional: false
|
|
45144
|
+
}],
|
|
45034
45145
|
"pipelineOrchestrator.setCameraStepOverride": [{
|
|
45035
45146
|
name: "deviceId",
|
|
45036
45147
|
form: "single",
|
|
@@ -46687,7 +46798,7 @@ var AgentUIAddon = class extends BaseAddon {
|
|
|
46687
46798
|
capability: adminUiCapability,
|
|
46688
46799
|
provider: {
|
|
46689
46800
|
getStaticDir: async () => ({ staticDir: path.resolve(__dirname) }),
|
|
46690
|
-
getVersion: async () => ({ version: "1.2.
|
|
46801
|
+
getVersion: async () => ({ version: "1.2.157" })
|
|
46691
46802
|
}
|
|
46692
46803
|
}];
|
|
46693
46804
|
}
|