@camstack/addon-pipeline 1.2.45 → 1.2.47
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +43 -13
- package/dist/detection-pipeline/index.mjs +43 -13
- package/dist/{dist-QyZ7QSRP.js → dist-C9Q1t0nT.js} +514 -3
- package/dist/{dist-BDkEhx4Z.mjs → dist-CfxC7XoI.mjs} +514 -3
- package/dist/{event-loop-stall-monitor-IAuNEdmG.mjs → event-loop-stall-monitor-B_XUPTwp.mjs} +7 -1
- package/dist/{event-loop-stall-monitor-COEKVBQK.js → event-loop-stall-monitor-Luq9AX4t.js} +7 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +15 -6
- package/dist/pipeline-runner/index.mjs +15 -6
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/session-decode/decode-worker-child.js +1 -1
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-C68YfSUH.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-SKj0Zdz2.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-KpixNEma.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-rd7UaqfV.mjs +26 -0
- package/dist/stream-broker/{hostInit-BMCrULpc.mjs → hostInit-D8gyxL0j.mjs} +2 -2
- package/dist/stream-broker/index.js +864 -106
- package/dist/stream-broker/index.mjs +864 -106
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-le27Mw_8.js → worker-protocol-BUJpm7l3.js} +1 -1
- package/dist/{worker-protocol-DFH_z2-q.mjs → worker-protocol-rqbyKlm9.mjs} +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-C7bsz4cP.js → MaskShapeCanvas-DI4BY7W2-DwXIyaHw.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-BmhLinUd.js → MotionZonesSettings-NcxxQN8r-Cf8EtWEG.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BJjyGWFy.js → PrivacyMaskSettings-APgPLF7p-BvsVXya9.js} +1 -1
- package/embed-dist/assets/{index-a4CMt-Uc.js → index-BuAeIGv8.js} +12 -12
- package/embed-dist/assets/index-ICnBEqOy.css +2 -0
- package/embed-dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CT2bGWqM.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-B3GxBnXM.mjs +0 -26
- package/embed-dist/assets/index-DC63og2c.css +0 -2
|
@@ -10017,6 +10017,69 @@ var StreamFormatSchema = _enum([
|
|
|
10017
10017
|
"mjpeg",
|
|
10018
10018
|
"rtsp"
|
|
10019
10019
|
]);
|
|
10020
|
+
/** A container `produceEventMedia` can emit. */
|
|
10021
|
+
var EventMediaKindSchema = _enum(["mp4", "gif"]);
|
|
10022
|
+
/**
|
|
10023
|
+
* One produced artifact, referenced by HANDLE.
|
|
10024
|
+
*
|
|
10025
|
+
* Never inline bytes: a produced clip is 200 KB–5 MB and every consumer of this
|
|
10026
|
+
* method is in another runner ([D9](../../../../docs/decisions/adr-0009.md),
|
|
10027
|
+
* [D18](../../../../docs/decisions/adr-0018.md) — cross-process media is fetched
|
|
10028
|
+
* on demand, compressed, by handle). `bytes` is here so a caller can decide
|
|
10029
|
+
* whether it wants the fetch at all.
|
|
10030
|
+
*/
|
|
10031
|
+
var EventMediaArtifactSchema = object({
|
|
10032
|
+
kind: EventMediaKindSchema,
|
|
10033
|
+
/** Opaque, single-camera, short-lived. Redeem with `fetchEventMedia`. */
|
|
10034
|
+
handle: string(),
|
|
10035
|
+
/**
|
|
10036
|
+
* The node holding the bytes — the ROUTING key for `fetchEventMedia`.
|
|
10037
|
+
*
|
|
10038
|
+
* `stream-broker` is a singleton cap and an unpinned call never leaves the
|
|
10039
|
+
* hub, so a handle produced on an agent's broker would be redeemed against
|
|
10040
|
+
* the hub's store and come back `null`. Same contract, same field name and
|
|
10041
|
+
* the same reason as `FrameHandleSchema.nodeId`: the producer stamps where it
|
|
10042
|
+
* lives and the consumer pins to it.
|
|
10043
|
+
*/
|
|
10044
|
+
nodeId: string(),
|
|
10045
|
+
mime: string(),
|
|
10046
|
+
bytes: number().int(),
|
|
10047
|
+
width: number().int(),
|
|
10048
|
+
height: number().int()
|
|
10049
|
+
});
|
|
10050
|
+
/**
|
|
10051
|
+
* What a production actually covered — the answer to the only question an
|
|
10052
|
+
* operator asks about a notification clip.
|
|
10053
|
+
*
|
|
10054
|
+
* `fromTs`/`toTs` are WALL CLOCK, derived from the ring's own packet timeline,
|
|
10055
|
+
* so a caller can state "this clip starts 4.1 s before the event" instead of
|
|
10056
|
+
* inferring it from a duration. A production whose `fromTs` is later than the
|
|
10057
|
+
* event is a production with no pre-roll, and that is exactly the defect this
|
|
10058
|
+
* method exists to make visible rather than plausible.
|
|
10059
|
+
*/
|
|
10060
|
+
var EventMediaCoverageSchema = object({
|
|
10061
|
+
fromTs: number(),
|
|
10062
|
+
toTs: number(),
|
|
10063
|
+
/** Encoded packets in the muxed window. */
|
|
10064
|
+
packets: number().int()
|
|
10065
|
+
});
|
|
10066
|
+
/**
|
|
10067
|
+
* The result of ONE cut, in every container the caller asked for.
|
|
10068
|
+
*
|
|
10069
|
+
* Every artifact in `media` came out of the SAME window of the SAME rendition —
|
|
10070
|
+
* that is the whole reason this is one method rather than one call per format.
|
|
10071
|
+
* A consumer attaching a gif and a video can no longer show two different
|
|
10072
|
+
* moments, because it never chose two sources.
|
|
10073
|
+
*/
|
|
10074
|
+
var EventMediaProductionSchema = object({
|
|
10075
|
+
media: array(EventMediaArtifactSchema).readonly(),
|
|
10076
|
+
coverage: EventMediaCoverageSchema,
|
|
10077
|
+
/** The rendition actually cut from — what the default or the fallback chose. */
|
|
10078
|
+
profile: CamProfileSchema,
|
|
10079
|
+
/** `copy` = the camera's own H.264, untouched. `encode` = re-encoded (H.265
|
|
10080
|
+
* source, a downscale, or a playback rate other than 1). */
|
|
10081
|
+
video: _enum(["copy", "encode"])
|
|
10082
|
+
});
|
|
10020
10083
|
var RtspRestreamEntrySchema = object({
|
|
10021
10084
|
brokerId: string(),
|
|
10022
10085
|
url: string(),
|
|
@@ -10446,6 +10509,66 @@ var streamBrokerCapability = {
|
|
|
10446
10509
|
kind: "mutation",
|
|
10447
10510
|
auth: "admin"
|
|
10448
10511
|
}),
|
|
10512
|
+
/**
|
|
10513
|
+
* THE production point for event media — one window, every container.
|
|
10514
|
+
*
|
|
10515
|
+
* `renderPreBufferClip` renders ONE format per call, so a consumer wanting a
|
|
10516
|
+
* gif and a video made two calls and got two windows. On 2026-08-08 the
|
|
10517
|
+
* operator received exactly that: a gif around a doorbell press and an mp4
|
|
10518
|
+
* of the six seconds after it. This method cuts once and derives the rest,
|
|
10519
|
+
* so "the attachments agree" is a property of the service instead of a
|
|
10520
|
+
* discipline every consumer has to keep.
|
|
10521
|
+
*
|
|
10522
|
+
* It is also the only place that owns the packets. The broker already
|
|
10523
|
+
* retains an AnnexB ring per camera (`setClipRetention`, D32) — the
|
|
10524
|
+
* prebuffer — so a production reaches BACKWARDS from the event with no
|
|
10525
|
+
* process to spawn and nothing kept warm. It waits out `postSeconds`, muxes
|
|
10526
|
+
* the window once (COPYING the camera's own H.264 whenever nothing is being
|
|
10527
|
+
* changed), derives any gif from that same mux, and returns HANDLES.
|
|
10528
|
+
*
|
|
10529
|
+
* Intended for every future consumer, not just notifications: a clips API, a
|
|
10530
|
+
* retrain export and an event export all want the same window of the same
|
|
10531
|
+
* camera and must not each grow their own renderer.
|
|
10532
|
+
*/
|
|
10533
|
+
produceEventMedia: method(object({
|
|
10534
|
+
deviceId: number(),
|
|
10535
|
+
/** Absent = the largest H.264 rendition at or below 1080p, which is
|
|
10536
|
+
* also the one that can be copied. Falls back to whatever the ring
|
|
10537
|
+
* actually retained, and the answer says which. */
|
|
10538
|
+
profile: CamProfileSchema.optional(),
|
|
10539
|
+
aroundMs: number(),
|
|
10540
|
+
preSeconds: number().min(0).max(20).default(4),
|
|
10541
|
+
postSeconds: number().min(0).max(20).default(6),
|
|
10542
|
+
kinds: array(EventMediaKindSchema).min(1).default(["mp4"]),
|
|
10543
|
+
/** GIF geometry. The video keeps the source's own. */
|
|
10544
|
+
gifMaxWidth: number().int().min(120).max(1280).default(640),
|
|
10545
|
+
gifFps: number().int().min(1).max(15).default(8),
|
|
10546
|
+
/**
|
|
10547
|
+
* Playback rate, applied to EVERY container so they stay one clip.
|
|
10548
|
+
* `1` is real time and is what allows the copy branch.
|
|
10549
|
+
*/
|
|
10550
|
+
speed: number().min(1).max(8).default(1)
|
|
10551
|
+
}), EventMediaProductionSchema, {
|
|
10552
|
+
kind: "mutation",
|
|
10553
|
+
auth: "admin"
|
|
10554
|
+
}),
|
|
10555
|
+
/**
|
|
10556
|
+
* Redeem a {@link EventMediaArtifactSchema} handle for its bytes.
|
|
10557
|
+
*
|
|
10558
|
+
* Separate from the production on purpose (D18): the producing runner keeps
|
|
10559
|
+
* the artifact for a few minutes, and a consumer that only wanted the
|
|
10560
|
+
* coverage never moves a megabyte. `null` once it has expired — a handle is
|
|
10561
|
+
* short-lived by design and a caller that waited too long must see that
|
|
10562
|
+
* rather than a zero-length file.
|
|
10563
|
+
*/
|
|
10564
|
+
fetchEventMedia: method(object({ handle: string() }), object({
|
|
10565
|
+
base64: string(),
|
|
10566
|
+
mime: string(),
|
|
10567
|
+
bytes: number().int()
|
|
10568
|
+
}).nullable(), {
|
|
10569
|
+
kind: "mutation",
|
|
10570
|
+
auth: "admin"
|
|
10571
|
+
}),
|
|
10449
10572
|
listAllCameraStreams: method(_void(), array(CameraStreamSchema).readonly()),
|
|
10450
10573
|
listAllProfileSlots: method(_void(), array(ProfileSlotSchema).readonly()),
|
|
10451
10574
|
getBrokerStats: method(object({ brokerId: string() }), BrokerStatsSchema),
|
|
@@ -16485,6 +16608,60 @@ var TrackFlagsSchema = object({
|
|
|
16485
16608
|
* `trained` without a re-fetch. */
|
|
16486
16609
|
retrainStatus: RetrainStatusSchema
|
|
16487
16610
|
});
|
|
16611
|
+
union([literal(1), literal(2)]);
|
|
16612
|
+
/**
|
|
16613
|
+
* WHO decided a label, and when. Carried per tier so a value can be traced to
|
|
16614
|
+
* the step and model that produced it — which is what makes the write rule
|
|
16615
|
+
* arguable after the fact ("why is 592's label `dog` and not `Canis lupus`?")
|
|
16616
|
+
* and what lets a migrated, UNATTRIBUTED value be told apart from a real one.
|
|
16617
|
+
*
|
|
16618
|
+
* `stepId` is the pipeline step id (`animal-classifier`, `bird-classifier`,
|
|
16619
|
+
* `plate-ocr`, `face-embedding`, `object-detection`), or the sentinel
|
|
16620
|
+
* `migration:4g` for a value the 4g migration moved from the single-slot era —
|
|
16621
|
+
* that value has no provenance, and the write rule lets ANY properly-attributed
|
|
16622
|
+
* write of the same tier replace it regardless of score.
|
|
16623
|
+
*/
|
|
16624
|
+
var LabelAttributionSchema = object({
|
|
16625
|
+
stepId: string(),
|
|
16626
|
+
modelId: string().optional(),
|
|
16627
|
+
decidedAt: number()
|
|
16628
|
+
});
|
|
16629
|
+
/**
|
|
16630
|
+
* The TIERED label model (roadmap 4g), spread into `TrackSchema` and
|
|
16631
|
+
* `ObjectEventSchema` from ONE place so the two surfaces cannot drift — a
|
|
16632
|
+
* track and its events always answer the same question the same way.
|
|
16633
|
+
*
|
|
16634
|
+
* Two scalar columns, not an array: every consumer wants "the coarse one" or
|
|
16635
|
+
* "the fine one", and an array made both a scan. `label` is tier 1, `subLabel`
|
|
16636
|
+
* is tier 2, and each carries its own score + attribution.
|
|
16637
|
+
*
|
|
16638
|
+
* **Reading it.** What a human should be shown is `subLabel ?? label` — the
|
|
16639
|
+
* finest thing known. Before 4g the single `label` column held the finest
|
|
16640
|
+
* value, so a consumer that has not been updated reads the tier-1 slot and
|
|
16641
|
+
* shows nothing on a species-only row; that is why the migration puts every
|
|
16642
|
+
* pre-4g value in tier 2 (it cannot regress a display that reads the fallback)
|
|
16643
|
+
* and why the read surfaces were changed in the same train.
|
|
16644
|
+
*
|
|
16645
|
+
* **Writing it.** The slots are independent, which is the whole point: a
|
|
16646
|
+
* tier-1 write (`bird`) can never overwrite a tier-2 value (`Turdus
|
|
16647
|
+
* migratorius`), so fineness cannot regress by construction. Within a tier the
|
|
16648
|
+
* higher score wins. One rule, one implementation — see
|
|
16649
|
+
* `pipeline/label-tier.ts` in addon-post-analysis.
|
|
16650
|
+
*/
|
|
16651
|
+
var TieredLabelFields = {
|
|
16652
|
+
/** Tier 1 — the sub-class. See {@link LabelTierSchema}. */
|
|
16653
|
+
label: string().optional(),
|
|
16654
|
+
/** Confidence of the tier-1 value, as reported by the deciding step. */
|
|
16655
|
+
labelScore: number().optional(),
|
|
16656
|
+
/** Provenance of the tier-1 value. See {@link LabelAttributionSchema}. */
|
|
16657
|
+
labelMeta: LabelAttributionSchema.optional(),
|
|
16658
|
+
/** Tier 2 — the instance. See {@link LabelTierSchema}. */
|
|
16659
|
+
subLabel: string().optional(),
|
|
16660
|
+
/** Confidence of the tier-2 value, as reported by the deciding step. */
|
|
16661
|
+
subLabelScore: number().optional(),
|
|
16662
|
+
/** Provenance of the tier-2 value. See {@link LabelAttributionSchema}. */
|
|
16663
|
+
subLabelMeta: LabelAttributionSchema.optional()
|
|
16664
|
+
};
|
|
16488
16665
|
/** Per-camera slice of a training-export estimate. */
|
|
16489
16666
|
var TrainingExportDeviceTotalsSchema = object({
|
|
16490
16667
|
deviceId: number(),
|
|
@@ -16509,7 +16686,7 @@ var TrackSchema = object({
|
|
|
16509
16686
|
trackId: string(),
|
|
16510
16687
|
deviceId: number(),
|
|
16511
16688
|
className: string(),
|
|
16512
|
-
|
|
16689
|
+
...TieredLabelFields,
|
|
16513
16690
|
producingDeviceName: string().optional(),
|
|
16514
16691
|
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
16515
16692
|
source: TrackSourceSchema.optional(),
|
|
@@ -16622,7 +16799,7 @@ var ObjectEventSchema = object({
|
|
|
16622
16799
|
/** Omitted in slim projection. */
|
|
16623
16800
|
trackId: string().optional(),
|
|
16624
16801
|
className: string(),
|
|
16625
|
-
|
|
16802
|
+
...TieredLabelFields,
|
|
16626
16803
|
/** Omitted in slim projection. */
|
|
16627
16804
|
confidence: number().optional(),
|
|
16628
16805
|
/** Heavy JSON — omitted in slim projection. */
|
|
@@ -16703,6 +16880,173 @@ var MediaFileSchema = object({
|
|
|
16703
16880
|
* stored blob and a `?variant=thumb` rendering without fetching either.
|
|
16704
16881
|
*/
|
|
16705
16882
|
var MediaFileInfoSchema = MediaFileSchema.omit({ base64: true });
|
|
16883
|
+
/**
|
|
16884
|
+
* The MACRO tier of an annotation — a CLOSED set.
|
|
16885
|
+
*
|
|
16886
|
+
* This is what the exported detector predicts, so a typo here is a new class
|
|
16887
|
+
* with one example in it. `label` and `subLabel` are open strings by contrast:
|
|
16888
|
+
* the whole point of the page is teaching the model things it does not know
|
|
16889
|
+
* yet, and constraining that vocabulary would make it useless.
|
|
16890
|
+
*
|
|
16891
|
+
* A macro class is NEVER a label. The provider refuses a write whose `label` or
|
|
16892
|
+
* `subLabel` is one of these values, in any casing, because once `person`
|
|
16893
|
+
* exists in both tiers "every person box" stops being answerable without
|
|
16894
|
+
* knowing every string anyone ever typed — and the damage is retroactive.
|
|
16895
|
+
*/
|
|
16896
|
+
var RetrainMacroClassSchema = _enum([
|
|
16897
|
+
"person",
|
|
16898
|
+
"vehicle",
|
|
16899
|
+
"animal",
|
|
16900
|
+
"package",
|
|
16901
|
+
"face",
|
|
16902
|
+
"plate"
|
|
16903
|
+
]);
|
|
16904
|
+
/** A subject to learn, or a phantom to unlearn (taught by OMISSION). */
|
|
16905
|
+
var RetrainAnnotationKindSchema = _enum(["subject", "model_error"]);
|
|
16906
|
+
/** Did a human draw this box, or did the assist propose it? */
|
|
16907
|
+
var RetrainAnnotationSourceSchema = _enum(["operator", "assist"]);
|
|
16908
|
+
/** Normalised `[0,1]` rectangle against the FULL frame — the canonical form. */
|
|
16909
|
+
var RetrainBboxSchema = object({
|
|
16910
|
+
x: number(),
|
|
16911
|
+
y: number(),
|
|
16912
|
+
w: number(),
|
|
16913
|
+
h: number()
|
|
16914
|
+
});
|
|
16915
|
+
/**
|
|
16916
|
+
* One annotated subject.
|
|
16917
|
+
*
|
|
16918
|
+
* `bbox` is normalised against the full frame, ALWAYS. The per-model shapes
|
|
16919
|
+
* (letterboxed root / zone-cropped package / subject-cropped classifier) are
|
|
16920
|
+
* derived from it at export and never stored — storing them is how one feature
|
|
16921
|
+
* space ends up holding two crops of the same subject (D52).
|
|
16922
|
+
*/
|
|
16923
|
+
var RetrainAnnotationSchema = object({
|
|
16924
|
+
id: string(),
|
|
16925
|
+
trackId: string(),
|
|
16926
|
+
deviceId: number(),
|
|
16927
|
+
/** The COPY in retrain storage — never the source track's media key. */
|
|
16928
|
+
mediaKey: string(),
|
|
16929
|
+
bbox: RetrainBboxSchema,
|
|
16930
|
+
macroClass: RetrainMacroClassSchema,
|
|
16931
|
+
label: string().optional(),
|
|
16932
|
+
subLabel: string().optional(),
|
|
16933
|
+
kind: RetrainAnnotationKindSchema,
|
|
16934
|
+
source: RetrainAnnotationSourceSchema,
|
|
16935
|
+
/** Which model proposed this box — or, on a `model_error`, drew the phantom. */
|
|
16936
|
+
assistModelId: string().optional(),
|
|
16937
|
+
assistScore: number().optional(),
|
|
16938
|
+
exportedInBatch: string().optional(),
|
|
16939
|
+
createdAt: number()
|
|
16940
|
+
});
|
|
16941
|
+
/** The write form — the server owns `id`, `createdAt` and the frame binding. */
|
|
16942
|
+
var RetrainAnnotationDraftSchema = RetrainAnnotationSchema.omit({
|
|
16943
|
+
id: true,
|
|
16944
|
+
trackId: true,
|
|
16945
|
+
deviceId: true,
|
|
16946
|
+
mediaKey: true,
|
|
16947
|
+
createdAt: true,
|
|
16948
|
+
exportedInBatch: true
|
|
16949
|
+
});
|
|
16950
|
+
/** A track sitting in `staging`, with everything the worklist needs to rank it. */
|
|
16951
|
+
var RetrainTrackSchema = object({
|
|
16952
|
+
trackId: string(),
|
|
16953
|
+
deviceId: number(),
|
|
16954
|
+
className: string(),
|
|
16955
|
+
label: string().optional(),
|
|
16956
|
+
firstSeen: number(),
|
|
16957
|
+
lastSeen: number(),
|
|
16958
|
+
/** How many frames the dataset already holds from this track. */
|
|
16959
|
+
frameCount: number().int(),
|
|
16960
|
+
/** How many subjects have been annotated on those frames. `0` with
|
|
16961
|
+
* `frameCount: 0` is exactly "staging, still to work". */
|
|
16962
|
+
annotationCount: number().int()
|
|
16963
|
+
});
|
|
16964
|
+
/** A frame the picker may offer — an index row, no blob was read to produce it. */
|
|
16965
|
+
var RetrainFrameCandidateSchema = object({
|
|
16966
|
+
mediaKey: string(),
|
|
16967
|
+
kind: MediaFileKindEnum,
|
|
16968
|
+
timestamp: number(),
|
|
16969
|
+
sizeBytes: number().int(),
|
|
16970
|
+
/** A copy of this original already exists — selecting it is free and cannot
|
|
16971
|
+
* fail, whatever became of the original. */
|
|
16972
|
+
copied: boolean()
|
|
16973
|
+
});
|
|
16974
|
+
/** A frame the dataset OWNS: bytes copied at selection time. */
|
|
16975
|
+
var RetrainFrameSchema = object({
|
|
16976
|
+
frameId: string(),
|
|
16977
|
+
deviceId: number(),
|
|
16978
|
+
trackId: string(),
|
|
16979
|
+
/** Provenance only. It may already point at nothing — that is expected. */
|
|
16980
|
+
sourceMediaKey: string(),
|
|
16981
|
+
sourceKind: MediaFileKindEnum,
|
|
16982
|
+
sizeBytes: number().int(),
|
|
16983
|
+
width: number().int(),
|
|
16984
|
+
height: number().int(),
|
|
16985
|
+
copiedAt: number()
|
|
16986
|
+
});
|
|
16987
|
+
/** Why a copy-on-select could not be honoured — named, never a silent skip. */
|
|
16988
|
+
var RetrainCopyRefusalSchema = _enum([
|
|
16989
|
+
"source-missing",
|
|
16990
|
+
"unreadable-image",
|
|
16991
|
+
"write-failed"
|
|
16992
|
+
]);
|
|
16993
|
+
var RetrainFrameSelectionSchema = object({
|
|
16994
|
+
copied: array(RetrainFrameSchema).readonly(),
|
|
16995
|
+
refused: array(object({
|
|
16996
|
+
sourceMediaKey: string(),
|
|
16997
|
+
reason: RetrainCopyRefusalSchema
|
|
16998
|
+
})).readonly()
|
|
16999
|
+
});
|
|
17000
|
+
var RetrainFrameListSchema = object({
|
|
17001
|
+
candidates: array(RetrainFrameCandidateSchema).readonly(),
|
|
17002
|
+
copies: array(RetrainFrameSchema).readonly(),
|
|
17003
|
+
/** What the page pre-selects — the native key frame when one survives. */
|
|
17004
|
+
autoPickMediaKey: string().optional()
|
|
17005
|
+
});
|
|
17006
|
+
/** What the operator asked the assist to look for. */
|
|
17007
|
+
var RetrainAssistSubjectSchema = discriminatedUnion("kind", [object({
|
|
17008
|
+
kind: literal("package"),
|
|
17009
|
+
zone: RetrainBboxSchema.optional()
|
|
17010
|
+
}), object({
|
|
17011
|
+
kind: literal("objects"),
|
|
17012
|
+
modelId: string(),
|
|
17013
|
+
minScore: number().optional()
|
|
17014
|
+
})]);
|
|
17015
|
+
/**
|
|
17016
|
+
* The assist's answer — a discriminated union, because "the model saw nothing"
|
|
17017
|
+
* and "this node cannot run that model" lead to different next moves and a
|
|
17018
|
+
* nullable result cannot tell them apart.
|
|
17019
|
+
*/
|
|
17020
|
+
var RetrainAssistResultSchema = discriminatedUnion("kind", [object({
|
|
17021
|
+
kind: literal("proposed"),
|
|
17022
|
+
modelId: string(),
|
|
17023
|
+
stepId: string(),
|
|
17024
|
+
minScore: number(),
|
|
17025
|
+
/** Drafts, ready to edit. `source: 'assist'` until the operator touches one. */
|
|
17026
|
+
proposals: array(RetrainAnnotationDraftSchema).readonly(),
|
|
17027
|
+
/** Returned by the runner but removed by the threshold. */
|
|
17028
|
+
belowThreshold: number().int()
|
|
17029
|
+
}), object({
|
|
17030
|
+
kind: literal("refused"),
|
|
17031
|
+
/** `no-zone` is ours; the rest are the runner's own refusal vocabulary. */
|
|
17032
|
+
reason: string(),
|
|
17033
|
+
detail: string().optional()
|
|
17034
|
+
})]);
|
|
17035
|
+
/** The outcome of a lifecycle move owned by the retrain page. */
|
|
17036
|
+
var RetrainTransitionResultSchema = object({
|
|
17037
|
+
trackId: string(),
|
|
17038
|
+
/** Where the track ended up, whatever happened. */
|
|
17039
|
+
retrainStatus: RetrainStatusSchema,
|
|
17040
|
+
/** `false` ⇒ the move was refused or was a no-op; `reason` says which. */
|
|
17041
|
+
changed: boolean(),
|
|
17042
|
+
reason: _enum([
|
|
17043
|
+
"unknown-track",
|
|
17044
|
+
"no-frames-copied",
|
|
17045
|
+
"not-staging",
|
|
17046
|
+
"not-trained",
|
|
17047
|
+
"unchanged"
|
|
17048
|
+
]).optional()
|
|
17049
|
+
});
|
|
16706
17050
|
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
16707
17051
|
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
16708
17052
|
var DeviceEventQueryInput = object({
|
|
@@ -16757,7 +17101,7 @@ var KeyEventSchema = object({
|
|
|
16757
17101
|
/** Track start time (firstSeen). */
|
|
16758
17102
|
timestamp: number(),
|
|
16759
17103
|
className: string(),
|
|
16760
|
-
|
|
17104
|
+
...TieredLabelFields,
|
|
16761
17105
|
importance: number(),
|
|
16762
17106
|
/** Highest-confidence ObjectEvent id for the track (empty when none). */
|
|
16763
17107
|
bestEventId: string(),
|
|
@@ -17031,6 +17375,79 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17031
17375
|
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
17032
17376
|
kind: "query",
|
|
17033
17377
|
auth: "admin"
|
|
17378
|
+
}), method(object({
|
|
17379
|
+
/** Empty ⇒ every camera that has staging tracks. A LIST, not a single
|
|
17380
|
+
* `deviceId`, deliberately: `deviceId` would make this device-bound and
|
|
17381
|
+
* route it at one camera's owner, and "every camera" would stop being
|
|
17382
|
+
* expressible at all. */
|
|
17383
|
+
deviceIds: array(number()).optional(),
|
|
17384
|
+
limit: number().int().min(1).max(500).optional()
|
|
17385
|
+
}), array(RetrainTrackSchema).readonly(), {
|
|
17386
|
+
kind: "query",
|
|
17387
|
+
auth: "admin"
|
|
17388
|
+
}), method(object({ trackId: string() }), RetrainFrameListSchema, {
|
|
17389
|
+
kind: "query",
|
|
17390
|
+
auth: "admin"
|
|
17391
|
+
}), method(object({
|
|
17392
|
+
deviceId: number(),
|
|
17393
|
+
trackId: string(),
|
|
17394
|
+
mediaKeys: array(string()).min(1)
|
|
17395
|
+
}), RetrainFrameSelectionSchema, {
|
|
17396
|
+
kind: "mutation",
|
|
17397
|
+
auth: "admin"
|
|
17398
|
+
}), method(object({
|
|
17399
|
+
deviceId: number(),
|
|
17400
|
+
trackId: string(),
|
|
17401
|
+
frameId: string()
|
|
17402
|
+
}), object({
|
|
17403
|
+
removed: boolean(),
|
|
17404
|
+
removedAnnotations: number().int()
|
|
17405
|
+
}), {
|
|
17406
|
+
kind: "mutation",
|
|
17407
|
+
auth: "admin"
|
|
17408
|
+
}), method(object({ frameId: string() }), object({
|
|
17409
|
+
base64: string(),
|
|
17410
|
+
width: number().int(),
|
|
17411
|
+
height: number().int()
|
|
17412
|
+
}), {
|
|
17413
|
+
kind: "query",
|
|
17414
|
+
auth: "admin"
|
|
17415
|
+
}), method(object({
|
|
17416
|
+
deviceId: number(),
|
|
17417
|
+
trackId: string(),
|
|
17418
|
+
frameId: string(),
|
|
17419
|
+
subject: RetrainAssistSubjectSchema,
|
|
17420
|
+
/** Which node runs it. Absent ⇒ wherever an unowned call lands. */
|
|
17421
|
+
nodeId: string().optional()
|
|
17422
|
+
}), RetrainAssistResultSchema, {
|
|
17423
|
+
kind: "mutation",
|
|
17424
|
+
auth: "admin"
|
|
17425
|
+
}), method(object({ trackId: string() }), array(RetrainAnnotationSchema).readonly(), {
|
|
17426
|
+
kind: "query",
|
|
17427
|
+
auth: "admin"
|
|
17428
|
+
}), method(object({
|
|
17429
|
+
deviceId: number(),
|
|
17430
|
+
trackId: string(),
|
|
17431
|
+
frameId: string(),
|
|
17432
|
+
annotations: array(RetrainAnnotationDraftSchema)
|
|
17433
|
+
}), array(RetrainAnnotationSchema).readonly(), {
|
|
17434
|
+
kind: "mutation",
|
|
17435
|
+
auth: "admin"
|
|
17436
|
+
}), method(object({
|
|
17437
|
+
deviceId: number(),
|
|
17438
|
+
trackId: string()
|
|
17439
|
+
}), RetrainTransitionResultSchema, {
|
|
17440
|
+
kind: "mutation",
|
|
17441
|
+
auth: "admin"
|
|
17442
|
+
}), method(object({
|
|
17443
|
+
deviceId: number(),
|
|
17444
|
+
trackId: string()
|
|
17445
|
+
}), RetrainTransitionResultSchema, {
|
|
17446
|
+
kind: "mutation",
|
|
17447
|
+
auth: "admin"
|
|
17448
|
+
}), method(object({ deviceIds: array(number()).optional() }), object({ url: string() }), {
|
|
17449
|
+
kind: "query",
|
|
17450
|
+
auth: "admin"
|
|
17034
17451
|
}), method(object({
|
|
17035
17452
|
eventId: string(),
|
|
17036
17453
|
kind: MediaFileKindEnum.optional()
|
|
@@ -17762,6 +18179,22 @@ var DetailResultSchema = object({
|
|
|
17762
18179
|
bbox: NativeCropBboxSchema.optional(),
|
|
17763
18180
|
embedding: string().optional(),
|
|
17764
18181
|
label: string().optional(),
|
|
18182
|
+
/**
|
|
18183
|
+
* The tier `label` occupies, copied VERBATIM from the producing step's
|
|
18184
|
+
* `StepDefinition.labelTier` (roadmap 4g). Present only when `label` is.
|
|
18185
|
+
*
|
|
18186
|
+
* It rides the wire rather than being resolved by the consumer because the
|
|
18187
|
+
* declaration lives with the step definition, which only the executing node
|
|
18188
|
+
* has: post-analysis holds no step registry, and re-deriving the tier from
|
|
18189
|
+
* `className` there would be exactly the inference this model exists to
|
|
18190
|
+
* forbid. A `label` that arrives WITHOUT this field is refused by the write
|
|
18191
|
+
* rule and logged (`label tier undeclared`) — an older runner therefore
|
|
18192
|
+
* stops enriching rather than guessing, which is why addon-pipeline is
|
|
18193
|
+
* deployed BEFORE addon-post-analysis.
|
|
18194
|
+
*/
|
|
18195
|
+
labelTier: union([literal(1), literal(2)]).optional(),
|
|
18196
|
+
/** Model that produced `label` — carried into the tier's attribution. */
|
|
18197
|
+
labelModelId: string().optional(),
|
|
17765
18198
|
alignedCropJpeg: string().optional(),
|
|
17766
18199
|
/** Face short side (px) measured on the NATIVE crop surface. The `bbox`
|
|
17767
18200
|
* above is detection-frame px (≈6× smaller on a 4K camera) — min-face-size
|
|
@@ -28417,6 +28850,12 @@ Object.freeze({
|
|
|
28417
28850
|
addonId: null,
|
|
28418
28851
|
access: "delete"
|
|
28419
28852
|
},
|
|
28853
|
+
"pipelineAnalytics.completeRetrainTrack": {
|
|
28854
|
+
capName: "pipeline-analytics",
|
|
28855
|
+
capScope: "device",
|
|
28856
|
+
addonId: null,
|
|
28857
|
+
access: "create"
|
|
28858
|
+
},
|
|
28420
28859
|
"pipelineAnalytics.deleteDeviceEvents": {
|
|
28421
28860
|
capName: "pipeline-analytics",
|
|
28422
28861
|
capScope: "device",
|
|
@@ -28429,6 +28868,12 @@ Object.freeze({
|
|
|
28429
28868
|
addonId: null,
|
|
28430
28869
|
access: "delete"
|
|
28431
28870
|
},
|
|
28871
|
+
"pipelineAnalytics.deselectRetrainFrame": {
|
|
28872
|
+
capName: "pipeline-analytics",
|
|
28873
|
+
capScope: "device",
|
|
28874
|
+
addonId: null,
|
|
28875
|
+
access: "create"
|
|
28876
|
+
},
|
|
28432
28877
|
"pipelineAnalytics.getActiveTracks": {
|
|
28433
28878
|
capName: "pipeline-analytics",
|
|
28434
28879
|
capScope: "device",
|
|
@@ -28489,6 +28934,18 @@ Object.freeze({
|
|
|
28489
28934
|
addonId: null,
|
|
28490
28935
|
access: "view"
|
|
28491
28936
|
},
|
|
28937
|
+
"pipelineAnalytics.getRetrainExportUrl": {
|
|
28938
|
+
capName: "pipeline-analytics",
|
|
28939
|
+
capScope: "device",
|
|
28940
|
+
addonId: null,
|
|
28941
|
+
access: "view"
|
|
28942
|
+
},
|
|
28943
|
+
"pipelineAnalytics.getRetrainFrameImage": {
|
|
28944
|
+
capName: "pipeline-analytics",
|
|
28945
|
+
capScope: "device",
|
|
28946
|
+
addonId: null,
|
|
28947
|
+
access: "view"
|
|
28948
|
+
},
|
|
28492
28949
|
"pipelineAnalytics.getSensorEvents": {
|
|
28493
28950
|
capName: "pipeline-analytics",
|
|
28494
28951
|
capScope: "device",
|
|
@@ -28543,6 +29000,24 @@ Object.freeze({
|
|
|
28543
29000
|
addonId: null,
|
|
28544
29001
|
access: "view"
|
|
28545
29002
|
},
|
|
29003
|
+
"pipelineAnalytics.listRetrainAnnotations": {
|
|
29004
|
+
capName: "pipeline-analytics",
|
|
29005
|
+
capScope: "device",
|
|
29006
|
+
addonId: null,
|
|
29007
|
+
access: "view"
|
|
29008
|
+
},
|
|
29009
|
+
"pipelineAnalytics.listRetrainFrames": {
|
|
29010
|
+
capName: "pipeline-analytics",
|
|
29011
|
+
capScope: "device",
|
|
29012
|
+
addonId: null,
|
|
29013
|
+
access: "view"
|
|
29014
|
+
},
|
|
29015
|
+
"pipelineAnalytics.listRetrainStaging": {
|
|
29016
|
+
capName: "pipeline-analytics",
|
|
29017
|
+
capScope: "device",
|
|
29018
|
+
addonId: null,
|
|
29019
|
+
access: "view"
|
|
29020
|
+
},
|
|
28546
29021
|
"pipelineAnalytics.listTrackMedia": {
|
|
28547
29022
|
capName: "pipeline-analytics",
|
|
28548
29023
|
capScope: "device",
|
|
@@ -28555,6 +29030,12 @@ Object.freeze({
|
|
|
28555
29030
|
addonId: null,
|
|
28556
29031
|
access: "view"
|
|
28557
29032
|
},
|
|
29033
|
+
"pipelineAnalytics.proposeRetrainAnnotations": {
|
|
29034
|
+
capName: "pipeline-analytics",
|
|
29035
|
+
capScope: "device",
|
|
29036
|
+
addonId: null,
|
|
29037
|
+
access: "create"
|
|
29038
|
+
},
|
|
28558
29039
|
"pipelineAnalytics.pruneEvents": {
|
|
28559
29040
|
capName: "pipeline-analytics",
|
|
28560
29041
|
capScope: "device",
|
|
@@ -28585,12 +29066,30 @@ Object.freeze({
|
|
|
28585
29066
|
addonId: null,
|
|
28586
29067
|
access: "create"
|
|
28587
29068
|
},
|
|
29069
|
+
"pipelineAnalytics.restageRetrainTrack": {
|
|
29070
|
+
capName: "pipeline-analytics",
|
|
29071
|
+
capScope: "device",
|
|
29072
|
+
addonId: null,
|
|
29073
|
+
access: "create"
|
|
29074
|
+
},
|
|
29075
|
+
"pipelineAnalytics.saveRetrainAnnotations": {
|
|
29076
|
+
capName: "pipeline-analytics",
|
|
29077
|
+
capScope: "device",
|
|
29078
|
+
addonId: null,
|
|
29079
|
+
access: "create"
|
|
29080
|
+
},
|
|
28588
29081
|
"pipelineAnalytics.searchObjectEvents": {
|
|
28589
29082
|
capName: "pipeline-analytics",
|
|
28590
29083
|
capScope: "device",
|
|
28591
29084
|
addonId: null,
|
|
28592
29085
|
access: "view"
|
|
28593
29086
|
},
|
|
29087
|
+
"pipelineAnalytics.selectRetrainFrames": {
|
|
29088
|
+
capName: "pipeline-analytics",
|
|
29089
|
+
capScope: "device",
|
|
29090
|
+
addonId: null,
|
|
29091
|
+
access: "create"
|
|
29092
|
+
},
|
|
28594
29093
|
"pipelineAnalytics.setTrackFlags": {
|
|
28595
29094
|
capName: "pipeline-analytics",
|
|
28596
29095
|
capScope: "device",
|
|
@@ -29983,6 +30482,12 @@ Object.freeze({
|
|
|
29983
30482
|
addonId: null,
|
|
29984
30483
|
access: "create"
|
|
29985
30484
|
},
|
|
30485
|
+
"streamBroker.fetchEventMedia": {
|
|
30486
|
+
capName: "stream-broker",
|
|
30487
|
+
capScope: "system",
|
|
30488
|
+
addonId: null,
|
|
30489
|
+
access: "create"
|
|
30490
|
+
},
|
|
29986
30491
|
"streamBroker.getAllRtspEntries": {
|
|
29987
30492
|
capName: "stream-broker",
|
|
29988
30493
|
capScope: "system",
|
|
@@ -30067,6 +30572,12 @@ Object.freeze({
|
|
|
30067
30572
|
addonId: null,
|
|
30068
30573
|
access: "create"
|
|
30069
30574
|
},
|
|
30575
|
+
"streamBroker.produceEventMedia": {
|
|
30576
|
+
capName: "stream-broker",
|
|
30577
|
+
capScope: "system",
|
|
30578
|
+
addonId: null,
|
|
30579
|
+
access: "create"
|
|
30580
|
+
},
|
|
30070
30581
|
"streamBroker.publishCameraStream": {
|
|
30071
30582
|
capName: "stream-broker",
|
|
30072
30583
|
capScope: "system",
|
package/dist/{event-loop-stall-monitor-IAuNEdmG.mjs → event-loop-stall-monitor-B_XUPTwp.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-
|
|
1
|
+
import { L as hfModelUrl, a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS } from "./dist-CfxC7XoI.mjs";
|
|
2
2
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
3
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
4
|
var HF_REPO = "camstack/camstack-models";
|
|
@@ -1258,6 +1258,7 @@ var ObjectDetectionStep = class {
|
|
|
1258
1258
|
"animal",
|
|
1259
1259
|
"package"
|
|
1260
1260
|
],
|
|
1261
|
+
labelTier: 1,
|
|
1261
1262
|
models: [...OBJECT_DETECTION_MODELS],
|
|
1262
1263
|
defaultModelId: "yolo26n",
|
|
1263
1264
|
defaultModelIdByFormat: { tflite: "ssd-mobilenet-v2-coco-edgetpu" },
|
|
@@ -1427,6 +1428,7 @@ var AnimalClassifierStep = class {
|
|
|
1427
1428
|
extractMode: "crop-roi",
|
|
1428
1429
|
inputClasses: ["animal"],
|
|
1429
1430
|
outputClasses: ["animal-type"],
|
|
1431
|
+
labelTier: 1,
|
|
1430
1432
|
models: [...ANIMAL_CLASSIFIER_MODELS],
|
|
1431
1433
|
defaultModelId: "animal-classifier",
|
|
1432
1434
|
enabledByDefault: false,
|
|
@@ -1605,6 +1607,7 @@ var STEP_FACE_EMBEDDING = new PipelineStepBase({
|
|
|
1605
1607
|
extractMode: "crop-roi",
|
|
1606
1608
|
inputClasses: ["face"],
|
|
1607
1609
|
outputClasses: ["identity"],
|
|
1610
|
+
labelTier: 2,
|
|
1608
1611
|
models: [...FACE_EMBEDDING_MODELS],
|
|
1609
1612
|
defaultModelId: "arcface-r100",
|
|
1610
1613
|
defaultConfidence: 0,
|
|
@@ -1661,6 +1664,7 @@ var STEP_PLATE_OCR = new PlateOcrStep({
|
|
|
1661
1664
|
extractMode: "crop-roi",
|
|
1662
1665
|
inputClasses: ["plate"],
|
|
1663
1666
|
outputClasses: ["plate-text"],
|
|
1667
|
+
labelTier: 2,
|
|
1664
1668
|
models: [...PLATE_OCR_MODELS],
|
|
1665
1669
|
defaultModelId: "vgg-english-g2",
|
|
1666
1670
|
defaultConfidence: 0,
|
|
@@ -1695,6 +1699,7 @@ var STEP_BIRD_CLASSIFIER = new ClassifierWithMinConfidence({
|
|
|
1695
1699
|
extractMode: "crop-roi",
|
|
1696
1700
|
inputClasses: ["animal"],
|
|
1697
1701
|
outputClasses: ["species"],
|
|
1702
|
+
labelTier: 2,
|
|
1698
1703
|
models: [...BIRD_CLASSIFIER_MODELS],
|
|
1699
1704
|
defaultModelId: "bird-classifier",
|
|
1700
1705
|
enabledByDefault: false,
|
|
@@ -1714,6 +1719,7 @@ var STEP_VEHICLE_CLASSIFIER = new ClassifierWithMinConfidence({
|
|
|
1714
1719
|
extractMode: "crop-roi",
|
|
1715
1720
|
inputClasses: ["vehicle"],
|
|
1716
1721
|
outputClasses: ["vehicle-type"],
|
|
1722
|
+
labelTier: 1,
|
|
1717
1723
|
models: [...VEHICLE_CLASSIFIER_MODELS],
|
|
1718
1724
|
defaultModelId: "vehicle-type-v1",
|
|
1719
1725
|
enabledByDefault: false,
|