@camstack/addon-pipeline 1.1.55 → 1.1.57

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.
Files changed (46) hide show
  1. package/dist/audio-analyzer/index.js +2 -2
  2. package/dist/audio-analyzer/index.mjs +2 -2
  3. package/dist/detection-pipeline/index.js +92 -88
  4. package/dist/detection-pipeline/index.mjs +91 -87
  5. package/dist/{dist-DI57FC8K.js → dist-CK8Ur-OS.js} +1045 -43
  6. package/dist/{dist-RWGGPwVx.mjs → dist-CL531uVA.mjs} +1045 -43
  7. package/dist/motion-wasm/index.js +9 -41
  8. package/dist/motion-wasm/index.mjs +9 -41
  9. package/dist/pipeline-runner/index.js +338 -664
  10. package/dist/pipeline-runner/index.mjs +327 -655
  11. package/dist/recorder/index.js +2 -2
  12. package/dist/recorder/index.mjs +2 -2
  13. package/dist/remote-restream-BeHi78PZ.mjs +25 -0
  14. package/dist/remote-restream-CO36Sr30.js +36 -0
  15. package/dist/session-decode/decode-worker-child.js +5 -3
  16. package/dist/session-decode/decode-worker-child.mjs +5 -3
  17. package/dist/{step-definitions-CP9kVSml.mjs → step-definitions-1d3_vQ6S.mjs} +45 -3
  18. package/dist/{step-definitions-CNBFKjZe.js → step-definitions-DHAxruAQ.js} +45 -3
  19. package/dist/stream-broker/_stub.js +351 -291
  20. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-mDCPzmT3.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Cm_B-hQT.mjs} +2 -2
  21. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Ba7Eyd47.mjs +26 -0
  22. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Dn_pxzP-.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-TWCUWhCm.mjs} +2 -2
  23. package/dist/stream-broker/{hostInit-GM_CI22k.mjs → hostInit-DEaqJpGA.mjs} +2 -2
  24. package/dist/stream-broker/index.js +935 -38
  25. package/dist/stream-broker/index.mjs +932 -35
  26. package/dist/stream-broker/remoteEntry.js +1 -1
  27. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-BChW0ntM.js → MaskShapeCanvas-DI4BY7W2-CZUzu3MF.js} +1 -1
  28. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-DDzqEbSe.js → MotionZonesSettings-NcxxQN8r-CmZbzLQi.js} +1 -1
  29. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-B879GXaf.js → PrivacyMaskSettings-APgPLF7p-BOKDrH0N.js} +1 -1
  30. package/embed-dist/assets/index-Bmpl9O1K.css +2 -0
  31. package/embed-dist/assets/index-DOsK8CZb.js +81 -0
  32. package/embed-dist/index.html +2 -2
  33. package/package.json +7 -5
  34. package/python/inference_pool.py +183 -29
  35. package/python/postprocessors/__init__.py +2 -0
  36. package/python/postprocessors/ssd.py +128 -0
  37. package/python/requirements-edgetpu.txt +23 -0
  38. package/python/test_inference_pool_layout.py +16 -1
  39. package/python/test_inference_pool_preprocess.py +65 -0
  40. package/dist/remote-source-plane-CHgvzzA6.js +0 -1030
  41. package/dist/remote-source-plane-DU0aRSPv.mjs +0 -1001
  42. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-B3gTdHEh.mjs +0 -26
  43. package/embed-dist/assets/index-CC06JBcl.css +0 -2
  44. package/embed-dist/assets/index-CNjQ5rAE.js +0 -81
  45. package/dist/{model-download-service-C-IHWnXx-BPy6aoAx.mjs → model-download-service-C-IHWnXx-3Mmeob3l.mjs} +1 -1
  46. package/dist/{model-download-service-C-IHWnXx-BLXzxpRB.js → model-download-service-C-IHWnXx-D326YNnt.js} +1 -1
@@ -4286,6 +4286,14 @@ function object(shape, params) {
4286
4286
  ...normalizeParams(params)
4287
4287
  });
4288
4288
  }
4289
+ function looseObject(shape, params) {
4290
+ return new ZodObject({
4291
+ type: "object",
4292
+ shape,
4293
+ catchall: unknown(),
4294
+ ...normalizeParams(params)
4295
+ });
4296
+ }
4289
4297
  var ZodUnion = /*@__PURE__*/ $constructor("ZodUnion", (inst, def) => {
4290
4298
  $ZodUnion.init(inst, def);
4291
4299
  ZodType.init(inst, def);
@@ -4627,7 +4635,7 @@ function _instanceof(cls, params = {}) {
4627
4635
  return inst;
4628
4636
  }
4629
4637
  //#endregion
4630
- //#region ../types/dist/sleep-Baang_XW.mjs
4638
+ //#region ../types/dist/sleep-_sv7WKkq.mjs
4631
4639
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4632
4640
  EventCategory["SystemBoot"] = "system.boot";
4633
4641
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5037,10 +5045,51 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
5037
5045
  EventCategory["EnrichmentEmbeddingStored"] = "enrichment.embedding.stored";
5038
5046
  EventCategory["EnrichmentSceneStateChanged"] = "enrichment.scene.state-changed";
5039
5047
  EventCategory["EnrichmentActivitySummary"] = "enrichment.activity.summary";
5048
+ /**
5049
+ * Unified track-lifecycle event: ONE category carrying `phase:
5050
+ * 'start' | 'update' | 'end'` with a rich, typed
5051
+ * `PipelineAnalyticsTrackLifecyclePayload`. Supersedes the thin
5052
+ * `PipelineAnalyticsTrackStarted` / `PipelineAnalyticsTrackEnded`
5053
+ * pair — a consumer subscribes once and branches on `phase`.
5054
+ */
5055
+ EventCategory["PipelineAnalyticsTrackLifecycle"] = "pipeline-analytics.track-lifecycle";
5056
+ /**
5057
+ * @deprecated Superseded by {@link PipelineAnalyticsTrackLifecycle}
5058
+ * (`phase:'start'`). Kept as a soft alias — no known subscribers.
5059
+ */
5040
5060
  EventCategory["PipelineAnalyticsTrackStarted"] = "pipeline-analytics.track-started";
5061
+ /**
5062
+ * @deprecated Superseded by {@link PipelineAnalyticsTrackLifecycle}
5063
+ * (`phase:'end'`). Kept as a soft alias — no known subscribers.
5064
+ */
5041
5065
  EventCategory["PipelineAnalyticsTrackEnded"] = "pipeline-analytics.track-ended";
5042
5066
  EventCategory["PipelineAnalyticsDetectionEvent"] = "pipeline-analytics.detection-event";
5043
5067
  EventCategory["PipelineAnalyticsFrameTracked"] = "pipeline-analytics.frame-tracked";
5068
+ /**
5069
+ * Fired by `addon-post-analysis` when a parked (stationary) object appears
5070
+ * (a track was promoted to a stationary-registry entry) or departs (the
5071
+ * object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
5072
+ * the dedicated "Stationary" section — never the live event feed. Payload:
5073
+ * `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
5074
+ */
5075
+ EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
5076
+ /**
5077
+ * Fired by `addon-post-analysis` whenever a gallery face row changes:
5078
+ * `kind:'buffered'` a new detected face was persisted, `'assigned'` /
5079
+ * `'unassigned'` its identity link changed, `'deleted'` the row was
5080
+ * removed. Telemetry semantics (D8): a lost event only delays a refresh,
5081
+ * never a correctness issue. Payload `PipelineAnalyticsFaceGalleryChangedPayload`.
5082
+ */
5083
+ EventCategory["PipelineAnalyticsFaceGalleryChanged"] = "pipeline-analytics.face-gallery-changed";
5084
+ /**
5085
+ * Fired by `addon-post-analysis` whenever a gallery plate row changes:
5086
+ * `kind:'buffered'` a new read was persisted (`PlateRecognizer.onTrackEnd`),
5087
+ * `'assigned'` / `'unassigned'` its vehicle link changed
5088
+ * (`PlateGalleryProvider`), `'deleted'` the row was removed. Telemetry
5089
+ * semantics (D8): a lost event only delays a refresh, never a correctness
5090
+ * issue. Payload `PipelineAnalyticsPlateGalleryChangedPayload`.
5091
+ */
5092
+ EventCategory["PipelineAnalyticsPlateGalleryChanged"] = "pipeline-analytics.plate-gallery-changed";
5044
5093
  EventCategory["FrigateLiveEvent"] = "frigate.live-event";
5045
5094
  EventCategory["CameraStreamsProfileSlotsChanged"] = "camera-streams.onProfileSlotsChanged";
5046
5095
  /**
@@ -7009,7 +7058,8 @@ var MODEL_FORMATS = [
7009
7058
  "coreml",
7010
7059
  "openvino",
7011
7060
  "tflite",
7012
- "pt"
7061
+ "pt",
7062
+ "gguf"
7013
7063
  ];
7014
7064
  /**
7015
7065
  * Multi-file format payload.
@@ -7053,7 +7103,8 @@ var ModelFormatsSchema = object({
7053
7103
  coreml: ModelFormatEntrySchema.optional(),
7054
7104
  openvino: ModelFormatEntrySchema.optional(),
7055
7105
  tflite: ModelFormatEntrySchema.optional(),
7056
- pt: ModelFormatEntrySchema.optional()
7106
+ pt: ModelFormatEntrySchema.optional(),
7107
+ gguf: ModelFormatEntrySchema.optional()
7057
7108
  });
7058
7109
  /**
7059
7110
  * Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
@@ -7094,6 +7145,15 @@ var ModelCatalogEntrySchema = object({
7094
7145
  width: number(),
7095
7146
  height: number()
7096
7147
  }),
7148
+ /**
7149
+ * Channel count of the model input tensor. Omit ⇒ 3 (RGB), the default for
7150
+ * every detector / classifier / embedder. Set to 1 for a grayscale CTC text
7151
+ * recognizer (EasyOCR VGG plate-OCR: input `[N,1,H,W]`) so the preprocess
7152
+ * feeds a single-channel, EasyOCR-normalized tensor instead of the default
7153
+ * 3-channel RGB one. Threaded through `PoolModelConfig.inputChannels` to the
7154
+ * Python inference pool.
7155
+ */
7156
+ inputChannels: number().int().positive().optional(),
7097
7157
  labels: array(LabelDefinitionSchema).readonly(),
7098
7158
  inputLayout: _enum(["nchw", "nhwc"]).optional(),
7099
7159
  inputNormalization: _enum([
@@ -7103,6 +7163,16 @@ var ModelCatalogEntrySchema = object({
7103
7163
  ]).optional(),
7104
7164
  preprocessMode: _enum(["letterbox", "resize"]).optional(),
7105
7165
  /**
7166
+ * Per-MODEL postprocessor override. Absent ⇒ the step's own
7167
+ * `StepDefinition.postprocessor` applies (the normal case — every model in a
7168
+ * step shares its decode). Set it when a step hosts models with DIFFERENT raw
7169
+ * output layouts under one slot: e.g. object-detection is `'yolo'` by default,
7170
+ * but a Coral SSD MobileNet build emits the `TFLite_Detection_PostProcess`
7171
+ * 4-tensor layout and needs `'ssd'`. Threaded into `PoolModelConfig.postprocessor`
7172
+ * by the engine factory (`modelEntry.postprocessor ?? def.postprocessor`).
7173
+ */
7174
+ postprocessor: custom().optional(),
7175
+ /**
7106
7176
  * When true, the executor produces a landmark-aligned crop (similarity warp
7107
7177
  * onto the canonical template) before this step runs, instead of a plain
7108
7178
  * axis-aligned bbox crop. Required for face-recognition embedders (ArcFace):
@@ -11347,7 +11417,8 @@ var ModelFormatSchema$1 = _enum([
11347
11417
  "coreml",
11348
11418
  "openvino",
11349
11419
  "tflite",
11350
- "pt"
11420
+ "pt",
11421
+ "gguf"
11351
11422
  ]);
11352
11423
  var PipelineSlotSchema = _enum([
11353
11424
  "detector",
@@ -11441,7 +11512,8 @@ var EngineProvisioningSchema = object({
11441
11512
  runtimeId: _enum([
11442
11513
  "onnx",
11443
11514
  "openvino",
11444
- "coreml"
11515
+ "coreml",
11516
+ "edgetpu"
11445
11517
  ]).nullable(),
11446
11518
  device: string().nullable(),
11447
11519
  state: _enum([
@@ -12891,6 +12963,140 @@ DeviceType.Camera, method(object({ deviceId: number() }), PtzAutotrackStatusSche
12891
12963
  deviceId: number(),
12892
12964
  status: PtzAutotrackStatusSchema
12893
12965
  });
12966
+ /**
12967
+ * scene-monitor — device-scoped reference-region state cap. An operator marks
12968
+ * a rect ROI on a camera frame and names one or more states; the engine
12969
+ * (pipeline-analytics, designated post-processing node) reports which state is
12970
+ * active on an ongoing basis. Two operator-selectable check modes share every-
12971
+ * thing except the comparator: `similarity` (CLIP cosine at the same ROI coords
12972
+ * vs condition-tagged references) and `llm` (vision-LLM judgment over the crop).
12973
+ *
12974
+ * D14 device-config archetype (`deviceConfig.ui.kind:'widget'`) — the framework
12975
+ * derives the device-detail contribution; the provider carries NO hand-written
12976
+ * settings-contribution methods. `status.kind:'push'` — the engine pushes on
12977
+ * every hysteresis flip / availability change; consumers never poll.
12978
+ */
12979
+ /** Extensible condition tag. Seeded 'day' | 'night'; open by design so more can
12980
+ * be added without a wire break (matching falls back to any-condition refs). */
12981
+ var SceneConditionSchema = string();
12982
+ /** One captured reference — condition-tagged, model-version-gated. `embedding`
12983
+ * is `number[]` (Float32Array does NOT survive MsgPack/UDS). */
12984
+ var SceneReferenceSchema = object({
12985
+ embedding: array(number()),
12986
+ modelId: string(),
12987
+ condition: SceneConditionSchema,
12988
+ capturedAt: number(),
12989
+ thumbnailMediaId: string().optional()
12990
+ });
12991
+ var SceneMonitorStateSchema = object({
12992
+ id: string(),
12993
+ label: string(),
12994
+ references: array(SceneReferenceSchema),
12995
+ textPrompts: array(string()).optional(),
12996
+ referenceCount: number(),
12997
+ currentlyMatched: boolean()
12998
+ });
12999
+ /** Per-mode comparator params in a discriminated union so an `llm` scene never
13000
+ * carries similarity knobs and vice-versa. */
13001
+ var SceneCheckSchema = discriminatedUnion("mode", [object({
13002
+ mode: literal("similarity"),
13003
+ threshold: number().min(0).max(1),
13004
+ hysteresisCount: number().int().positive()
13005
+ }), object({
13006
+ mode: literal("llm"),
13007
+ prompt: string(),
13008
+ profileId: string().optional(),
13009
+ hysteresisCount: number().int().positive()
13010
+ })]);
13011
+ var SceneMonitorSchema = object({
13012
+ id: string(),
13013
+ label: string(),
13014
+ roi: MaskRectShapeSchema,
13015
+ enabled: boolean(),
13016
+ triggerMode: _enum([
13017
+ "periodic",
13018
+ "on-motion",
13019
+ "both"
13020
+ ]),
13021
+ checkIntervalSec: number().optional(),
13022
+ check: SceneCheckSchema,
13023
+ states: array(SceneMonitorStateSchema),
13024
+ currentStateId: string().nullable(),
13025
+ lastCheckedAt: number().nullable(),
13026
+ lastConfidence: number().nullable(),
13027
+ currentCondition: SceneConditionSchema.nullable(),
13028
+ availability: _enum(["ok", "unavailable"]),
13029
+ unavailableReason: string().nullable()
13030
+ });
13031
+ var SceneMonitorStatusSchema = object({
13032
+ monitors: array(SceneMonitorSchema),
13033
+ lastFetchedAt: number()
13034
+ });
13035
+ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSchema), method(object({
13036
+ deviceId: number(),
13037
+ label: string(),
13038
+ roi: MaskRectShapeSchema,
13039
+ check: SceneCheckSchema,
13040
+ triggerMode: _enum([
13041
+ "periodic",
13042
+ "on-motion",
13043
+ "both"
13044
+ ]).optional(),
13045
+ checkIntervalSec: number().optional()
13046
+ }), SceneMonitorSchema, {
13047
+ kind: "mutation",
13048
+ auth: "admin"
13049
+ }), method(object({
13050
+ deviceId: number(),
13051
+ monitorId: string(),
13052
+ patch: object({
13053
+ label: string().optional(),
13054
+ roi: MaskRectShapeSchema.optional(),
13055
+ enabled: boolean().optional(),
13056
+ triggerMode: _enum([
13057
+ "periodic",
13058
+ "on-motion",
13059
+ "both"
13060
+ ]).optional(),
13061
+ checkIntervalSec: number().optional(),
13062
+ check: SceneCheckSchema.optional()
13063
+ })
13064
+ }), _void(), {
13065
+ kind: "mutation",
13066
+ auth: "admin"
13067
+ }), method(object({
13068
+ deviceId: number(),
13069
+ monitorId: string()
13070
+ }), _void(), {
13071
+ kind: "mutation",
13072
+ auth: "admin"
13073
+ }), method(object({
13074
+ deviceId: number(),
13075
+ monitorId: string(),
13076
+ stateId: string().optional(),
13077
+ label: string().optional(),
13078
+ condition: SceneConditionSchema.optional()
13079
+ }), object({
13080
+ stateId: string(),
13081
+ referenceCount: number()
13082
+ }), {
13083
+ kind: "mutation",
13084
+ auth: "admin"
13085
+ }), method(object({
13086
+ deviceId: number(),
13087
+ monitorId: string(),
13088
+ stateId: string(),
13089
+ index: number()
13090
+ }), _void(), {
13091
+ kind: "mutation",
13092
+ auth: "admin"
13093
+ }), method(object({
13094
+ deviceId: number(),
13095
+ monitorId: string()
13096
+ }), _void(), {
13097
+ kind: "mutation",
13098
+ auth: "admin"
13099
+ });
12894
13100
  object({
12895
13101
  /** Whether the script is currently executing. */
12896
13102
  isRunning: boolean(),
@@ -13298,6 +13504,36 @@ var ZoneScopeBreakdownSchema = PerScopeBreakdownSchema.extend({
13298
13504
  * with the per-track detail panel and live overlay. */
13299
13505
  trackIds: array(string()).readonly()
13300
13506
  });
13507
+ /**
13508
+ * A parked ("stationary") object surfaced alongside occupancy — an object that
13509
+ * settled and stopped moving. It is NO LONGER a tracked object (the tracker was
13510
+ * told to forget it so it stops re-spawning tracks/events), but it IS still
13511
+ * physically present, so it keeps counting toward `frame` occupancy and is
13512
+ * listed here so the UI can show it in a dedicated "Stationary" section instead
13513
+ * of flooding the live event feed.
13514
+ */
13515
+ var StationaryObjectSchema = object({
13516
+ id: string(),
13517
+ className: string(),
13518
+ bbox: object({
13519
+ x: number(),
13520
+ y: number(),
13521
+ w: number(),
13522
+ h: number()
13523
+ }),
13524
+ frameWidth: number().int().nonnegative(),
13525
+ frameHeight: number().int().nonnegative(),
13526
+ /** When the source track was first seen. */
13527
+ firstSeenAt: number().int(),
13528
+ /** When the object was recognised as parked (promotion time). */
13529
+ becameStationaryAt: number().int(),
13530
+ /** Last frame a detection confirmed the object is still there. */
13531
+ lastConfirmedAt: number().int(),
13532
+ /** Enrichment label carried from the source track (identity / plate). */
13533
+ label: string().optional(),
13534
+ /** Native-resolution key-frame media key for the parked object's best image. */
13535
+ keyFrameMediaKey: string().optional()
13536
+ });
13301
13537
  var CameraOccupancySnapshotSchema = object({
13302
13538
  /** Frame timestamp of the inference result that produced this snapshot. */
13303
13539
  ts: number().int(),
@@ -13306,10 +13542,15 @@ var CameraOccupancySnapshotSchema = object({
13306
13542
  frameHeight: number().int().nonnegative(),
13307
13543
  /** Per-zone breakdown — one entry per defined zone (user + onboard). */
13308
13544
  zones: array(ZoneScopeBreakdownSchema).readonly(),
13309
- /** Frame-wide aggregate (everywhere, regardless of zone membership). */
13545
+ /** Frame-wide aggregate (everywhere, regardless of zone membership).
13546
+ * INCLUDES currently-confirmed stationary objects (they are still present). */
13310
13547
  frame: PerScopeBreakdownSchema,
13311
13548
  /** Detections that landed outside every zone. Empty when no zones defined. */
13312
- unzoned: PerScopeBreakdownSchema
13549
+ unzoned: PerScopeBreakdownSchema,
13550
+ /** Parked objects on this camera (additive — absent on legacy snapshots).
13551
+ * Surfaced separately so the UI shows them in a dedicated section rather
13552
+ * than as repeated tracks/events. */
13553
+ stationaryObjects: array(StationaryObjectSchema).readonly().optional()
13313
13554
  });
13314
13555
  /**
13315
13556
  * Time-series resolution. The history methods return one bucket per
@@ -13985,7 +14226,12 @@ var NotificationRuleConditionsSchema = object({
13985
14226
  clipDescription: object({
13986
14227
  text: string().min(1),
13987
14228
  minSimilarity: number().min(0).max(1)
13988
- }).optional()
14229
+ }).optional(),
14230
+ /** Match events whose recognized-entity label (face identity name or plate
14231
+ * vehicle name, propagated onto `event.data.label`) is one of these values.
14232
+ * Empty/absent → unaffected (back-compat). Enables "notify me when <named
14233
+ * vehicle/person> is seen". */
14234
+ labels: array(string()).readonly().optional()
13989
14235
  });
13990
14236
  var NotificationRuleTemplateSchema = object({
13991
14237
  title: string(),
@@ -14328,11 +14574,19 @@ method(object({
14328
14574
  * login page needs NO change.
14329
14575
  *
14330
14576
  * - `widget` — a Module-Federation widget the login page mounts (via
14331
- * `loadRemoteBundle`) for an in-page ceremony. Covers the passkey
14332
- * login ceremony, which must run `@simplewebauthn/browser` INSIDE the
14333
- * addon bundle. The referenced widget also declares `preAuth: true` in
14334
- * its `addon-widgets-source` catalog entry. `auth.listLoginMethods`
14335
- * stamps a public `bundleUrl` from `addonId` + `bundle`.
14577
+ * `loadRemoteBundle`) for an in-page ceremony. `auth.listLoginMethods`
14578
+ * stamps a public `bundleUrl` from `addonId` + `bundle`. Generic
14579
+ * mechanism kept for future use; no shipped addon uses it on the login
14580
+ * page (the passkey ceremony below runs natively in the shell instead).
14581
+ *
14582
+ * - `passkey` — a declarative WebAuthn ceremony the shell renders
14583
+ * natively (`@simplewebauthn/browser` lives in `addon-admin-ui`, not in
14584
+ * a remotely-loaded bundle). Carries the addon's effective `rpId` /
14585
+ * `origin` (from its `resolveRpID()` / `resolveOrigin()`) so the shell
14586
+ * can gate visibility (IP-literal origin, hostname/rpId mismatch) WITHOUT
14587
+ * fetching any remote code pre-auth. Contribution stays unconditional —
14588
+ * enrollment state is never leaked pre-auth; visibility is a shell
14589
+ * decision.
14336
14590
  *
14337
14591
  * Every contribution carries a `stage`:
14338
14592
  * - `primary` — shown on the first credentials screen (OIDC /
@@ -14346,30 +14600,45 @@ method(object({
14346
14600
  */
14347
14601
  /** When a login method renders in the two-phase login flow. */
14348
14602
  var LoginStageEnum = _enum(["primary", "second-factor"]);
14349
- /** One login-method contribution — redirect button OR pre-auth widget. */
14350
- var LoginMethodContributionSchema = discriminatedUnion("kind", [object({
14351
- kind: literal("redirect"),
14352
- /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
14353
- id: string(),
14354
- /** Operator-facing button label. */
14355
- label: string(),
14356
- /** lucide-react icon name. */
14357
- icon: string().optional(),
14358
- /** Addon-owned HTTP route the button navigates to (GET). */
14359
- startUrl: string(),
14360
- stage: LoginStageEnum
14361
- }), object({
14362
- kind: literal("widget"),
14363
- /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
14364
- id: string(),
14365
- /** Owning addon id drives the public bundle URL + the MF namespace. */
14366
- addonId: string(),
14367
- /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
14368
- bundle: string(),
14369
- /** MF remote descriptor `{ remoteName, exposedModule, componentKey }`. */
14370
- remote: WidgetRemoteSchema,
14371
- stage: LoginStageEnum
14372
- })]);
14603
+ /** One login-method contribution — redirect button, pre-auth widget, or native passkey ceremony. */
14604
+ var LoginMethodContributionSchema = discriminatedUnion("kind", [
14605
+ object({
14606
+ kind: literal("redirect"),
14607
+ /** Stable id within the login-method set (e.g. `auth-oidc/google`). */
14608
+ id: string(),
14609
+ /** Operator-facing button label. */
14610
+ label: string(),
14611
+ /** lucide-react icon name. */
14612
+ icon: string().optional(),
14613
+ /** Addon-owned HTTP route the button navigates to (GET). */
14614
+ startUrl: string(),
14615
+ stage: LoginStageEnum
14616
+ }),
14617
+ object({
14618
+ kind: literal("widget"),
14619
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-login`). */
14620
+ id: string(),
14621
+ /** Owning addon id — drives the public bundle URL + the MF namespace. */
14622
+ addonId: string(),
14623
+ /** Bundle filename inside the addon's dist dir (`remoteEntry.js`). */
14624
+ bundle: string(),
14625
+ /** MF remote descriptor — `{ remoteName, exposedModule, componentKey }`. */
14626
+ remote: WidgetRemoteSchema,
14627
+ stage: LoginStageEnum
14628
+ }),
14629
+ object({
14630
+ kind: literal("passkey"),
14631
+ /** Stable id within the login-method set (e.g. `auth-webauthn/passkey-direct-login`). */
14632
+ id: string(),
14633
+ /** Operator-facing button label. */
14634
+ label: string(),
14635
+ stage: LoginStageEnum,
14636
+ /** Effective WebAuthn RP ID (`resolveRpID()`) — the shell gates visibility on it. */
14637
+ rpId: string(),
14638
+ /** Effective expected origin (`resolveOrigin()`), null when unconfigured. */
14639
+ origin: string().nullable()
14640
+ })
14641
+ ]);
14373
14642
  method(_void(), array(LoginMethodContributionSchema).readonly());
14374
14643
  /**
14375
14644
  * Orchestrator-side destination metadata. The orchestrator computes
@@ -16249,14 +16518,14 @@ var TargetKindCapsSchema = object({
16249
16518
  * the union is large and not meant for runtime validation here; the exported
16250
16519
  * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
16251
16520
  */
16252
- var ConfigSchemaPassthrough = unknown();
16521
+ var ConfigSchemaPassthrough$1 = unknown();
16253
16522
  var TargetKindSchema = object({
16254
16523
  kind: string(),
16255
16524
  label: string(),
16256
16525
  icon: string(),
16257
16526
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
16258
16527
  addonId: string(),
16259
- configSchema: ConfigSchemaPassthrough,
16528
+ configSchema: ConfigSchemaPassthrough$1,
16260
16529
  supportsDiscovery: boolean(),
16261
16530
  caps: TargetKindCapsSchema
16262
16531
  });
@@ -16309,6 +16578,298 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
16309
16578
  enabled: boolean()
16310
16579
  }), _void(), { kind: "mutation" });
16311
16580
  /**
16581
+ * Shared LLM generate contracts — imported by BOTH `llm.cap.ts` (consumer
16582
+ * surface) and `llm-runtime.cap.ts` (node-side managed executor) so the two
16583
+ * caps stay wire-compatible without a circular cap→cap import.
16584
+ *
16585
+ * Errors are a discriminated-union RESULT, never thrown: the shape survives
16586
+ * every transport tier structurally, and failed calls still write usage rows.
16587
+ * Token counts only in v1 — no costUsd (operator decision, 2026-07-15).
16588
+ */
16589
+ var LlmUsageSchema = object({
16590
+ inputTokens: number(),
16591
+ outputTokens: number()
16592
+ });
16593
+ var LlmErrorCodeSchema = _enum([
16594
+ "timeout",
16595
+ "rate-limited",
16596
+ "auth",
16597
+ "refusal",
16598
+ "bad-request",
16599
+ "unavailable",
16600
+ "no-profile",
16601
+ "budget-exceeded",
16602
+ "adapter-error"
16603
+ ]);
16604
+ var LlmGenerateResultSchema = discriminatedUnion("ok", [object({
16605
+ ok: literal(true),
16606
+ text: string(),
16607
+ model: string(),
16608
+ usage: LlmUsageSchema,
16609
+ truncated: boolean(),
16610
+ latencyMs: number()
16611
+ }), object({
16612
+ ok: literal(false),
16613
+ code: LlmErrorCodeSchema,
16614
+ message: string(),
16615
+ retryAfterMs: number().optional()
16616
+ })]);
16617
+ /**
16618
+ * `Uint8Array` is the sanctioned binary convention — superjson + the UDS
16619
+ * MsgPack channel round-trip typed arrays (embedding-encoder.cap.ts:29,
16620
+ * notification-output.cap.ts:27-31 precedents).
16621
+ */
16622
+ var LlmImageSchema = object({
16623
+ bytes: _instanceof(Uint8Array),
16624
+ mimeType: string()
16625
+ });
16626
+ var LlmGenerateBaseInputSchema = object({
16627
+ /** Collection routing (the notification-output posture). */
16628
+ addonId: string().optional(),
16629
+ /** Explicit profile; else the resolution chain (spec §3). */
16630
+ profileId: string().optional(),
16631
+ /** MANDATORY usage tag: 'ai-summary', 'notifier-rules', 'adhoc-ui', … */
16632
+ consumer: string(),
16633
+ system: string().optional(),
16634
+ /** v1: single-turn. `messages[]` is a v2 additive field. */
16635
+ prompt: string(),
16636
+ /** Structured output — adapter-mapped (response_format / forced tool / responseSchema). */
16637
+ jsonSchema: record(string(), unknown()).optional(),
16638
+ /** Per-call override of the profile default. */
16639
+ maxTokens: number().int().positive().optional(),
16640
+ temperature: number().optional()
16641
+ });
16642
+ /**
16643
+ * `llm-runtime` — node-side managed llama.cpp executor (spec §4). Registered
16644
+ * on EVERY node where `addon-ai` is installed; the hub `llm` provider reaches
16645
+ * a specific node's runtime with `nodePin(profile.runtime.nodeId)` — normal
16646
+ * cap routing, zero bespoke plumbing. `internal: true`: the operator reaches
16647
+ * this only through the `llm` cap's methods.
16648
+ *
16649
+ * One running llama-server child per node in v1 (models are RAM-heavy).
16650
+ * Resource ceiling = llama-server flags + idleStopMinutes ONLY (no RSS
16651
+ * watchdog — operator decision #3).
16652
+ */
16653
+ var ManagedModelRefSchema = discriminatedUnion("kind", [
16654
+ object({
16655
+ kind: literal("catalog"),
16656
+ catalogId: string()
16657
+ }),
16658
+ object({
16659
+ kind: literal("url"),
16660
+ url: string(),
16661
+ sha256: string().optional()
16662
+ }),
16663
+ object({
16664
+ kind: literal("path"),
16665
+ path: string()
16666
+ })
16667
+ ]);
16668
+ var ManagedRuntimeConfigSchema = object({
16669
+ /** WHERE the runtime lives — hub or any agent. */
16670
+ nodeId: string(),
16671
+ /** Closed for v1; 'ollama' is a v2 candidate. */
16672
+ engine: _enum(["llama-cpp"]),
16673
+ model: ManagedModelRefSchema,
16674
+ contextSize: number().int().default(4096),
16675
+ /** 0 = CPU-only. */
16676
+ gpuLayers: number().int().default(0),
16677
+ /** Default: cpus-2, clamped ≥1 (resolved node-side). */
16678
+ threads: number().int().optional(),
16679
+ /** Concurrent slots. */
16680
+ parallel: number().int().default(1),
16681
+ /** Else lazy: first generate boots it. */
16682
+ autoStart: boolean().default(false),
16683
+ /** 0 = never; frees RAM after quiet periods. */
16684
+ idleStopMinutes: number().int().default(30)
16685
+ });
16686
+ var LlmRuntimeStatusSchema = object({
16687
+ /** Status is ALWAYS node-qualified. */
16688
+ nodeId: string(),
16689
+ state: _enum([
16690
+ "stopped",
16691
+ "downloading",
16692
+ "starting",
16693
+ "ready",
16694
+ "crashed",
16695
+ "failed"
16696
+ ]),
16697
+ pid: number().optional(),
16698
+ port: number().optional(),
16699
+ modelPath: string().optional(),
16700
+ modelId: string().optional(),
16701
+ downloadProgress: number().min(0).max(1).optional(),
16702
+ lastError: string().optional(),
16703
+ crashesInWindow: number(),
16704
+ /** Child RSS (sampled best-effort). */
16705
+ memoryBytes: number().optional(),
16706
+ vramBytes: number().optional()
16707
+ });
16708
+ var LlmNodeModelSchema = object({
16709
+ file: string(),
16710
+ sizeBytes: number(),
16711
+ catalogId: string().optional(),
16712
+ installedAt: number().optional()
16713
+ });
16714
+ var LlmRuntimeDiskUsageSchema = object({
16715
+ nodeId: string(),
16716
+ modelsBytes: number(),
16717
+ freeBytes: number().optional()
16718
+ });
16719
+ method(LlmGenerateBaseInputSchema.extend({
16720
+ images: array(LlmImageSchema).optional(),
16721
+ runtime: ManagedRuntimeConfigSchema,
16722
+ /** The managed profile's timeout, threaded by the hub provider. */
16723
+ timeoutMs: number().int().positive().optional()
16724
+ }), LlmGenerateResultSchema, { kind: "mutation" }), method(object({ runtime: ManagedRuntimeConfigSchema }), LlmRuntimeStatusSchema, {
16725
+ kind: "mutation",
16726
+ auth: "admin"
16727
+ }), method(object({}), _void(), {
16728
+ kind: "mutation",
16729
+ auth: "admin"
16730
+ }), method(object({}), LlmRuntimeStatusSchema), method(object({ model: ManagedModelRefSchema }), _void(), {
16731
+ kind: "mutation",
16732
+ auth: "admin"
16733
+ }), method(object({ file: string() }), _void(), {
16734
+ kind: "mutation",
16735
+ auth: "admin"
16736
+ }), method(object({}), array(LlmNodeModelSchema)), method(object({}), LlmRuntimeDiskUsageSchema);
16737
+ /**
16738
+ * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
16739
+ * methods concat-fan across providers; single-row methods route to ONE
16740
+ * provider by the `addonId` in the call input (the notification-output
16741
+ * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
16742
+ * (hub-placed); the cap stays open for future providers.
16743
+ *
16744
+ * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
16745
+ * `apiKey` is a password field — providers REDACT it on read and merge on
16746
+ * write; a stored key NEVER round-trips to a client.
16747
+ */
16748
+ var LlmProfileKindSchema = _enum([
16749
+ "openai-compatible",
16750
+ "openai",
16751
+ "anthropic",
16752
+ "google",
16753
+ "managed-local"
16754
+ ]);
16755
+ var LlmProfileSchema = object({
16756
+ id: string(),
16757
+ name: string(),
16758
+ kind: LlmProfileKindSchema,
16759
+ /** Stamped by the provider — keeps the fanned catalog routable. */
16760
+ addonId: string(),
16761
+ enabled: boolean(),
16762
+ /** Vendor model id, or the managed runtime's loaded model. */
16763
+ model: string(),
16764
+ /** Required for openai-compatible; override for cloud kinds. */
16765
+ baseUrl: string().optional(),
16766
+ /** ConfigUISchema type:'password' — never round-trips (spec §5). */
16767
+ apiKey: string().optional(),
16768
+ supportsVision: boolean(),
16769
+ temperature: number().min(0).max(2).optional(),
16770
+ maxTokens: number().int().positive().optional(),
16771
+ timeoutMs: number().int().positive().default(6e4),
16772
+ extraHeaders: record(string(), string()).optional(),
16773
+ /** kind === 'managed-local' only (spec §4). */
16774
+ runtime: ManagedRuntimeConfigSchema.optional()
16775
+ });
16776
+ /** ConfigUISchema tree passed through untyped on the wire (the
16777
+ * notification-output `ConfigSchemaPassthrough` precedent at
16778
+ * notification-output.cap.ts:151); the exported TS type re-tightens it. */
16779
+ var ConfigSchemaPassthrough = unknown();
16780
+ var LlmProfileKindDescriptorSchema = object({
16781
+ kind: LlmProfileKindSchema,
16782
+ label: string(),
16783
+ icon: string(),
16784
+ /** Stamped by each provider so the concat-fanned catalog stays routable. */
16785
+ addonId: string(),
16786
+ configSchema: ConfigSchemaPassthrough
16787
+ });
16788
+ var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
16789
+ var LlmDefaultSchema = object({
16790
+ selector: LlmDefaultSelectorSchema,
16791
+ profileId: string()
16792
+ });
16793
+ /** Server-side rollup row — getUsage never dumps raw call rows (spec §6). */
16794
+ var LlmUsageRollupSchema = object({
16795
+ day: string(),
16796
+ consumer: string(),
16797
+ profileId: string(),
16798
+ calls: number(),
16799
+ okCalls: number(),
16800
+ errorCalls: number(),
16801
+ inputTokens: number(),
16802
+ outputTokens: number(),
16803
+ avgLatencyMs: number()
16804
+ });
16805
+ /** LLM-facing view over the reused ModelCatalogEntry mechanism (spec §4.2). */
16806
+ var ManagedModelCatalogEntrySchema = object({
16807
+ id: string(),
16808
+ label: string(),
16809
+ family: string(),
16810
+ purpose: _enum(["text", "vision"]),
16811
+ url: string(),
16812
+ sha256: string(),
16813
+ sizeBytes: number(),
16814
+ quantization: string(),
16815
+ /** Load-time guidance shown in the picker. */
16816
+ minRamBytes: number(),
16817
+ contextSizeDefault: number().int(),
16818
+ /** Vision models: companion projector file. */
16819
+ mmprojUrl: string().optional()
16820
+ });
16821
+ var LlmRuntimeNodeSchema = object({
16822
+ nodeId: string(),
16823
+ reachable: boolean(),
16824
+ status: LlmRuntimeStatusSchema.optional(),
16825
+ disk: LlmRuntimeDiskUsageSchema.optional(),
16826
+ error: string().optional()
16827
+ });
16828
+ var GenerateVisionInputSchema = LlmGenerateBaseInputSchema.extend({ images: array(LlmImageSchema).min(1) });
16829
+ var ProfileRefInputSchema = object({
16830
+ addonId: string(),
16831
+ profileId: string()
16832
+ });
16833
+ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
16834
+ kind: "mutation",
16835
+ auth: "admin"
16836
+ }), method(ProfileRefInputSchema, _void(), {
16837
+ kind: "mutation",
16838
+ auth: "admin"
16839
+ }), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
16840
+ kind: "mutation",
16841
+ auth: "admin"
16842
+ }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
16843
+ selector: LlmDefaultSelectorSchema,
16844
+ profileId: string().nullable()
16845
+ }), _void(), {
16846
+ kind: "mutation",
16847
+ auth: "admin"
16848
+ }), method(object({
16849
+ since: number().optional(),
16850
+ until: number().optional(),
16851
+ consumer: string().optional(),
16852
+ profileId: string().optional()
16853
+ }), array(LlmUsageRollupSchema)), method(object({}), array(ManagedModelCatalogEntrySchema)), method(object({}), array(LlmRuntimeNodeSchema)), method(object({ nodeId: string() }), array(LlmNodeModelSchema)), method(object({
16854
+ nodeId: string(),
16855
+ model: ManagedModelRefSchema
16856
+ }), _void(), {
16857
+ kind: "mutation",
16858
+ auth: "admin"
16859
+ }), method(object({
16860
+ nodeId: string(),
16861
+ file: string()
16862
+ }), _void(), {
16863
+ kind: "mutation",
16864
+ auth: "admin"
16865
+ }), method(ProfileRefInputSchema, LlmRuntimeStatusSchema), method(ProfileRefInputSchema, LlmRuntimeStatusSchema, {
16866
+ kind: "mutation",
16867
+ auth: "admin"
16868
+ }), method(ProfileRefInputSchema, _void(), {
16869
+ kind: "mutation",
16870
+ auth: "admin"
16871
+ });
16872
+ /**
16312
16873
  * Zod schemas for persisted record types.
16313
16874
  *
16314
16875
  * These schemas serve as the single source of truth for types that are
@@ -16510,6 +17071,22 @@ var TrackSnapshotSchema = object({
16510
17071
  /** MediaStore key; resolve via `getTrackMedia({ trackId })`. */
16511
17072
  mediaKey: string()
16512
17073
  });
17074
+ /**
17075
+ * One audio-classification label heard on the track's camera while the
17076
+ * track was alive, aggregated per label. An "episode" is one persisted
17077
+ * audio event (the confident-classification path: score ≥ the device's
17078
+ * `classificationMinScore`, class-change-or-heartbeat coalesced) — NOT
17079
+ * one 32 ms inference chunk, so counts stay human-scaled.
17080
+ */
17081
+ var TrackAudioLabelSchema = object({
17082
+ label: string(),
17083
+ /** Highest classification score observed across the label's episodes. */
17084
+ peakScore: number(),
17085
+ /** Number of coalesced audio-event episodes carrying this label. */
17086
+ count: number(),
17087
+ firstAt: number(),
17088
+ lastAt: number()
17089
+ });
16513
17090
  var TrackSchema = object({
16514
17091
  trackId: string(),
16515
17092
  deviceId: number(),
@@ -16524,6 +17101,10 @@ var TrackSchema = object({
16524
17101
  snapshots: array(TrackSnapshotSchema).readonly(),
16525
17102
  /** Deduplicated zones the track has entered at least once. */
16526
17103
  zonesVisited: array(string()).readonly(),
17104
+ /** Deduplicated set of detector classes observed for this track over its
17105
+ * life (a track may be reclassified, e.g. person→vehicle). Absent on
17106
+ * legacy rows written before class accumulation shipped. */
17107
+ classes: array(string()).readonly().optional(),
16527
17108
  /** Cumulative normalized distance travelled (0..1 units = full frame width). */
16528
17109
  totalDistance: number(),
16529
17110
  state: TrackStateSchema,
@@ -16537,7 +17118,11 @@ var TrackSchema = object({
16537
17118
  bestEventId: string().optional(),
16538
17119
  /** Tag of the importance sub-signal that dominated the score
16539
17120
  * (identity|dwell|proximity|class|confidence|travel|zone). */
16540
- importanceReason: string().optional()
17121
+ importanceReason: string().optional(),
17122
+ /** Audio-classification labels heard on the camera during the track's
17123
+ * life (score ≥ device `classificationMinScore`), aggregated per label.
17124
+ * Absent on legacy rows / tracks with no confident audio. */
17125
+ audioLabels: array(TrackAudioLabelSchema).readonly().optional()
16541
17126
  });
16542
17127
  var BaseEventFields = {
16543
17128
  id: string(),
@@ -16685,7 +17270,7 @@ var KeyEventSchema = object({
16685
17270
  /** Track lifetime in ms (lastSeen - firstSeen). */
16686
17271
  windowMs: number().optional()
16687
17272
  });
16688
- var TrackedDetectionSchema = object({
17273
+ object({
16689
17274
  trackId: string(),
16690
17275
  className: string(),
16691
17276
  confidence: number(),
@@ -16693,6 +17278,23 @@ var TrackedDetectionSchema = object({
16693
17278
  zones: array(string()).readonly(),
16694
17279
  state: TrackStateSchema
16695
17280
  });
17281
+ var OverlayDetectionSchema = looseObject({
17282
+ id: string(),
17283
+ kind: _enum(["first-level", "detail"]),
17284
+ macroClass: string(),
17285
+ score: number(),
17286
+ bbox: object({
17287
+ x: number(),
17288
+ y: number(),
17289
+ width: number(),
17290
+ height: number()
17291
+ }),
17292
+ labels: array(looseObject({
17293
+ label: string(),
17294
+ score: number()
17295
+ })).readonly(),
17296
+ parentId: string().optional()
17297
+ });
16696
17298
  var ScoredObjectEventSchema = ObjectEventSchema.extend({ score: number() });
16697
17299
  var SearchObjectEventsInput = object({
16698
17300
  text: string(),
@@ -16703,6 +17305,20 @@ var SearchObjectEventsInput = object({
16703
17305
  limit: number().default(50),
16704
17306
  minScore: number().min(0).max(1).default(.2)
16705
17307
  });
17308
+ var TrackCascadeCountsSchema = object({
17309
+ /** Persisted track roots deleted (authoritative). */
17310
+ tracks: number().int(),
17311
+ /** Object events removed with their tracks (best-effort; see note above). */
17312
+ events: number().int(),
17313
+ /** Track/face/plate-owned media removed (best-effort). Never identity media. */
17314
+ media: number().int(),
17315
+ /** Unassigned (non-enrolled) face reads removed (best-effort). */
17316
+ faces: number().int(),
17317
+ /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
17318
+ plates: number().int(),
17319
+ /** Per-track CLIP search vectors removed (best-effort). */
17320
+ embeddings: number().int()
17321
+ });
16706
17322
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
16707
17323
  deviceId: number(),
16708
17324
  trackId: string()
@@ -16734,6 +17350,24 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
16734
17350
  }), {
16735
17351
  kind: "mutation",
16736
17352
  auth: "admin"
17353
+ }), method(object({
17354
+ deviceId: number(),
17355
+ cutoffMs: number()
17356
+ }), TrackCascadeCountsSchema, {
17357
+ kind: "mutation",
17358
+ auth: "admin"
17359
+ }), method(object({ deviceId: number() }), TrackCascadeCountsSchema, {
17360
+ kind: "mutation",
17361
+ auth: "admin"
17362
+ }), method(object({
17363
+ deviceId: number(),
17364
+ trackIds: array(string()).min(1)
17365
+ }), object({
17366
+ deleted: number().int(),
17367
+ failed: array(string()).readonly()
17368
+ }), {
17369
+ kind: "mutation",
17370
+ auth: "admin"
16737
17371
  }), method(object({
16738
17372
  eventId: string(),
16739
17373
  kind: MediaFileKindEnum.optional()
@@ -16742,7 +17376,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
16742
17376
  timestamp: number(),
16743
17377
  frameWidth: number(),
16744
17378
  frameHeight: number(),
16745
- detections: array(TrackedDetectionSchema).readonly()
17379
+ detections: array(OverlayDetectionSchema).readonly()
16746
17380
  }), object({
16747
17381
  deviceId: number(),
16748
17382
  trackId: string(),
@@ -19606,6 +20240,24 @@ DeviceType.Camera, method(object({
19606
20240
  deviceId: number(),
19607
20241
  status: OsdStatusSchema
19608
20242
  });
20243
+ var VehicleSchema = object({
20244
+ id: string(),
20245
+ name: string(),
20246
+ sampleCount: number().int().nonnegative(),
20247
+ coverMediaKey: string().optional(),
20248
+ /** Inline base64 of the cover sample's plate crop, resolved from `coverMediaKey`. */
20249
+ coverBase64: string().optional()
20250
+ });
20251
+ var VehicleSampleInfoSchema = object({
20252
+ id: string(),
20253
+ /** The plate text this sample enrolled (self-labeling — no embedding). */
20254
+ text: string(),
20255
+ /** OCR confidence of the enrolled read (0..1). */
20256
+ score: number(),
20257
+ addedAt: number().int(),
20258
+ deviceId: number().int().optional(),
20259
+ base64: string().optional()
20260
+ });
19609
20261
  var PlateInfoSchema = object({
19610
20262
  plateId: string(),
19611
20263
  deviceId: number().int(),
@@ -19617,6 +20269,16 @@ var PlateInfoSchema = object({
19617
20269
  score: number(),
19618
20270
  /** True when the text was manually corrected (exempt from retention). */
19619
20271
  corrected: boolean(),
20272
+ /** Recognized vehicle id when a matcher lookup named this read (SQL NULL → absent). */
20273
+ recognizedVehicleId: string().optional(),
20274
+ /** Resolved vehicle name for `recognizedVehicleId` (UI convenience). */
20275
+ vehicleName: string().optional(),
20276
+ /** True once the read was assigned to a vehicle (enrolled as a sample). */
20277
+ assigned: boolean(),
20278
+ /** keyFrame parity: the plate bbox (pixel space) on the native key frame. */
20279
+ plateBbox: BoundingBoxSchema.optional(),
20280
+ /** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
20281
+ keyFrameMediaKey: string().optional(),
19620
20282
  base64: string().optional()
19621
20283
  });
19622
20284
  var MediaFileLiteSchema = object({
@@ -19656,6 +20318,48 @@ method(object({
19656
20318
  }), method(object({ plateId: string() }), _void(), {
19657
20319
  kind: "mutation",
19658
20320
  auth: "admin"
20321
+ }), method(_void(), array(VehicleSchema).readonly()), method(object({ name: string().min(1) }), VehicleSchema, {
20322
+ kind: "mutation",
20323
+ auth: "admin"
20324
+ }), method(object({
20325
+ id: string(),
20326
+ name: string().min(1)
20327
+ }), _void(), {
20328
+ kind: "mutation",
20329
+ auth: "admin"
20330
+ }), method(object({ id: string() }), _void(), {
20331
+ kind: "mutation",
20332
+ auth: "admin"
20333
+ }), method(object({ vehicleId: string() }), array(VehicleSampleInfoSchema).readonly()), method(object({
20334
+ vehicleId: string(),
20335
+ sampleId: string()
20336
+ }), _void(), {
20337
+ kind: "mutation",
20338
+ auth: "admin"
20339
+ }), method(object({
20340
+ plateId: string(),
20341
+ vehicleId: string()
20342
+ }), _void(), {
20343
+ kind: "mutation",
20344
+ auth: "admin"
20345
+ }), method(object({ plateId: string() }), _void(), {
20346
+ kind: "mutation",
20347
+ auth: "admin"
20348
+ }), method(object({
20349
+ plateIds: array(string()).min(1),
20350
+ vehicleId: string()
20351
+ }), object({
20352
+ assigned: number().int(),
20353
+ failed: array(string()).readonly()
20354
+ }), {
20355
+ kind: "mutation",
20356
+ auth: "admin"
20357
+ }), method(object({ plateIds: array(string()).min(1) }), object({
20358
+ unassigned: number().int(),
20359
+ failed: array(string()).readonly()
20360
+ }), {
20361
+ kind: "mutation",
20362
+ auth: "admin"
19659
20363
  });
19660
20364
  var ModelFormatSchema = _enum(MODEL_FORMATS);
19661
20365
  var HwAccelBackendInputSchema = _enum([
@@ -19734,6 +20438,10 @@ var GpuInfoSchema = object({
19734
20438
  memoryMB: number().optional()
19735
20439
  });
19736
20440
  var NpuInfoSchema = object({ type: _enum(["apple-ane", "intel-npu"]) });
20441
+ var CoralInfoSchema = object({
20442
+ type: literal("coral-edgetpu"),
20443
+ bus: string().optional()
20444
+ });
19737
20445
  var HardwareInfoSchema = object({
19738
20446
  platform: HardwarePlatformSchema,
19739
20447
  arch: HardwareArchSchema,
@@ -19742,7 +20450,8 @@ var HardwareInfoSchema = object({
19742
20450
  totalRAM_MB: number(),
19743
20451
  availableRAM_MB: number(),
19744
20452
  gpu: GpuInfoSchema.nullable(),
19745
- npu: NpuInfoSchema.nullable()
20453
+ npu: NpuInfoSchema.nullable(),
20454
+ coral: CoralInfoSchema.nullable().optional()
19746
20455
  });
19747
20456
  var PlatformScoreSchema = object({
19748
20457
  runtime: _enum(["node", "python"]),
@@ -22234,6 +22943,168 @@ Object.freeze({
22234
22943
  addonId: null,
22235
22944
  access: "create"
22236
22945
  },
22946
+ "llm.deleteModel": {
22947
+ capName: "llm",
22948
+ capScope: "system",
22949
+ addonId: null,
22950
+ access: "delete"
22951
+ },
22952
+ "llm.deleteProfile": {
22953
+ capName: "llm",
22954
+ capScope: "system",
22955
+ addonId: null,
22956
+ access: "delete"
22957
+ },
22958
+ "llm.generate": {
22959
+ capName: "llm",
22960
+ capScope: "system",
22961
+ addonId: null,
22962
+ access: "create"
22963
+ },
22964
+ "llm.generateVision": {
22965
+ capName: "llm",
22966
+ capScope: "system",
22967
+ addonId: null,
22968
+ access: "create"
22969
+ },
22970
+ "llm.getDefaults": {
22971
+ capName: "llm",
22972
+ capScope: "system",
22973
+ addonId: null,
22974
+ access: "view"
22975
+ },
22976
+ "llm.getRuntimeStatus": {
22977
+ capName: "llm",
22978
+ capScope: "system",
22979
+ addonId: null,
22980
+ access: "view"
22981
+ },
22982
+ "llm.getUsage": {
22983
+ capName: "llm",
22984
+ capScope: "system",
22985
+ addonId: null,
22986
+ access: "view"
22987
+ },
22988
+ "llm.installModel": {
22989
+ capName: "llm",
22990
+ capScope: "system",
22991
+ addonId: null,
22992
+ access: "create"
22993
+ },
22994
+ "llm.listModelCatalog": {
22995
+ capName: "llm",
22996
+ capScope: "system",
22997
+ addonId: null,
22998
+ access: "view"
22999
+ },
23000
+ "llm.listModels": {
23001
+ capName: "llm",
23002
+ capScope: "system",
23003
+ addonId: null,
23004
+ access: "view"
23005
+ },
23006
+ "llm.listNodeModels": {
23007
+ capName: "llm",
23008
+ capScope: "system",
23009
+ addonId: null,
23010
+ access: "view"
23011
+ },
23012
+ "llm.listProfileKinds": {
23013
+ capName: "llm",
23014
+ capScope: "system",
23015
+ addonId: null,
23016
+ access: "view"
23017
+ },
23018
+ "llm.listProfiles": {
23019
+ capName: "llm",
23020
+ capScope: "system",
23021
+ addonId: null,
23022
+ access: "view"
23023
+ },
23024
+ "llm.listRuntimeNodes": {
23025
+ capName: "llm",
23026
+ capScope: "system",
23027
+ addonId: null,
23028
+ access: "view"
23029
+ },
23030
+ "llm.setDefault": {
23031
+ capName: "llm",
23032
+ capScope: "system",
23033
+ addonId: null,
23034
+ access: "create"
23035
+ },
23036
+ "llm.startRuntime": {
23037
+ capName: "llm",
23038
+ capScope: "system",
23039
+ addonId: null,
23040
+ access: "create"
23041
+ },
23042
+ "llm.stopRuntime": {
23043
+ capName: "llm",
23044
+ capScope: "system",
23045
+ addonId: null,
23046
+ access: "create"
23047
+ },
23048
+ "llm.testProfile": {
23049
+ capName: "llm",
23050
+ capScope: "system",
23051
+ addonId: null,
23052
+ access: "create"
23053
+ },
23054
+ "llm.upsertProfile": {
23055
+ capName: "llm",
23056
+ capScope: "system",
23057
+ addonId: null,
23058
+ access: "create"
23059
+ },
23060
+ "llmRuntime.complete": {
23061
+ capName: "llm-runtime",
23062
+ capScope: "system",
23063
+ addonId: null,
23064
+ access: "create"
23065
+ },
23066
+ "llmRuntime.deleteModel": {
23067
+ capName: "llm-runtime",
23068
+ capScope: "system",
23069
+ addonId: null,
23070
+ access: "delete"
23071
+ },
23072
+ "llmRuntime.ensureStarted": {
23073
+ capName: "llm-runtime",
23074
+ capScope: "system",
23075
+ addonId: null,
23076
+ access: "create"
23077
+ },
23078
+ "llmRuntime.getDiskUsage": {
23079
+ capName: "llm-runtime",
23080
+ capScope: "system",
23081
+ addonId: null,
23082
+ access: "view"
23083
+ },
23084
+ "llmRuntime.installModel": {
23085
+ capName: "llm-runtime",
23086
+ capScope: "system",
23087
+ addonId: null,
23088
+ access: "create"
23089
+ },
23090
+ "llmRuntime.listLocalModels": {
23091
+ capName: "llm-runtime",
23092
+ capScope: "system",
23093
+ addonId: null,
23094
+ access: "view"
23095
+ },
23096
+ "llmRuntime.status": {
23097
+ capName: "llm-runtime",
23098
+ capScope: "system",
23099
+ addonId: null,
23100
+ access: "view"
23101
+ },
23102
+ "llmRuntime.stop": {
23103
+ capName: "llm-runtime",
23104
+ capScope: "system",
23105
+ addonId: null,
23106
+ access: "create"
23107
+ },
22237
23108
  "localNetwork.getAllowedAddresses": {
22238
23109
  capName: "local-network",
22239
23110
  capScope: "system",
@@ -22864,6 +23735,12 @@ Object.freeze({
22864
23735
  addonId: null,
22865
23736
  access: "delete"
22866
23737
  },
23738
+ "pipelineAnalytics.deleteTracks": {
23739
+ capName: "pipeline-analytics",
23740
+ capScope: "device",
23741
+ addonId: null,
23742
+ access: "delete"
23743
+ },
22867
23744
  "pipelineAnalytics.getActiveTracks": {
22868
23745
  capName: "pipeline-analytics",
22869
23746
  capScope: "device",
@@ -22930,12 +23807,24 @@ Object.freeze({
22930
23807
  addonId: null,
22931
23808
  access: "create"
22932
23809
  },
23810
+ "pipelineAnalytics.pruneTracksBefore": {
23811
+ capName: "pipeline-analytics",
23812
+ capScope: "device",
23813
+ addonId: null,
23814
+ access: "create"
23815
+ },
22933
23816
  "pipelineAnalytics.searchObjectEvents": {
22934
23817
  capName: "pipeline-analytics",
22935
23818
  capScope: "device",
22936
23819
  addonId: null,
22937
23820
  access: "view"
22938
23821
  },
23822
+ "pipelineAnalytics.wipeAllAnalytics": {
23823
+ capName: "pipeline-analytics",
23824
+ capScope: "device",
23825
+ addonId: null,
23826
+ access: "delete"
23827
+ },
22939
23828
  "pipelineExecutor.cacheFrameInPool": {
22940
23829
  capName: "pipeline-executor",
22941
23830
  capScope: "system",
@@ -23440,18 +24329,42 @@ Object.freeze({
23440
24329
  addonId: null,
23441
24330
  access: "create"
23442
24331
  },
24332
+ "plateGallery.assignPlate": {
24333
+ capName: "plate-gallery",
24334
+ capScope: "system",
24335
+ addonId: null,
24336
+ access: "create"
24337
+ },
24338
+ "plateGallery.assignPlates": {
24339
+ capName: "plate-gallery",
24340
+ capScope: "system",
24341
+ addonId: null,
24342
+ access: "create"
24343
+ },
23443
24344
  "plateGallery.correctPlateText": {
23444
24345
  capName: "plate-gallery",
23445
24346
  capScope: "system",
23446
24347
  addonId: null,
23447
24348
  access: "create"
23448
24349
  },
24350
+ "plateGallery.createVehicle": {
24351
+ capName: "plate-gallery",
24352
+ capScope: "system",
24353
+ addonId: null,
24354
+ access: "create"
24355
+ },
23449
24356
  "plateGallery.deletePlate": {
23450
24357
  capName: "plate-gallery",
23451
24358
  capScope: "system",
23452
24359
  addonId: null,
23453
24360
  access: "delete"
23454
24361
  },
24362
+ "plateGallery.deleteVehicle": {
24363
+ capName: "plate-gallery",
24364
+ capScope: "system",
24365
+ addonId: null,
24366
+ access: "delete"
24367
+ },
23455
24368
  "plateGallery.getPlateByTrack": {
23456
24369
  capName: "plate-gallery",
23457
24370
  capScope: "system",
@@ -23470,6 +24383,30 @@ Object.freeze({
23470
24383
  addonId: null,
23471
24384
  access: "view"
23472
24385
  },
24386
+ "plateGallery.listVehicles": {
24387
+ capName: "plate-gallery",
24388
+ capScope: "system",
24389
+ addonId: null,
24390
+ access: "view"
24391
+ },
24392
+ "plateGallery.listVehicleSamples": {
24393
+ capName: "plate-gallery",
24394
+ capScope: "system",
24395
+ addonId: null,
24396
+ access: "view"
24397
+ },
24398
+ "plateGallery.removeVehicleSample": {
24399
+ capName: "plate-gallery",
24400
+ capScope: "system",
24401
+ addonId: null,
24402
+ access: "delete"
24403
+ },
24404
+ "plateGallery.renameVehicle": {
24405
+ capName: "plate-gallery",
24406
+ capScope: "system",
24407
+ addonId: null,
24408
+ access: "create"
24409
+ },
23473
24410
  "plateGallery.searchPlates": {
23474
24411
  capName: "plate-gallery",
23475
24412
  capScope: "system",
@@ -23482,6 +24419,18 @@ Object.freeze({
23482
24419
  addonId: null,
23483
24420
  access: "view"
23484
24421
  },
24422
+ "plateGallery.unassignPlate": {
24423
+ capName: "plate-gallery",
24424
+ capScope: "system",
24425
+ addonId: null,
24426
+ access: "create"
24427
+ },
24428
+ "plateGallery.unassignPlates": {
24429
+ capName: "plate-gallery",
24430
+ capScope: "system",
24431
+ addonId: null,
24432
+ access: "create"
24433
+ },
23485
24434
  "platformProbe.getCapabilities": {
23486
24435
  capName: "platform-probe",
23487
24436
  capScope: "system",
@@ -23674,6 +24623,48 @@ Object.freeze({
23674
24623
  addonId: null,
23675
24624
  access: "create"
23676
24625
  },
24626
+ "sceneMonitor.captureReference": {
24627
+ capName: "scene-monitor",
24628
+ capScope: "device",
24629
+ addonId: null,
24630
+ access: "create"
24631
+ },
24632
+ "sceneMonitor.createScene": {
24633
+ capName: "scene-monitor",
24634
+ capScope: "device",
24635
+ addonId: null,
24636
+ access: "create"
24637
+ },
24638
+ "sceneMonitor.deleteReference": {
24639
+ capName: "scene-monitor",
24640
+ capScope: "device",
24641
+ addonId: null,
24642
+ access: "delete"
24643
+ },
24644
+ "sceneMonitor.deleteScene": {
24645
+ capName: "scene-monitor",
24646
+ capScope: "device",
24647
+ addonId: null,
24648
+ access: "delete"
24649
+ },
24650
+ "sceneMonitor.listScenes": {
24651
+ capName: "scene-monitor",
24652
+ capScope: "device",
24653
+ addonId: null,
24654
+ access: "view"
24655
+ },
24656
+ "sceneMonitor.recheckNow": {
24657
+ capName: "scene-monitor",
24658
+ capScope: "device",
24659
+ addonId: null,
24660
+ access: "create"
24661
+ },
24662
+ "sceneMonitor.updateScene": {
24663
+ capName: "scene-monitor",
24664
+ capScope: "device",
24665
+ addonId: null,
24666
+ access: "create"
24667
+ },
23677
24668
  "scriptRunner.run": {
23678
24669
  capName: "script-runner",
23679
24670
  capScope: "device",
@@ -24758,6 +25749,7 @@ Object.freeze({
24758
25749
  Object.freeze({
24759
25750
  "broker": "broker",
24760
25751
  "device-export": "device-export",
25752
+ "llm": "ai",
24761
25753
  "mesh-network": "mesh",
24762
25754
  "mqtt-broker": "broker",
24763
25755
  "network-access": "ingress",
@@ -24896,6 +25888,10 @@ var CPU = {
24896
25888
  value: "cpu",
24897
25889
  label: "CPU"
24898
25890
  };
25891
+ var USB = {
25892
+ value: "usb",
25893
+ label: "Coral USB"
25894
+ };
24899
25895
  var RUNTIMES = [
24900
25896
  {
24901
25897
  id: "onnx",
@@ -24954,6 +25950,12 @@ var RUNTIMES = [
24954
25950
  return out;
24955
25951
  },
24956
25952
  defaultDevice: "all"
25953
+ },
25954
+ {
25955
+ id: "edgetpu",
25956
+ supports: (hw) => hw?.coral != null,
25957
+ devices: () => [USB],
25958
+ defaultDevice: "usb"
24957
25959
  }
24958
25960
  ];
24959
25961
  function def(id) {