@camstack/types 1.2.42 → 1.2.44

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 (48) hide show
  1. package/dist/addon.js +8 -2
  2. package/dist/addon.mjs +8 -2
  3. package/dist/cap-call-context.d.ts +26 -0
  4. package/dist/capabilities/index.d.ts +8 -5
  5. package/dist/capabilities/osd-manager.cap.d.ts +900 -0
  6. package/dist/capabilities/pipeline-analytics.cap.d.ts +171 -4
  7. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +36 -0
  8. package/dist/capabilities/privacy-mask.cap.d.ts +69 -9
  9. package/dist/capabilities/recording.cap.d.ts +27 -0
  10. package/dist/capabilities/schemas/streaming-shared.d.ts +2 -0
  11. package/dist/capabilities/server-management.cap.d.ts +3 -3
  12. package/dist/capabilities/snapshot.cap.d.ts +1 -1
  13. package/dist/capabilities/stream-broker.cap.d.ts +36 -0
  14. package/dist/capabilities/stream-params.cap.d.ts +8 -4
  15. package/dist/device/device-profile.d.ts +12 -4
  16. package/dist/device/system-mirror.d.ts +11 -0
  17. package/dist/ffmpeg/encode-defaults.d.ts +18 -0
  18. package/dist/ffmpeg/fmp4-box-splitter.d.ts +113 -0
  19. package/dist/ffmpeg/fmp4-fragment-child.d.ts +85 -0
  20. package/dist/ffmpeg/fmp4-fragment-plane.d.ts +142 -0
  21. package/dist/ffmpeg/invocation.d.ts +102 -2
  22. package/dist/ffmpeg/sharing-key.d.ts +54 -2
  23. package/dist/fmp4-box-splitter-B53u9-Nu.mjs +615 -0
  24. package/dist/fmp4-box-splitter-BkWH7O3L.js +686 -0
  25. package/dist/generated/addon-api.d.ts +117 -0
  26. package/dist/generated/cap-input-defaults.d.ts +1 -1
  27. package/dist/generated/capability-router-map.d.ts +5 -2
  28. package/dist/generated/device-proxy.d.ts +4 -2
  29. package/dist/generated/method-access-map.d.ts +1 -1
  30. package/dist/generated/system-proxy.d.ts +2 -0
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.js +1264 -394
  33. package/dist/index.mjs +1217 -385
  34. package/dist/interfaces/camera-switches.d.ts +211 -5
  35. package/dist/interfaces/inference-engine.d.ts +24 -3
  36. package/dist/interfaces/stream-broker.d.ts +18 -0
  37. package/dist/node.d.ts +4 -0
  38. package/dist/node.js +509 -3
  39. package/dist/node.mjs +507 -3
  40. package/dist/notification/schedule.d.ts +20 -0
  41. package/dist/pipeline/native-lease.d.ts +150 -0
  42. package/dist/{sleep-BmNKsY7v.mjs → sleep-cC4Fuup8.mjs} +59 -3
  43. package/dist/{sleep-Cvi1JxZp.js → sleep-eiC10_cX.js} +64 -2
  44. package/dist/types/pipeline-step.d.ts +1 -1
  45. package/dist/utils/addon-id.d.ts +30 -0
  46. package/package.json +1 -1
  47. package/dist/canonical-hash-7nfBbEqR.mjs +0 -35
  48. package/dist/canonical-hash-BcZHRHIx.js +0 -40
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as EventCategory } from "./event-category-41fKf-q9.mjs";
2
- import { $ as ProfileRtspEntrySchema, A as method, B as scopeKey, C as DeviceType, Ct as collectHydratedFieldValues, D as event, E as DEVICE_STATUS_METHOD, F as readNodePin, G as CamStreamKindSchema, H as BrokerStatusSchema, I as ReadinessRegistry, J as DecodedAudioChunkSchema, K as CamStreamResolutionSchema, L as ReadinessTimeoutError, M as systemMethod, N as CAP_NODE_PIN_CONTEXT_KEY, O as expandCapMethods, P as nodePin, Q as FrameHandleSchema, R as emitDownForOwnedCaps, S as DeviceRole, St as collectHydratedFieldEntries, T as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Tt as resolveHydratedFieldValue, U as CAM_PROFILE_ORDER, V as BrokerStatsSchema, W as CamProfileSchema, X as EncodedPacketSchema, Y as DecodedFrameSchema, Z as FrameHandleFormatSchema, _ as RawStateResultSchema, _t as createEvent, a as asJsonObject, at as SubscribeAudioChunksResultSchema, b as ChargingStatus, bt as WELL_KNOWN_TABS, c as parseJsonArray, ct as makeProfileBrokerId, d as DEVICE_SCOPED_CAPS, dt as selectAssignedProfileSlots, et as ProfileSlotSchema, f as isDeviceScopedCap, ft as DATAPLANE_SECRET_HEADER, g as createSliceHandle, gt as createDurableState, h as createMirrorSource, ht as normalizeAddonInitResult, i as asJsonArray, it as SubscribeAudioChunksInputSchema, j as resolveCapMount, k as isDeviceConfigCap, l as parseJsonObject, lt as makeSourceBrokerId, m as createLazyTrpcSource, mt as BaseAddon, n as sleepCancellable, nt as StreamSourceEntrySchema, o as asNumber, ot as SubscribeFramesInputSchema, p as createDeviceProxy, pt as DisposerChain, q as CameraStreamSchema, r as asBoolean, rt as StreamSourceSchema, s as asString, st as SubscribeFramesResultSchema, t as sleep, tt as ProfileSlotStatusSchema, u as parseJsonUnknown, ut as parseProfileBrokerId, v as deviceOpsCapability, vt as emitReadiness, w as adminUiCapability, wt as hydrateSchema, x as DeviceFeature, xt as WELL_KNOWN_TAB_MAP, y as viewerUiCapability, yt as isEvent, z as readinessKey } from "./sleep-BmNKsY7v.mjs";
3
- import { t as canonicalHash } from "./canonical-hash-7nfBbEqR.mjs";
2
+ import { $ as FrameHandleSchema, A as method, B as readinessKey, C as DeviceType, Ct as collectHydratedFieldEntries, D as event, E as DEVICE_STATUS_METHOD, Et as resolveHydratedFieldValue, F as readNodePin, G as CamProfileSchema, H as BrokerStatsSchema, I as toNodeId, J as CameraStreamSchema, K as CamStreamKindSchema, L as ReadinessRegistry, M as systemMethod, N as CAP_NODE_PIN_CONTEXT_KEY, O as expandCapMethods, P as nodePin, Q as FrameHandleFormatSchema, R as ReadinessTimeoutError, S as DeviceRole, St as WELL_KNOWN_TAB_MAP, T as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Tt as hydrateSchema, U as BrokerStatusSchema, V as scopeKey, W as CAM_PROFILE_ORDER, X as DecodedFrameSchema, Y as DecodedAudioChunkSchema, Z as EncodedPacketSchema, _ as RawStateResultSchema, _t as createDurableState, a as asJsonObject, at as SubscribeAudioChunksInputSchema, b as ChargingStatus, bt as isEvent, c as parseJsonArray, ct as SubscribeFramesResultSchema, d as DEVICE_SCOPED_CAPS, dt as parseProfileBrokerId, et as ProfileRtspEntrySchema, f as isDeviceScopedCap, ft as selectAssignedProfileSlots, g as createSliceHandle, gt as normalizeAddonInitResult, h as createMirrorSource, ht as BaseAddon, i as asJsonArray, it as StreamSourceSchema, j as resolveCapMount, k as isDeviceConfigCap, l as parseJsonObject, lt as makeProfileBrokerId, m as createLazyTrpcSource, mt as DisposerChain, n as sleepCancellable, nt as ProfileSlotStatusSchema, o as asNumber, ot as SubscribeAudioChunksResultSchema, p as createDeviceProxy, pt as DATAPLANE_SECRET_HEADER, q as CamStreamResolutionSchema, r as asBoolean, rt as StreamSourceEntrySchema, s as asString, st as SubscribeFramesInputSchema, t as sleep, tt as ProfileSlotSchema, u as parseJsonUnknown, ut as makeSourceBrokerId, v as deviceOpsCapability, vt as createEvent, w as adminUiCapability, wt as collectHydratedFieldValues, x as DeviceFeature, xt as WELL_KNOWN_TABS, y as viewerUiCapability, yt as emitReadiness, z as emitDownForOwnedCaps } from "./sleep-cC4Fuup8.mjs";
3
+ import { a as buildAudioArgs, c as buildVideoArgs, d as logBannerArgs, f as pickVideoEncoder, i as audioPlanFromEncodeProfile, l as invocationFromEncodeProfile, n as canonicalHash, o as buildFfmpegArgs, r as AUDIO_PRESETS, s as buildInputArgs, t as Fmp4BoxSplitter, u as isSoftwareDecode } from "./fmp4-box-splitter-B53u9-Nu.mjs";
4
4
  import { EventSourceType } from "./enums.mjs";
5
5
  import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
6
6
  import { z } from "zod";
@@ -230,335 +230,6 @@ function encodeProfileFromStreamShape(stream) {
230
230
  };
231
231
  }
232
232
  //#endregion
233
- //#region src/ffmpeg/invocation.ts
234
- var AUDIO_ENCODER_BY_CODEC = {
235
- opus: "libopus",
236
- aac: "aac",
237
- pcmu: "pcm_mulaw",
238
- pcma: "pcm_alaw"
239
- };
240
- /**
241
- * Camera-microphone audio, per codec. Lives HERE rather than in
242
- * `encode-defaults.ts` only to avoid an import cycle (`encode-defaults` depends
243
- * on these types); it is re-exported from there, which is where to read it.
244
- *
245
- * Every source in this repo is a mono camera mic. The former broker preset
246
- * encoded Opus at `channels: 2`, spending bitrate duplicating one channel —
247
- * that is the value this consolidation changed.
248
- */
249
- var AUDIO_PRESETS = {
250
- aac: {
251
- kind: "encode",
252
- codec: "aac",
253
- bitrateKbps: 128,
254
- sampleRateHz: 48e3,
255
- channels: 1
256
- },
257
- opus: {
258
- kind: "encode",
259
- codec: "opus",
260
- bitrateKbps: 64,
261
- sampleRateHz: 48e3,
262
- channels: 1
263
- },
264
- pcmu: {
265
- kind: "encode",
266
- codec: "pcmu",
267
- sampleRateHz: 8e3,
268
- channels: 1
269
- }
270
- };
271
- /** `-hide_banner -loglevel <level>` — every ffmpeg site opens with this. */
272
- function logBannerArgs(level) {
273
- return [
274
- "-hide_banner",
275
- "-loglevel",
276
- level
277
- ];
278
- }
279
- /** `true` when the resolved value means "decode in software" (⇒ no `-hwaccel`). */
280
- function isSoftwareDecode(decodeHwAccel) {
281
- return !decodeHwAccel || decodeHwAccel === "none" || decodeHwAccel === "copy";
282
- }
283
- /**
284
- * Every INPUT option, in order, terminated by `-i <url>`. Nothing may be
285
- * appended to this list by a caller — that is the whole point of the function.
286
- */
287
- function buildInputArgs(input, decodeHwAccel) {
288
- const args = [];
289
- if (!isSoftwareDecode(decodeHwAccel)) args.push("-hwaccel", String(decodeHwAccel));
290
- if (input.extraArgs?.length) args.push(...input.extraArgs);
291
- if (input.fflags?.length) for (const flag of input.fflags) args.push("-fflags", flag);
292
- if (input.rtspTransport) args.push("-rtsp_transport", input.rtspTransport);
293
- args.push("-i", input.url);
294
- return args;
295
- }
296
- /** The `-vf` filter args, or `[]` when a consumer `-vf` already claims the slot. */
297
- function buildVideoFilterArgs(scale, outputArgs) {
298
- if (!scale) return [];
299
- if (outputArgs.some((a) => a === "-vf")) return [];
300
- if (scale.mode === "exact") return ["-vf", `scale=${scale.width}:${scale.height}`];
301
- return ["-vf", `scale='min(${scale.width},iw)':'min(${scale.height},ih)':force_original_aspect_ratio=decrease:force_divisible_by=2`];
302
- }
303
- /** Rate-control args for an encode plan. */
304
- function buildRateControlArgs(video) {
305
- const kbps = video.bitrateKbps;
306
- if (kbps === void 0) return [];
307
- const rc = video.rateControl ?? {
308
- kind: "cap",
309
- vbvSeconds: 2
310
- };
311
- const bufsize = Math.max(1, Math.round(kbps * rc.vbvSeconds));
312
- return [
313
- ...rc.kind === "cbr" ? ["-b:v", `${kbps}k`] : [],
314
- "-maxrate",
315
- `${kbps}k`,
316
- "-bufsize",
317
- `${bufsize}k`
318
- ];
319
- }
320
- /** The whole video block (`-vf` … `-c:v` … knobs), after `-i`. */
321
- function buildVideoArgs(video, outputArgs) {
322
- if (video.kind === "copy") return [
323
- "-c:v",
324
- "copy",
325
- ...video.bitstreamFilter ? ["-bsf:v", video.bitstreamFilter] : []
326
- ];
327
- const args = [
328
- ...buildVideoFilterArgs(video.scale, outputArgs),
329
- "-c:v",
330
- video.encoder
331
- ];
332
- if (video.preset !== void 0) args.push("-preset", video.preset);
333
- if (video.tune !== void 0) args.push("-tune", video.tune);
334
- if (video.profile !== void 0) args.push("-profile:v", video.profile);
335
- if (video.level !== void 0) args.push("-level", video.level);
336
- if (video.pixelFormat !== void 0) args.push("-pix_fmt", video.pixelFormat);
337
- if (video.fps !== void 0) args.push("-r", String(video.fps));
338
- if (video.gopFrames !== void 0) args.push("-g", String(video.gopFrames));
339
- if (video.bf !== void 0) args.push("-bf", String(video.bf));
340
- args.push(...buildRateControlArgs(video));
341
- if (video.bitstreamFilter !== void 0) args.push("-bsf:v", video.bitstreamFilter);
342
- return args;
343
- }
344
- /** The whole audio block, after `-i`. */
345
- function buildAudioArgs(audio) {
346
- if (audio.kind === "none") return ["-an"];
347
- if (audio.kind === "copy") return ["-c:a", "copy"];
348
- const args = [];
349
- if (audio.filter !== void 0) args.push("-af", audio.filter);
350
- args.push("-c:a", AUDIO_ENCODER_BY_CODEC[audio.codec]);
351
- if (audio.application !== void 0) args.push("-application", audio.application);
352
- if (audio.frameDurationMs !== void 0) args.push("-frame_duration", String(audio.frameDurationMs));
353
- if (audio.globalHeader === true) args.push("-flags", "+global_header");
354
- if (audio.sampleRateHz !== void 0) args.push("-ar", String(audio.sampleRateHz));
355
- if (audio.bitrateKbps !== void 0) args.push("-b:a", `${audio.bitrateKbps}k`);
356
- if (audio.vbvBufferKbits !== void 0) args.push("-bufsize", `${audio.vbvBufferKbits}k`);
357
- if (audio.channels !== void 0) args.push("-ac", String(audio.channels));
358
- return args;
359
- }
360
- /** RTP output-leg args (`-payload_type`, `-ssrc`, `-sdp_file`, `-f rtp <url>`). */
361
- function buildRtpOutputArgs(out) {
362
- const args = [];
363
- if (out.payloadType !== void 0) args.push("-payload_type", String(out.payloadType));
364
- if (out.ssrc !== void 0) args.push("-ssrc", String(out.ssrc));
365
- if (out.sdpFile !== void 0) args.push("-sdp_file", out.sdpFile);
366
- args.push("-f", "rtp", out.url);
367
- return args;
368
- }
369
- /** `true` when the sink is a raw elementary bytestream that cannot mux audio. */
370
- function isElementaryVideoSink(sink) {
371
- return sink.kind === "stdout" && (sink.container === "h264" || sink.container === "hevc");
372
- }
373
- /**
374
- * A second output mapping source audio to RTP-over-UDP. `0:a:0?` makes the
375
- * audio optional so a source with no audio skips it instead of failing the
376
- * whole invocation.
377
- */
378
- function buildAudioSidecarArgs(sidecar) {
379
- return [
380
- "-map",
381
- "0:a:0?",
382
- ...buildAudioArgs(sidecar.codec === "pcma" ? {
383
- kind: "encode",
384
- codec: "pcma",
385
- sampleRateHz: 8e3,
386
- channels: 1
387
- } : AUDIO_PRESETS[sidecar.codec]),
388
- ...buildRtpOutputArgs({
389
- url: sidecar.rtpUrl,
390
- sdpFile: sidecar.sdpFile
391
- })
392
- ];
393
- }
394
- /**
395
- * Assemble the full ffmpeg argument list. Layout:
396
- *
397
- * -hide_banner -loglevel <level>
398
- * [-hwaccel <backend|auto>] ─┐ INPUT options — strictly before -i.
399
- * [<input.extraArgs>] │
400
- * [-fflags <flag>…] │
401
- * [-rtsp_transport tcp] │
402
- * -i <url> ─┘
403
- * <video block> <threads> <audio block> ─┐ OUTPUT options.
404
- * <consumer outputArgs verbatim> │
405
- * <sink> ─┘ terminal
406
- */
407
- function buildFfmpegArgs(inv) {
408
- const head = [...logBannerArgs(inv.logLevel), ...buildInputArgs(inv.input, inv.decodeHwAccel)];
409
- const threadArgs = inv.threadCount > 0 ? ["-threads", String(inv.threadCount)] : [];
410
- if (inv.sink.kind === "rtp-outputs") {
411
- const videoLeg = inv.sink.video ? [
412
- "-an",
413
- "-map",
414
- "0:v:0",
415
- ...buildVideoArgs(inv.video, inv.outputArgs),
416
- ...threadArgs,
417
- ...inv.outputArgs,
418
- ...buildRtpOutputArgs(inv.sink.video)
419
- ] : [];
420
- const audioLeg = inv.sink.audio ? [
421
- "-vn",
422
- "-map",
423
- "0:a:0?",
424
- ...buildAudioArgs(inv.audio),
425
- ...buildRtpOutputArgs(inv.sink.audio)
426
- ] : [];
427
- return [
428
- ...head,
429
- ...videoLeg,
430
- ...audioLeg
431
- ];
432
- }
433
- const audioArgs = isElementaryVideoSink(inv.sink) ? ["-an"] : buildAudioArgs(inv.audio);
434
- const sinkArgs = inv.sink.kind === "stdout" ? [
435
- "-f",
436
- inv.sink.container,
437
- "pipe:1"
438
- ] : [
439
- "-f",
440
- "rtsp",
441
- "-rtsp_transport",
442
- "tcp",
443
- "-rtsp_flags",
444
- "listen",
445
- inv.sink.url
446
- ];
447
- return [
448
- ...head,
449
- ...buildVideoArgs(inv.video, inv.outputArgs),
450
- ...threadArgs,
451
- ...audioArgs,
452
- ...inv.outputArgs,
453
- ...sinkArgs,
454
- ...inv.audioSidecar ? buildAudioSidecarArgs(inv.audioSidecar) : []
455
- ];
456
- }
457
- /**
458
- * Hardware ENCODER ids per decode-hwaccel backend — a static, deterministic
459
- * map (the same shape the reference NVR uses: platform → encoder, no probe).
460
- */
461
- var ENCODER_IDS_BY_BACKEND = {
462
- videotoolbox: {
463
- h264: "h264_videotoolbox",
464
- h265: "hevc_videotoolbox"
465
- },
466
- vaapi: {
467
- h264: "h264_vaapi",
468
- h265: "hevc_vaapi"
469
- },
470
- qsv: {
471
- h264: "h264_qsv",
472
- h265: "hevc_qsv"
473
- },
474
- cuda: {
475
- h264: "h264_nvenc",
476
- h265: "hevc_nvenc"
477
- },
478
- nvdec: {
479
- h264: "h264_nvenc",
480
- h265: "hevc_nvenc"
481
- },
482
- amf: {
483
- h264: "h264_amf",
484
- h265: "hevc_amf"
485
- }
486
- };
487
- /**
488
- * The hardware encoder for a target codec on `backend`, or the software one.
489
- * `'auto'` is NOT a backend identity (it is an instruction to ffmpeg), so it
490
- * maps to software encoding.
491
- */
492
- function pickVideoEncoder(target, backend, useHardware) {
493
- const software = target === "h264" ? "libx264" : "libx265";
494
- if (!useHardware || backend === null || isSoftwareDecode(backend) || backend === "auto") return software;
495
- const ids = ENCODER_IDS_BY_BACKEND[backend.toLowerCase()];
496
- if (!ids) return software;
497
- return target === "h264" ? ids.h264 : ids.h265;
498
- }
499
- /** Map an `EncodeProfile.audio` to an audio plan. */
500
- function audioPlanFromEncodeProfile(audio) {
501
- if (audio === "passthrough") return { kind: "none" };
502
- if (audio.codec === "copy") return { kind: "copy" };
503
- return {
504
- kind: "encode",
505
- codec: audio.codec,
506
- ...audio.bitrateKbps !== void 0 ? { bitrateKbps: audio.bitrateKbps } : {},
507
- ...audio.sampleRateHz !== void 0 ? { sampleRateHz: audio.sampleRateHz } : {},
508
- ...audio.channels !== void 0 ? { channels: audio.channels } : {}
509
- };
510
- }
511
- /**
512
- * Adapt an `EncodeProfile` (the operator/consumer-facing shape) into an
513
- * {@link FfmpegInvocation}. This is the ONLY bridge between the two models —
514
- * a second one is how the repo grew two argv builders that disagreed about
515
- * hardware.
516
- *
517
- * Smart video copy: when the source already speaks the requested codec the
518
- * encode block is elided entirely and ffmpeg runs as a re-muxer on the video
519
- * plane. Width / height / fps / bitrate in the profile are a downstream BUDGET,
520
- * not a forced rescale.
521
- */
522
- function invocationFromEncodeProfile(input) {
523
- const v = input.profile.video;
524
- const shouldCopy = v.codec === "copy" || input.forceReencode !== true && v.codec === input.sourceCodec;
525
- const scale = v.width !== void 0 && v.height !== void 0 ? {
526
- mode: "fit",
527
- width: v.width,
528
- height: v.height
529
- } : null;
530
- const target = v.codec === "h265" ? "h265" : "h264";
531
- const video = shouldCopy ? { kind: "copy" } : {
532
- kind: "encode",
533
- encoder: pickVideoEncoder(target, input.decodeHwAccel, input.hardwareEncoders === true),
534
- scale,
535
- ...v.preset !== void 0 ? { preset: v.preset } : {},
536
- ...v.tune !== void 0 ? { tune: v.tune } : {},
537
- ...v.profile !== void 0 ? { profile: v.profile } : {},
538
- ...v.level !== void 0 ? { level: v.level } : {},
539
- ...v.fps !== void 0 ? { fps: v.fps } : {},
540
- ...v.gopFrames !== void 0 ? { gopFrames: v.gopFrames } : {},
541
- ...v.bf !== void 0 ? { bf: v.bf } : {},
542
- ...v.bitrateKbps !== void 0 ? { bitrateKbps: v.bitrateKbps } : {}
543
- };
544
- return {
545
- logLevel: input.logLevel ?? "error",
546
- decodeHwAccel: input.decodeHwAccel,
547
- input: {
548
- url: input.sourceUrl,
549
- rtspTransport: "tcp",
550
- fflags: ["+discardcorrupt"],
551
- ...input.profile.inputArgs?.length ? { extraArgs: input.profile.inputArgs } : {}
552
- },
553
- video,
554
- audio: audioPlanFromEncodeProfile(input.profile.audio),
555
- threadCount: input.threadCount ?? 0,
556
- outputArgs: input.profile.outputArgs ?? [],
557
- sink: input.sink,
558
- ...input.audioSidecar !== void 0 ? { audioSidecar: input.audioSidecar } : {}
559
- };
560
- }
561
- //#endregion
562
233
  //#region src/ffmpeg/encode-defaults.ts
563
234
  /**
564
235
  * The shape every live egress starts from: H.264 Baseline 3.1 at 720p25.
@@ -603,9 +274,27 @@ var WEBRTC_EGRESS_PROFILE = {
603
274
  * audio plane (out-of-band), so this is `passthrough` exactly like the browser
604
275
  * — see the ADR for why the previous in-band Opus was encoded and discarded.
605
276
  */
277
+ /**
278
+ * Alexa's egress asks for OPUS, and that is a change with a history.
279
+ *
280
+ * The previous profile encoded Opus IN-BAND into an MPEG-TS, where it was
281
+ * discarded: Opus is `stream_type 0x06` and the broker's demuxer maps only
282
+ * `0x0f` (aac), `0x03`/`0x04` (mp2) and `0x81` (ac3). Every frame it produced
283
+ * died at the demuxer, so the encode was replaced with `passthrough` — correct,
284
+ * because paying libopus for nothing is worse than silence.
285
+ *
286
+ * But `passthrough` means the egress emits NO audio at all, and Alexa's audio
287
+ * does not arrive by magic: it rides the published stream, which is what the
288
+ * WebRTC session dials. So the Echo had video and silence either way.
289
+ *
290
+ * Opus here now reaches the egress AUDIO SIDECAR — a separate RTP leg the
291
+ * restreamer grafts onto its SDP — which never touches the MPEG-TS demuxer that
292
+ * killed the in-band attempt. Same codec, different plane, and this one the
293
+ * consumer can actually negotiate.
294
+ */
606
295
  var ALEXA_EGRESS_PROFILE = {
607
296
  ...BASE_LIVE_EGRESS_PROFILE,
608
- audio: "passthrough"
297
+ audio: { codec: "opus" }
609
298
  };
610
299
  /** VBV window for a consumer whose budget is enforced per second (HomeKit). */
611
300
  var RATE_CONTROL_TIGHT = {
@@ -726,6 +415,14 @@ async function resolveEgressDecodeHwAccel(deps) {
726
415
  * Here every knob is a named field, and defaults are APPLIED before hashing so
727
416
  * an omitted field and its explicit default land on the same key.
728
417
  */
418
+ /**
419
+ * The transport a CAP request describes. `fragments` is deliberately
420
+ * unreachable from here — the request schema has no way to ask for it, so the
421
+ * cap path can never be handed a fragment child by accident.
422
+ */
423
+ function egressTransportFromRequest(request) {
424
+ return { transport: request.publishLocally === true ? "push" : "dial" };
425
+ }
729
426
  /** Absent optional ⇒ this sentinel, so `undefined` and "not set" agree. */
730
427
  var UNSET = "\0unset";
731
428
  function canonicalVideo(video) {
@@ -757,10 +454,12 @@ function canonicalAudio(audio) {
757
454
  * future operator-facing "why are these two not sharing?" surface — can diff
758
455
  * two requests without reversing a hash.
759
456
  */
760
- function canonicalEgressPlan(request) {
457
+ function canonicalEgressPlan(request, delivery = egressTransportFromRequest(request)) {
761
458
  return {
762
459
  deviceId: request.deviceId,
763
460
  source: request.source.kind === "profile" ? `profile:${request.source.profile}` : `cam-stream:${request.source.camStreamId}`,
461
+ transport: delivery.transport,
462
+ fragmentMs: delivery.fragmentMs ?? -1,
764
463
  video: canonicalVideo(request.encode.video),
765
464
  audio: canonicalAudio(request.encode.audio),
766
465
  rateControl: request.rateControl ?? "relaxed",
@@ -780,8 +479,8 @@ function canonicalEgressPlan(request) {
780
479
  * exactly a mutable shared object, where one consumer's downgrade dragged
781
480
  * every other consumer to 360p.
782
481
  */
783
- function egressTranscodeSharingKey(request) {
784
- return `egress:${canonicalHash(canonicalEgressPlan(request))}`;
482
+ function egressTranscodeSharingKey(request, delivery = egressTransportFromRequest(request)) {
483
+ return `egress:${canonicalHash(canonicalEgressPlan(request, delivery))}`;
785
484
  }
786
485
  //#endregion
787
486
  //#region src/health/wiring-health.ts
@@ -901,7 +600,7 @@ var DEFAULT_RETENTION = {
901
600
  * ## This file adds no state
902
601
  *
903
602
  * Every switch here is a VIEW onto an authority that already existed
904
- * ([D61](../../../../docs/decisions/adr-0062.md)). The whole point of the
603
+ * ([D62](../../../../docs/decisions/adr-0062.md)). The whole point of the
905
604
  * group is that there is exactly one place each function is turned off, and
906
605
  * the group routes to it:
907
606
  *
@@ -912,6 +611,53 @@ var DEFAULT_RETENTION = {
912
611
  * | `audio-analysis` | `deviceManager.setWrapperActive('audio-analysis')` | `AudioSubscriptionController.subscribeAudioStream` returns `null` before opening the stream |
913
612
  * | `recording` | `recording.setDeviceConfig` → `RecordingConfig.enabled` | `band-decision.shouldRecord` returns false; the controller detaches the device |
914
613
  * | `notifications` | `notificationRules.setDeviceMuted` | `NotificationCenter.evaluateAndEnqueue` returns before any rule is evaluated |
614
+ * | `privacy-mask` | `privacyMask.setMask({ enabled })` → the CAMERA | the camera blanks the masked regions itself; every stream and recording carries the black boxes |
615
+ * | `device-audio` | `privacyMask.setAudioEnabled` → the CAMERA | the camera stops encoding an audio track at all; every consumer sees silent video |
616
+ * | `broker-audio` | `streamBroker.setDeviceAudioMute` → `DeviceOverride.audioMuted` | `StreamBroker.setAudioMuted` drops the audio plane at the source: no `type:'audio'` packet leaves `fanOutEncoded`, no RTP reaches the restreamer, and the restreamer serves the video-only SDP |
617
+ *
618
+ * ## `device-audio` and `broker-audio` are two functions, not two knobs
619
+ *
620
+ * They look adjacent and they are not the same control ([D83](../../../../docs/decisions/adr-0083.md)):
621
+ * `device-audio` writes the CAMERA, so it is hardware privacy — the microphone
622
+ * genuinely stops, it survives CamStack entirely, and it costs a multi-second
623
+ * encoder restart on every flip. `broker-audio` writes THIS server, so it is
624
+ * instant, vendor-independent and reversible without touching the camera, and
625
+ * a camera that ignores or lacks the ISAPI/Reolink control is still silenced.
626
+ * D62 forbids a second switch that *disagrees* with the first; these two
627
+ * cannot disagree, because neither reads the other's store — the camera holds
628
+ * one, the broker holds the other, and each reports its own fact.
629
+ *
630
+ * ## The two switches whose authority is not on this server
631
+ *
632
+ * `privacy-mask` and `device-audio` write the CAMERA. That is not a loophole
633
+ * in "the group stores nothing" — it is the purest form of it: the camera
634
+ * holds the fact, every read is a read-through, and there is no server-side
635
+ * copy that could drift. Their availability therefore cannot come from
636
+ * `listBindableCapsForDeviceType` (a device-NATIVE cap carries no wrappers and
637
+ * is filtered out there); it comes from the cap's own camera-probed
638
+ * `privacyMask.getOptions()`, which is strictly more honest — it answers for
639
+ * THIS camera rather than for the device type
640
+ * ([D74](../../../../docs/decisions/adr-0074.md)).
641
+ *
642
+ * ## `privacy-mask` is the one row whose ON is not "the function is working"
643
+ *
644
+ * Every other switch means *this camera's function is doing its job*, so
645
+ * `enabled: false` is a thing an operator took away. `privacy-mask` means **the
646
+ * MASK is active** — `enabled: true` is video deliberately obscured. The
647
+ * polarity is not a choice made here: `addon-export-hap`'s privacy `Switch`
648
+ * (`builders/privacy-switch.ts`) already mirrors `patch.enabled` verbatim, and
649
+ * a HomeKit toggle that disagreed with the app's toggle for the same camera is
650
+ * worse than either surface not having one.
651
+ *
652
+ * Two consequences follow and both are load-bearing:
653
+ *
654
+ * - **It never counts as `switchedOff`.** `countsAsSwitchedOff` is `false` for
655
+ * exactly this row. With the polarity above, every camera that has NOT drawn
656
+ * a privacy mask would otherwise report `switchedOff: ['privacy-mask']` — the
657
+ * normal, healthy state of most cameras rendered as an operator disablement.
658
+ * - **Its cost line names BOTH directions.** `costWhenOff` is rendered
659
+ * unconditionally by both clients, so for this row it has to read correctly
660
+ * whichever way the switch is sitting.
915
661
  *
916
662
  * The wrapper-binding pair is not a new idea: `legacy-migrations.ts` already
917
663
  * migrated the legacy `audioEnabled` / `pipelineEnabled` /
@@ -930,22 +676,44 @@ var DEFAULT_RETENTION = {
930
676
  * `CameraStatus.switchedOff`.
931
677
  */
932
678
  /**
933
- * The five functions the operator named (2026-08-05). Deliberately NOT one id
934
- * per pipeline step: face recognition and plate/LPR are per-step toggles on
679
+ * The functions the operator named — five on 2026-08-05, plus the camera's own
680
+ * microphone on 2026-08-07. Deliberately NOT one id per pipeline step: face
681
+ * recognition and plate/LPR are per-step toggles on
935
682
  * `pipelineOrchestrator.setCameraStepToggle` and belong in the pipeline
936
- * editor, not in a five-button safety group.
683
+ * editor, not in a safety group.
937
684
  */
938
685
  var CameraSwitchIdSchema = z.enum([
939
686
  "stream-broker",
940
687
  "object-detection",
688
+ "privacy-mask",
689
+ "device-audio",
690
+ "broker-audio",
941
691
  "audio-analysis",
942
692
  "recording",
943
693
  "notifications"
944
694
  ]);
945
- /** Stable render order — broadest blast radius first. */
695
+ /**
696
+ * Stable render order — broadest blast radius first, and a source before the
697
+ * thing that consumes it. `device-audio` sits ABOVE `audio-analysis` because
698
+ * turning the microphone off leaves the analyzer with nothing to analyse; the
699
+ * reverse is not true.
700
+ *
701
+ * `privacy-mask` sits directly ABOVE `device-audio` because they are literal
702
+ * siblings — one cap, one device plane, video then audio — and NOT above
703
+ * `object-detection` despite feeding it: a mask blanks REGIONS, so its blast
704
+ * radius is partial, and the "broadest first" rule does not rank a partial
705
+ * control above a whole-function one.
706
+ *
707
+ * `broker-audio` sits directly BELOW `device-audio` by the same source-first
708
+ * rule: the camera's microphone feeds the broker, so silencing the camera
709
+ * leaves the broker's mute with nothing to suppress; the reverse is not true.
710
+ */
946
711
  var CAMERA_SWITCH_ORDER = [
947
712
  "stream-broker",
948
713
  "object-detection",
714
+ "privacy-mask",
715
+ "device-audio",
716
+ "broker-audio",
949
717
  "audio-analysis",
950
718
  "recording",
951
719
  "notifications"
@@ -963,14 +731,27 @@ var CameraSwitchAuthoritySchema = z.discriminatedUnion("kind", [
963
731
  capName: z.string()
964
732
  }),
965
733
  z.object({ kind: z.literal("recording-config") }),
966
- z.object({ kind: z.literal("notification-mute") })
734
+ z.object({ kind: z.literal("notification-mute") }),
735
+ z.object({
736
+ kind: z.literal("camera-audio"),
737
+ capName: z.string()
738
+ }),
739
+ z.object({
740
+ kind: z.literal("camera-mask"),
741
+ capName: z.string()
742
+ }),
743
+ z.object({ kind: z.literal("broker-audio-mute") })
967
744
  ]);
968
745
  /**
969
746
  * Why a switch is not offered for this camera. Rendered instead of the
970
747
  * control, never as a dead control — an absent function and a broken one must
971
748
  * not look the same.
972
749
  */
973
- var CameraSwitchUnavailableReasonSchema = z.enum(["no-provider", "source-unreachable"]);
750
+ var CameraSwitchUnavailableReasonSchema = z.enum([
751
+ "no-provider",
752
+ "source-unreachable",
753
+ "not-configured"
754
+ ]);
974
755
  /**
975
756
  * One switch, resolved for one camera.
976
757
  *
@@ -1010,6 +791,13 @@ var CameraSwitchGroupSchema = z.object({
1010
791
  var DETECTION_PIPELINE_CAP_NAME = "detection-pipeline";
1011
792
  var AUDIO_ANALYSIS_CAP_NAME = "audio-analysis";
1012
793
  /**
794
+ * The device-NATIVE cap that owns what the camera does not capture — masked
795
+ * video regions and, since 2026-08-07, the microphone. Named here because the
796
+ * `camera-audio` authority, the orchestrator's gather and the fake harness all
797
+ * have to agree on it.
798
+ */
799
+ var PRIVACY_MASK_CAP_NAME = "privacy-mask";
800
+ /**
1013
801
  * THE catalog. One entry per switch; the cost lines are the operator-facing
1014
802
  * contract and are written to be true rather than reassuring.
1015
803
  */
@@ -1018,7 +806,8 @@ var CAMERA_SWITCH_CATALOG = {
1018
806
  id: "stream-broker",
1019
807
  label: "Camera",
1020
808
  costWhenOff: "Off: the whole camera stops. No live view, no recording, no detection and no notifications — its streams are released and nothing dials it again until you turn it back on.",
1021
- authority: { kind: "device-disabled" }
809
+ authority: { kind: "device-disabled" },
810
+ countsAsSwitchedOff: true
1022
811
  },
1023
812
  "object-detection": {
1024
813
  id: "object-detection",
@@ -1027,7 +816,35 @@ var CAMERA_SWITCH_CATALOG = {
1027
816
  authority: {
1028
817
  kind: "wrapper-binding",
1029
818
  capName: DETECTION_PIPELINE_CAP_NAME
1030
- }
819
+ },
820
+ countsAsSwitchedOff: true
821
+ },
822
+ "privacy-mask": {
823
+ id: "privacy-mask",
824
+ label: "Privacy mask",
825
+ costWhenOff: "On: the zones you drew on this camera are blacked out by the camera itself — live view, playback, exports and detection all see the black boxes, and nothing behind them was ever recorded. Off: the camera captures the whole frame, and your zones are kept for when you turn it back on.",
826
+ authority: {
827
+ kind: "camera-mask",
828
+ capName: PRIVACY_MASK_CAP_NAME
829
+ },
830
+ countsAsSwitchedOff: false
831
+ },
832
+ "device-audio": {
833
+ id: "device-audio",
834
+ label: "Camera microphone",
835
+ costWhenOff: "Off: the camera captures no sound at all. Live view and recordings become silent video, and audio detection and classification have nothing left to analyse — turning them back on will not recover it. The picture, motion and object detection are unaffected, and two-way talk still works. Applies at the camera, so every consumer sees the same silence.",
836
+ authority: {
837
+ kind: "camera-audio",
838
+ capName: PRIVACY_MASK_CAP_NAME
839
+ },
840
+ countsAsSwitchedOff: true
841
+ },
842
+ "broker-audio": {
843
+ id: "broker-audio",
844
+ label: "Audio distribution",
845
+ costWhenOff: "Off: this server distributes no sound for this camera — live view is silent and everything recorded while it is off is silent FOREVER, even after you turn it back on. Audio detection and classification also have nothing to analyse. The camera keeps capturing sound, so nothing about the camera changes and turning this back on is instant, with no interruption to the picture.",
846
+ authority: { kind: "broker-audio-mute" },
847
+ countsAsSwitchedOff: true
1031
848
  },
1032
849
  "audio-analysis": {
1033
850
  id: "audio-analysis",
@@ -1036,19 +853,22 @@ var CAMERA_SWITCH_CATALOG = {
1036
853
  authority: {
1037
854
  kind: "wrapper-binding",
1038
855
  capName: AUDIO_ANALYSIS_CAP_NAME
1039
- }
856
+ },
857
+ countsAsSwitchedOff: true
1040
858
  },
1041
859
  recording: {
1042
860
  id: "recording",
1043
861
  label: "Recording",
1044
862
  costWhenOff: "Off: nothing new is written to disk. Footage already recorded stays, but retention keeps deleting it — so this camera’s history shrinks and is not replaced. Your recording schedule is kept and resumes when you turn it back on.",
1045
- authority: { kind: "recording-config" }
863
+ authority: { kind: "recording-config" },
864
+ countsAsSwitchedOff: true
1046
865
  },
1047
866
  notifications: {
1048
867
  id: "notifications",
1049
868
  label: "Notifications",
1050
869
  costWhenOff: "Off: this camera never notifies anyone, on any rule, with no expiry. Detection, events and recording carry on exactly as before — you simply stop being told about them.",
1051
- authority: { kind: "notification-mute" }
870
+ authority: { kind: "notification-mute" },
871
+ countsAsSwitchedOff: true
1052
872
  }
1053
873
  };
1054
874
  /** Resolve one switch's `{ available, enabled }` pair. */
@@ -1095,6 +915,67 @@ function resolveState(descriptor, input) {
1095
915
  available: true,
1096
916
  enabled: !input.notificationsMuted
1097
917
  };
918
+ case "camera-audio": {
919
+ const audio = input.deviceAudio;
920
+ if (audio === null) return {
921
+ available: false,
922
+ enabled: true,
923
+ unavailableReason: "source-unreachable"
924
+ };
925
+ if (!audio.supported) return {
926
+ available: false,
927
+ enabled: true,
928
+ unavailableReason: "no-provider"
929
+ };
930
+ if (audio.enabled === null) return {
931
+ available: false,
932
+ enabled: true,
933
+ unavailableReason: "source-unreachable"
934
+ };
935
+ return {
936
+ available: true,
937
+ enabled: audio.enabled
938
+ };
939
+ }
940
+ case "camera-mask": {
941
+ const mask = input.privacyMask;
942
+ if (mask === null) return {
943
+ available: false,
944
+ enabled: false,
945
+ unavailableReason: "source-unreachable"
946
+ };
947
+ if (!mask.supported) return {
948
+ available: false,
949
+ enabled: false,
950
+ unavailableReason: "no-provider"
951
+ };
952
+ if (mask.configuredRegions === null || mask.enabled === null) return {
953
+ available: false,
954
+ enabled: false,
955
+ unavailableReason: "source-unreachable"
956
+ };
957
+ if (mask.configuredRegions === 0) return {
958
+ available: false,
959
+ enabled: false,
960
+ unavailableReason: "not-configured"
961
+ };
962
+ return {
963
+ available: true,
964
+ enabled: mask.enabled
965
+ };
966
+ }
967
+ case "broker-audio-mute": {
968
+ const broker = input.brokerAudio;
969
+ if (broker === null) return {
970
+ available: false,
971
+ enabled: true,
972
+ unavailableReason: "source-unreachable"
973
+ };
974
+ return {
975
+ available: true,
976
+ enabled: !broker.muted
977
+ };
978
+ }
1098
979
  }
1099
980
  }
1100
981
  /**
@@ -1128,9 +1009,15 @@ function deriveCameraSwitches(input) {
1128
1009
  * `switchedOff: ['object-detection']` was turned off; the same camera with an
1129
1010
  * empty list is broken. Unavailable switches never appear — a function nobody
1130
1011
  * provides was not switched off by anyone.
1012
+ *
1013
+ * `privacy-mask` never appears either, whichever way it is sitting, because its
1014
+ * ON means "the mask is active" rather than "the function works"
1015
+ * ({@link CameraSwitchDescriptor.countsAsSwitchedOff}). Without that filter the
1016
+ * ordinary state of every camera nobody has masked would carry a
1017
+ * "switched off" badge, and the badge that matters would be lost in it.
1131
1018
  */
1132
1019
  function switchedOffIds(switches) {
1133
- return switches.filter((s) => s.available && !s.enabled).map((s) => s.id);
1020
+ return switches.filter((s) => CAMERA_SWITCH_CATALOG[s.id].countsAsSwitchedOff && s.available && !s.enabled).map((s) => s.id);
1134
1021
  }
1135
1022
  //#endregion
1136
1023
  //#region src/interfaces/device-capabilities/camera.ts
@@ -4166,6 +4053,26 @@ var EgressTranscodeRequestSchema = z.object({
4166
4053
  "h264_mp4toannexb",
4167
4054
  "hevc_mp4toannexb"
4168
4055
  ]).optional(),
4056
+ /**
4057
+ * Publish the transcode as a LOCAL push cam stream, instead of leaving the
4058
+ * consumer to dial the returned url. The broker picks the id and returns it
4059
+ * as `camStreamId` — a caller-supplied one would be circular, since the
4060
+ * sharing key is computed FROM this request.
4061
+ *
4062
+ * The url is still returned and still the contract for a transcode pinned to
4063
+ * another node. But dialling it locally costs an RTSP round trip that changes
4064
+ * the transport underneath the consumer: a dialled stream is an RTP source,
4065
+ * so `isRtpSource()` is true and the session takes the RTP-passthrough +
4066
+ * repacketizer branch. The push branch — the one the derived mechanism has
4067
+ * live hours on — is never reached. Measured on Alexa: broker registered, RTP
4068
+ * arriving, key frame arriving, black screen, on a chain healthy at every
4069
+ * other point.
4070
+ *
4071
+ * Same idea the transport already applies to CALLS, where `classifyCapRoute`
4072
+ * gives priority to `hub-in-process` so a local call never leaves the node.
4073
+ * This is that rule for media.
4074
+ */
4075
+ publishLocally: z.boolean().optional(),
4169
4076
  pixelFormat: z.enum(["yuv420p", "nv12"]).optional(),
4170
4077
  /**
4171
4078
  * Operator/consumer override for decode hardware. ABSENT is the normal case
@@ -4210,7 +4117,13 @@ var EgressTranscodeSchema = z.object({
4210
4117
  * Returned rather than assumed: a consumer that asked for hardware and got
4211
4118
  * software needs to be able to see that without reading the broker's logs.
4212
4119
  */
4213
- decodeHwAccel: z.string().nullable()
4120
+ decodeHwAccel: z.string().nullable(),
4121
+ /**
4122
+ * Set when `publishLocally` was honoured: attach to THIS instead of dialling
4123
+ * `url`, and the session takes the push/deframe transport rather than the
4124
+ * RTP-passthrough one. `null` means the consumer must dial.
4125
+ */
4126
+ camStreamId: z.string().nullable()
4214
4127
  });
4215
4128
  var streamBrokerCapability = {
4216
4129
  name: "stream-broker",
@@ -4504,7 +4417,44 @@ var streamBrokerCapability = {
4504
4417
  kind: "mutation",
4505
4418
  auth: "admin"
4506
4419
  }),
4507
- isRtspEnabled: method(z.object({ brokerId: z.string() }), z.boolean())
4420
+ isRtspEnabled: method(z.object({ brokerId: z.string() }), z.boolean()),
4421
+ /**
4422
+ * ── Per-device audio-plane policy (D83) ───────────────────────────
4423
+ *
4424
+ * The BROKER-side mute: while `muted`, this node distributes none of
4425
+ * the device's audio, on any plane it serves — live (WebRTC / encoded
4426
+ * subscribers) AND recording (the RTSP restreamer the recorder pulls,
4427
+ * which additionally serves the video-only SDP so the recorder's ffmpeg
4428
+ * never declares an audio stream it will not receive).
4429
+ *
4430
+ * Keyed by `deviceId`, not `brokerId`: every one of a camera's streams
4431
+ * carries the same microphone, and a per-stream answer would let main
4432
+ * and sub disagree about whether the camera is silent.
4433
+ *
4434
+ * The state lives in the broker's existing `DeviceOverride` blob — no
4435
+ * new store — and the mute is applied to a fresh broker at creation, so
4436
+ * a restart, a re-dial or a catalog republish never un-mutes a camera.
4437
+ */
4438
+ getDeviceAudioMute: method(z.object({ deviceId: z.number().int() }), z.object({
4439
+ muted: z.boolean(),
4440
+ /**
4441
+ * How many live non-derived brokers currently hold the mute. Purely
4442
+ * diagnostic: `muted` is the policy and is authoritative on its own
4443
+ * (it applies to brokers that do not exist yet), while this says
4444
+ * whether anything is presently being silenced.
4445
+ */
4446
+ appliedBrokers: z.number().int().nonnegative()
4447
+ })),
4448
+ setDeviceAudioMute: method(z.object({
4449
+ deviceId: z.number().int(),
4450
+ muted: z.boolean()
4451
+ }), z.object({
4452
+ muted: z.boolean(),
4453
+ appliedBrokers: z.number().int().nonnegative()
4454
+ }), {
4455
+ kind: "mutation",
4456
+ auth: "admin"
4457
+ })
4508
4458
  },
4509
4459
  events: {
4510
4460
  onCamStreamDemand: event(z.object({
@@ -12351,6 +12301,30 @@ var TrackSourceSchema = z.enum([
12351
12301
  "audio"
12352
12302
  ]);
12353
12303
  /**
12304
+ * Where a track sits in the RETRAIN lifecycle (D81).
12305
+ *
12306
+ * - `none` — never marked, or un-marked. Evictable.
12307
+ * - `staging` — the operator wants this track as training material and has not
12308
+ * finished with it. **This is the only state retention holds**: the track and
12309
+ * everything it owns (object events, crops, keyframes, CLIP vector) survive
12310
+ * the device's age window.
12311
+ * - `trained` — the retrain page has taken what it needed. The frames it chose
12312
+ * were COPIED into the retrain dataset at selection time, so the dataset no
12313
+ * longer depends on the track's media and the track becomes EVICTABLE again.
12314
+ * Terminal for the plain `markForTrain` toggle: returning it to `staging` is
12315
+ * a deliberate action of the retrain page, not a side effect of a checkbox.
12316
+ *
12317
+ * There is no `null`. The state is stored `TEXT NOT NULL DEFAULT 'none'` because
12318
+ * the store's filter language has only positive equality and `whereIn` — no
12319
+ * negation, no IS NULL — so a NULL would be unselectable by ANY predicate and
12320
+ * would make the entire pre-column history immortal in one deploy.
12321
+ */
12322
+ var RetrainStatusSchema = z.enum([
12323
+ "none",
12324
+ "staging",
12325
+ "trained"
12326
+ ]);
12327
+ /**
12354
12328
  * Per-track OPERATOR flags — set by hand from the admin UI or the viewer, never
12355
12329
  * by the pipeline. Spread into `TrackSchema` and `KeyEventSchema` from one place
12356
12330
  * so the two surfaces cannot drift.
@@ -12360,18 +12334,31 @@ var TrackSourceSchema = z.enum([
12360
12334
  * columns existed read as absent, and a consumer that needs a boolean should say
12361
12335
  * `flag === true`, not `flag !== false`.
12362
12336
  *
12363
- * What the flags DO is deliberately UNDEFINED at the time of writing: they are
12364
- * operator curation, and the behaviour they drive will be specified separately.
12365
- * In particular a `markForTrain` track is NOT pinned against retention — see
12366
- * `docs/decisions/adr-0059.md` for why that is a store-level change, not a flag.
12337
+ * `markForTrain` is the WIRE FACE of {@link RetrainStatusSchema}, not a column:
12338
+ * it is exactly `retrainStatus === 'staging'`, in both directions. Writing
12339
+ * `true` moves `none → staging`, writing `false` moves `staging none`, and a
12340
+ * `trained` track reports `false` while refusing both writes. The boolean is
12341
+ * kept because three surfaces drive a toggle off it; anything that needs to tell
12342
+ * "never marked" from "already trained" must read `retrainStatus`.
12343
+ *
12344
+ * `debug` does NOT pin; it is attention, not durability.
12367
12345
  */
12368
12346
  var TrackFlagFields = {
12369
- /** Operator marked this track as training material. */
12347
+ /** Operator marked this track as training material — i.e. `retrainStatus` is
12348
+ * `'staging'`. */
12370
12349
  markForTrain: z.boolean().optional(),
12371
12350
  /** Operator marked this track for diagnostic attention. */
12372
12351
  debug: z.boolean().optional()
12373
12352
  };
12374
12353
  /**
12354
+ * The lifecycle field itself, on the READ surfaces only (`Track`, `KeyEvent`).
12355
+ * Deliberately NOT part of {@link TrackFlagFields}: that group also builds the
12356
+ * write patch, and the status is not something the toggle sets — it is what the
12357
+ * toggle's boolean is derived from. Absent on an in-RAM track never touched;
12358
+ * always present on a persisted row (the column default materialises `'none'`).
12359
+ */
12360
+ var TrackRetrainFields = { retrainStatus: RetrainStatusSchema.optional() };
12361
+ /**
12375
12362
  * The write half: a PARTIAL patch. An omitted key is left untouched, so setting
12376
12363
  * one flag can never clear the other — the toggles are independent and are
12377
12364
  * driven from three surfaces that do not know about each other.
@@ -12385,7 +12372,32 @@ var TrackFlagsPatchSchema = z.object(TrackFlagFields);
12385
12372
  var TrackFlagsSchema = z.object({
12386
12373
  trackId: z.string(),
12387
12374
  markForTrain: z.boolean(),
12388
- debug: z.boolean()
12375
+ debug: z.boolean(),
12376
+ /** The lifecycle state the boolean was derived from. Required here (unlike on
12377
+ * a track row) because this shape is only ever produced by the write body,
12378
+ * which always knows it — and a surface that has just written needs to render
12379
+ * `trained` without a re-fetch. */
12380
+ retrainStatus: RetrainStatusSchema
12381
+ });
12382
+ /** Per-camera slice of a training-export estimate. */
12383
+ var TrainingExportDeviceTotalsSchema = z.object({
12384
+ deviceId: z.number(),
12385
+ tracks: z.number().int(),
12386
+ files: z.number().int(),
12387
+ bytes: z.number().int()
12388
+ });
12389
+ /**
12390
+ * What a training export WOULD contain. Computed from media index rows only —
12391
+ * no blob is read to produce this.
12392
+ */
12393
+ var TrainingExportSummarySchema = z.object({
12394
+ generatedAt: z.number(),
12395
+ trackCount: z.number().int(),
12396
+ fileCount: z.number().int(),
12397
+ byteCount: z.number().int(),
12398
+ /** More marked tracks exist than a single pass carries. */
12399
+ truncated: z.boolean(),
12400
+ devices: z.array(TrainingExportDeviceTotalsSchema).readonly()
12389
12401
  });
12390
12402
  var TrackSchema = z.object({
12391
12403
  trackId: z.string(),
@@ -12430,7 +12442,8 @@ var TrackSchema = z.object({
12430
12442
  * Populated from the persisted envelope columns on historical reads;
12431
12443
  * absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
12432
12444
  envelope: TrackEnvelopeSchema.optional(),
12433
- ...TrackFlagFields
12445
+ ...TrackFlagFields,
12446
+ ...TrackRetrainFields
12434
12447
  });
12435
12448
  var BaseEventFields = {
12436
12449
  id: z.string(),
@@ -12652,7 +12665,8 @@ var KeyEventSchema = z.object({
12652
12665
  bestEventId: z.string(),
12653
12666
  /** Track lifetime in ms (lastSeen - firstSeen). */
12654
12667
  windowMs: z.number().optional(),
12655
- ...TrackFlagFields
12668
+ ...TrackFlagFields,
12669
+ ...TrackRetrainFields
12656
12670
  });
12657
12671
  var TrackedDetectionSchema = z.object({
12658
12672
  trackId: z.string(),
@@ -13014,11 +13028,29 @@ var pipelineAnalyticsCapability = {
13014
13028
  *
13015
13029
  * `auth: 'protected'` (the default), NOT `admin`: the viewer is an
13016
13030
  * authenticated non-admin surface and two of the three call sites are
13017
- * there. Revisit if a flag ever gains an effect that costs storage
13018
- * `deleteTracks` next door is admin for exactly that reason.
13031
+ * there. The note that used to sit here said to revisit this the day a flag
13032
+ * gained an effect that costs storage, and D81 is that day — `markForTrain`
13033
+ * now pins. It STAYS protected, and the reason is that the alternative
13034
+ * makes the feature pointless: marking a track is something you do while
13035
+ * looking at it, on the surface you were already looking at it on, and that
13036
+ * surface is the viewer. What the storage cost gets instead is a BOUND — a
13037
+ * per-device pin budget enforced in the body, refusing a new pin past the
13038
+ * limit while always allowing un-marking. `deleteTracks` next door is still
13039
+ * admin, because destroying evidence and preserving it are not symmetric.
13040
+ *
13041
+ * `markForTrain` writes the retrain LIFECYCLE, not a boolean column: `true`
13042
+ * is `none → staging`, `false` is `staging → none`. A track already
13043
+ * `trained` refuses BOTH — its frames are copies inside the retrain dataset
13044
+ * and re-staging it from a generic toggle is how the same material gets
13045
+ * annotated twice under two ground truths. Returning a trained track to
13046
+ * staging is a deliberate action of the retrain page, which is also the only
13047
+ * thing that produces `trained` in the first place.
13019
13048
  *
13020
- * Returns the RESOLVED state of both flags (absent → `false`) so a caller
13021
- * can drive its toggle without a re-fetch. Rejects an unknown track.
13049
+ * Returns the RESOLVED state of both flags (absent → `false`) plus the
13050
+ * `retrainStatus` they were derived from, so a caller can drive its toggle
13051
+ * — and render a `trained` badge — without a re-fetch. Rejects an unknown
13052
+ * track, a new staging mark on a device already holding its full budget, and
13053
+ * any `markForTrain` write against a trained track.
13022
13054
  */
13023
13055
  setTrackFlags: method(z.object({
13024
13056
  /** Log/audit scope only — the trackId is globally unique on its own. */
@@ -13082,6 +13114,42 @@ var pipelineAnalyticsCapability = {
13082
13114
  kind: "query",
13083
13115
  auth: "admin"
13084
13116
  }),
13117
+ /**
13118
+ * The CHEAP QUESTION, asked before any media moves: how big is the dataset
13119
+ * the marked (`markForTrain`) tracks would produce?
13120
+ *
13121
+ * Answered from media INDEX rows only — key, kind, size, timestamp — so it
13122
+ * costs ~2 KB of reads per track and no blob reads at all. The measured harm
13123
+ * behind D56 was a bulk pass that read and base64'd every blob a track owned
13124
+ * before deciding anything, taking hub-main to 82 s busy out of 120; an
13125
+ * export is that same I/O shape, so it inherits the same discipline: know
13126
+ * the size, then decide.
13127
+ *
13128
+ * `truncated` reports that more marked tracks exist than one pass carries.
13129
+ * Empty `deviceIds` ⇒ every device that has marked tracks.
13130
+ */
13131
+ getTrainingExportSummary: method(z.object({ deviceIds: z.array(z.number()).optional() }), TrainingExportSummarySchema, {
13132
+ kind: "query",
13133
+ auth: "admin"
13134
+ }),
13135
+ /**
13136
+ * Where to download the dataset archive.
13137
+ *
13138
+ * The BYTES do not come back through this cap — they come from the returned
13139
+ * data-plane URL, which streams a tar built entry by entry. A multi-gigabyte
13140
+ * archive base64'd through a unary RPC envelope would be held whole in
13141
+ * memory twice on a hub this repo has already OOM'd once (D9/D18 are the
13142
+ * same lesson about frames). `getDownloadUrl` on `recordingExport` is the
13143
+ * precedent, and this follows it deliberately.
13144
+ *
13145
+ * The archive contains a `manifest.json` FIRST, then the stored media
13146
+ * VERBATIM under `tracks/<deviceId>/<trackId>/…`. No crop is derived and no
13147
+ * model is run: a training set's pixels must be the pixels the pipeline saw.
13148
+ */
13149
+ getTrainingExportUrl: method(z.object({ deviceIds: z.array(z.number()).optional() }), z.object({ url: z.string() }), {
13150
+ kind: "query",
13151
+ auth: "admin"
13152
+ }),
13085
13153
  getEventMedia: method(z.object({
13086
13154
  eventId: z.string(),
13087
13155
  kind: MediaFileKindEnum.optional()
@@ -15862,9 +15930,15 @@ var snapshotCapability = {
15862
15930
  * Bypass the cache freshness check and fetch directly from the
15863
15931
  * native (or stream-broker fallback). Triggered by the UI's
15864
15932
  * "refresh" button so an operator can force a fresh frame
15865
- * even when the cache is well within `snapshotMaxAgeMs`.
15866
- * On battery cams this WILL wake the camera — accept the
15867
- * cost only when the user explicitly asks for it.
15933
+ * even when the cache is well within the device's
15934
+ * `snapshotMaxAgeS` window.
15935
+ *
15936
+ * **`force` is an OPERATOR signal, not a freshness preference.** On a
15937
+ * battery camera it is the one thing that walks past the wrapper's
15938
+ * sleep gate and wakes the camera, so a background caller — a poller,
15939
+ * an event handler, a thumbnail — must NEVER set it. Every such caller
15940
+ * gets the cached frame, which on a sleeping battery camera is the
15941
+ * correct answer: stale but honest beats woken.
15868
15942
  */
15869
15943
  force: z.boolean().optional()
15870
15944
  }), SnapshotImageSchema.nullable()),
@@ -21840,6 +21914,216 @@ setOverlay: method(z.object({
21840
21914
  }] }
21841
21915
  };
21842
21916
  //#endregion
21917
+ //#region src/capabilities/osd-manager.cap.ts
21918
+ /**
21919
+ * `osd-manager` — the ORCHESTRATOR over the device-scope `osd` cap.
21920
+ *
21921
+ * The `osd` cap is the firmware contract: it probes a camera's overlay
21922
+ * SLOTS and writes literal text into one. It has no idea WHERE that text
21923
+ * comes from, and it must not — a driver that grew a "show the temperature
21924
+ * here" feature would grow it once per vendor.
21925
+ *
21926
+ * This cap owns the other half: a per-(camera, slot) BINDING that says
21927
+ * which value feeds the slot, how it is formatted, and under which
21928
+ * conditions it is shown at all. One addon renders every binding on every
21929
+ * camera, so a new source costs zero driver code.
21930
+ *
21931
+ * Three deliberate choices, each with a rejected alternative:
21932
+ *
21933
+ * 1. A source is `(capName, valuePath)` over the kernel's device
21934
+ * runtime-state mirror — NOT a closed enum of source kinds. Every
21935
+ * cap-keyed slice a device publishes is bindable the day the cap
21936
+ * ships. The rejected alternative (one enum member per source, with
21937
+ * a resolver branch each) is what makes "add the humidity too" a
21938
+ * code change.
21939
+ * 2. The display gate reuses `NcConditionsSchema` verbatim — the
21940
+ * notification centre's condition vocabulary — rather than a parallel
21941
+ * model. An operator who has learned one condition editor has learned
21942
+ * both.
21943
+ * 3. Because the renderer's facts are device STATE and not a detection
21944
+ * record, only a SUBSET of that vocabulary can be answered here.
21945
+ * `setSlotBinding` REJECTS the rest at write time (see
21946
+ * `getConditionSupport`). It does not accept-then-fail-closed: a
21947
+ * condition that can never be true renders a permanently blank
21948
+ * overlay, and a blank overlay looks exactly like a broken camera.
21949
+ */
21950
+ /** Where a slot's value comes from. */
21951
+ var OsdSourceSchema = z.discriminatedUnion("kind", [
21952
+ z.object({
21953
+ kind: z.literal("static"),
21954
+ text: z.string().max(64)
21955
+ }),
21956
+ z.object({
21957
+ kind: z.literal("clock"),
21958
+ /** Token pattern: `YYYY MM DD HH mm ss`. Everything else is literal. */
21959
+ pattern: z.string().min(1).max(32).default("HH:mm"),
21960
+ /** IANA zone. Omitted = the server's zone. */
21961
+ timezone: z.string().min(1).max(64).optional()
21962
+ }),
21963
+ z.object({
21964
+ kind: z.literal("device-state"),
21965
+ deviceId: z.number().int().optional(),
21966
+ capName: z.string().min(1).max(64),
21967
+ /** Dot path inside the slice, e.g. `detected`, `value`, `mode`. */
21968
+ valuePath: z.string().min(1).max(64)
21969
+ })
21970
+ ]);
21971
+ var OsdSlotBindingSchema = z.object({
21972
+ /** Off = the manager stops driving this slot. It does NOT clear it. */
21973
+ enabled: z.boolean().default(true),
21974
+ source: OsdSourceSchema,
21975
+ /** `${value}` and `${unit}` are substituted; every occurrence. */
21976
+ template: z.string().max(96).default("${value}"),
21977
+ /** Truncate with an ellipsis past this length. Absent = no limit. */
21978
+ maxCharacters: z.number().int().min(4).max(64).optional(),
21979
+ /**
21980
+ * Decimal places for a numeric value. `0` yields an integer — the
21981
+ * documented workaround for firmwares that reject `.` in overlay text.
21982
+ */
21983
+ maxDecimals: z.number().int().min(0).max(4).default(1),
21984
+ /** Appended via `${unit}`. The state mirror does not carry units. */
21985
+ unitLabel: z.string().max(8).optional(),
21986
+ /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
21987
+ valueMap: z.record(z.string(), z.string()).optional(),
21988
+ /** Time windows in which the slot is shown. Absent = always. */
21989
+ schedule: NcScheduleSchema.optional(),
21990
+ /**
21991
+ * Display gate, in the notification centre's condition vocabulary.
21992
+ * Only the keys reported by `getConditionSupport` are accepted.
21993
+ */
21994
+ conditions: NcConditionsSchema.optional(),
21995
+ /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
21996
+ fallbackText: z.string().max(64).default("")
21997
+ });
21998
+ /** One camera slot, as the operator sees it: firmware truth + our binding. */
21999
+ var OsdSlotViewSchema = z.object({
22000
+ slotId: z.string(),
22001
+ kind: OsdOverlayKindEnum,
22002
+ /** Firmware refuses text edits (a timestamp, the channel name). */
22003
+ readOnly: z.boolean(),
22004
+ cameraEnabled: z.boolean(),
22005
+ cameraText: z.string().optional(),
22006
+ binding: OsdSlotBindingSchema.nullable()
22007
+ });
22008
+ /**
22009
+ * What happened to one slot on one render pass. `unchanged` exists so the
22010
+ * operator can tell "we are driving this and the value is steady" from
22011
+ * "we never got there" — and so the loop can prove it is not rewriting
22012
+ * identical text to the camera every tick.
22013
+ */
22014
+ var OsdRenderOutcomeEnum = z.enum([
22015
+ "written",
22016
+ "unchanged",
22017
+ "gated",
22018
+ "unreadable",
22019
+ "disabled",
22020
+ "unbound",
22021
+ "failed"
22022
+ ]);
22023
+ var OsdRenderResultSchema = z.object({
22024
+ slotId: z.string(),
22025
+ outcome: OsdRenderOutcomeEnum,
22026
+ /** The text the slot should carry. Empty = the slot is switched off. */
22027
+ text: z.string(),
22028
+ /** Why, whenever the outcome is not a plain write. Never silent. */
22029
+ reason: z.string().optional()
22030
+ });
22031
+ var OsdSourceValueTypeEnum = z.enum([
22032
+ "number",
22033
+ "boolean",
22034
+ "string",
22035
+ "enum"
22036
+ ]);
22037
+ /**
22038
+ * One bindable value, derived from a cap's `runtimeState` schema — never
22039
+ * hand-listed. The editor renders from this, so a cap that ships a new
22040
+ * state field becomes bindable with no UI change.
22041
+ */
22042
+ var OsdSourceOptionSchema = z.object({
22043
+ deviceId: z.number().int(),
22044
+ deviceName: z.string(),
22045
+ capName: z.string(),
22046
+ valuePath: z.string(),
22047
+ label: z.string(),
22048
+ valueType: OsdSourceValueTypeEnum,
22049
+ /** Present for `enum`; the editor offers these as `valueMap` keys. */
22050
+ enumValues: z.array(z.string()).readonly().optional()
22051
+ });
22052
+ var osdManagerCapability = {
22053
+ name: "osd-manager",
22054
+ scope: "system",
22055
+ mode: "singleton",
22056
+ methods: {
22057
+ /**
22058
+ * The camera's slots, each with its binding. `supported: false` when
22059
+ * the camera publishes no `osd` cap — the page then says so instead
22060
+ * of rendering an empty list that reads as "no overlays configured".
22061
+ */
22062
+ getDeviceOsd: method(z.object({ deviceId: z.number().int() }), z.object({
22063
+ supported: z.boolean(),
22064
+ slots: z.array(OsdSlotViewSchema)
22065
+ }), { auth: "admin" }),
22066
+ /**
22067
+ * Every value bindable on this camera: its own state leaves first,
22068
+ * then every other device's. Derived from the cap definitions, so it
22069
+ * cannot drift from what the resolver can actually read.
22070
+ */
22071
+ getSourceCatalog: method(z.object({ deviceId: z.number().int() }), z.object({ sources: z.array(OsdSourceOptionSchema) }), { auth: "admin" }),
22072
+ /**
22073
+ * The condition ids this gate can answer, alongside the FULL notification
22074
+ * condition catalog. Both, in one call, on purpose: an editor that showed
22075
+ * the catalog without the supported set would offer conditions that
22076
+ * `setSlotBinding` then rejects.
22077
+ */
22078
+ getConditionSupport: method(z.object({}), z.object({
22079
+ supported: z.array(z.string()),
22080
+ catalog: z.array(NcConditionDescriptorSchema)
22081
+ }), { auth: "admin" }),
22082
+ /**
22083
+ * Persist a binding and render it immediately, returning the slot as
22084
+ * it now stands. Throws when the binding names an unsupported
22085
+ * condition, an unknown cap, or a value path that cap does not have.
22086
+ */
22087
+ setSlotBinding: method(z.object({
22088
+ deviceId: z.number().int(),
22089
+ slotId: z.string().min(1),
22090
+ binding: OsdSlotBindingSchema
22091
+ }), z.object({
22092
+ slot: OsdSlotViewSchema,
22093
+ render: OsdRenderResultSchema
22094
+ }), {
22095
+ kind: "mutation",
22096
+ auth: "admin"
22097
+ }),
22098
+ /** Forget the binding. The slot keeps whatever text it last carried. */
22099
+ clearSlotBinding: method(z.object({
22100
+ deviceId: z.number().int(),
22101
+ slotId: z.string().min(1)
22102
+ }), z.object({ success: z.literal(true) }), {
22103
+ kind: "mutation",
22104
+ auth: "admin"
22105
+ }),
22106
+ /**
22107
+ * Render without writing. `binding` overrides the stored one so an
22108
+ * editor can preview an unsaved change. Mutation kind only to carry
22109
+ * the binding object safely; no side effects.
22110
+ */
22111
+ previewSlot: method(z.object({
22112
+ deviceId: z.number().int(),
22113
+ slotId: z.string().min(1),
22114
+ binding: OsdSlotBindingSchema.optional()
22115
+ }), OsdRenderResultSchema, {
22116
+ kind: "mutation",
22117
+ auth: "admin"
22118
+ }),
22119
+ /** Force a render pass over one camera now, instead of at the next tick. */
22120
+ renderDevice: method(z.object({ deviceId: z.number().int() }), z.object({ results: z.array(OsdRenderResultSchema) }), {
22121
+ kind: "mutation",
22122
+ auth: "admin"
22123
+ })
22124
+ }
22125
+ };
22126
+ //#endregion
21843
22127
  //#region src/capabilities/pet-feeder.cap.ts
21844
22128
  /**
21845
22129
  * PetKit pet-feeder cap. Models the control + telemetry surface of a
@@ -22487,12 +22771,30 @@ var pressureSensorCapability = {
22487
22771
  //#endregion
22488
22772
  //#region src/capabilities/privacy-mask.cap.ts
22489
22773
  /**
22490
- * Privacy mask = up to `maxRegions` SHAPES the camera blanks out (NOT a
22491
- * cell grid). Reolink `<shelterList>` zones are rectangles; Hikvision
22492
- * ISAPI `<RegionCoordinatesList>` zones are free polygons (this camera:
22493
- * exactly 4 vertices, not necessarily axis-aligned). The cap composes the
22494
- * shared rect|polygon subset of the MaskShape vocabulary. All coords are
22495
- * normalized 0..1 (top-left origin).
22774
+ * PRIVACY what the camera deliberately does not capture. Two planes:
22775
+ *
22776
+ * - **video**: up to `maxRegions` SHAPES the camera blanks out (NOT a cell
22777
+ * grid). Reolink `<shelterList>` zones are rectangles; Hikvision ISAPI
22778
+ * `<RegionCoordinatesList>` zones are free polygons (this camera: exactly
22779
+ * 4 vertices, not necessarily axis-aligned). The cap composes the shared
22780
+ * rect|polygon subset of the MaskShape vocabulary. All coords are
22781
+ * normalized 0..1 (top-left origin).
22782
+ * - **audio**: the camera's microphone. `setAudioEnabled(false)` stops the
22783
+ * camera encoding an audio track at all, so EVERY consumer — live view,
22784
+ * recording, the audio analyzer, an export — sees silent video. There is
22785
+ * no server-side copy of this fact; the camera is the store and every read
22786
+ * is a read-through, which is why a switch over it cannot drift
22787
+ * ([D62](../../../../docs/decisions/adr-0062.md)).
22788
+ *
22789
+ * Both belong here for one reason: they are the two things an operator turns
22790
+ * off when the answer to "what is this camera allowed to record" changes, and
22791
+ * both are applied ON the device, before anything leaves it.
22792
+ *
22793
+ * **The audio flag has exactly one writer.** `stream-params` used to carry a
22794
+ * per-profile `audio` in its patch schema — reachable from no UI and honoured
22795
+ * by one provider — and it was removed when this landed. A second writer onto
22796
+ * one device register is the shape of every knob this repo has shipped that
22797
+ * disagreed with the one the reader read.
22496
22798
  */
22497
22799
  /** A privacy-mask region's geometry — rectangle or free polygon. */
22498
22800
  var PrivacyMaskShapeSchema = z.discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
@@ -22504,21 +22806,45 @@ var PrivacyMaskRegionSchema = z.object({
22504
22806
  enabled: z.boolean(),
22505
22807
  shape: PrivacyMaskShapeSchema
22506
22808
  });
22507
- /** Current on-camera privacy-mask state — master enable + zones. */
22809
+ /** Current on-camera privacy state — mask master enable + zones + microphone. */
22508
22810
  var PrivacyMaskStatusSchema = z.object({
22509
22811
  enabled: z.boolean(),
22510
22812
  /** Active zones (normalized 0..1). Length ≤ maxRegions. */
22511
22813
  regions: z.array(PrivacyMaskRegionSchema),
22814
+ /**
22815
+ * Is the camera capturing sound right now? Read from the camera, never from
22816
+ * a server-side mirror.
22817
+ *
22818
+ * `null` means "no answer" — either this camera exposes no controllable
22819
+ * microphone (`getOptions().supportsAudioMute === false`) or the read
22820
+ * failed. A consumer must render `null` as UNKNOWN and never as `false`:
22821
+ * "the microphone is off" and "we could not ask" look identical to an
22822
+ * operator only until one of them is wrong.
22823
+ *
22824
+ * On a camera whose profiles carry the flag independently (Reolink writes
22825
+ * it per stream), `true` means AT LEAST ONE profile still carries audio —
22826
+ * privacy is only satisfied when every one of them is silent.
22827
+ */
22828
+ audioEnabled: z.boolean().nullable(),
22512
22829
  lastFetchedAt: z.number()
22513
22830
  });
22514
- /** Per-camera availability. */
22831
+ /** Per-camera availability. Probed, never assumed from the model name. */
22515
22832
  var PrivacyMaskOptionsSchema = z.object({
22516
22833
  /** Maximum number of supported zones. */
22517
22834
  maxRegions: z.number(),
22518
22835
  /** Shape kinds this camera accepts — Reolink: ['rect']; Hikvision: ['rect','polygon']. */
22519
22836
  supportedShapes: z.array(MaskShapeKindSchema),
22520
22837
  /** Polygon vertex bounds when 'polygon' is supported (Hikvision: {min:4,max:4}). */
22521
- polygonVertices: MaskPolygonVerticesSchema.optional()
22838
+ polygonVertices: MaskPolygonVerticesSchema.optional(),
22839
+ /**
22840
+ * Does this camera expose a microphone switch we can actually write?
22841
+ *
22842
+ * Camera-probed: `true` only when the firmware answered with an audio flag
22843
+ * we know how to patch. A camera that never answered is `false` — a control
22844
+ * the operator can press that changes nothing is worse than no control, and
22845
+ * the switch group renders "not available" instead.
22846
+ */
22847
+ supportsAudioMute: z.boolean()
22522
22848
  });
22523
22849
  /** Partial change — every field optional. */
22524
22850
  var PrivacyMaskPatchSchema = z.object({
@@ -22545,6 +22871,27 @@ var privacyMaskCapability = {
22545
22871
  }), z.void(), {
22546
22872
  kind: "mutation",
22547
22873
  auth: "admin"
22874
+ }),
22875
+ /**
22876
+ * Turn the camera's microphone on or off, at the camera.
22877
+ *
22878
+ * Deliberately its OWN mutation rather than a field on
22879
+ * {@link PrivacyMaskPatchSchema}: `patch.enabled` already means "the video
22880
+ * mask master switch", and overloading it would make one boolean mean two
22881
+ * unrelated things on the same call. It is also the only method here whose
22882
+ * write leaves the device in a state a later `getStatus` reads back
22883
+ * verbatim, which is what makes it safe as a switch authority.
22884
+ *
22885
+ * A camera whose `getOptions().supportsAudioMute` is false must REJECT
22886
+ * this rather than silently accept it — a write nothing applies is exactly
22887
+ * what the switch group exists to remove.
22888
+ */
22889
+ setAudioEnabled: method(z.object({
22890
+ deviceId: z.number(),
22891
+ enabled: z.boolean()
22892
+ }), z.void(), {
22893
+ kind: "mutation",
22894
+ auth: "admin"
22548
22895
  })
22549
22896
  },
22550
22897
  status: {
@@ -22553,6 +22900,26 @@ var privacyMaskCapability = {
22553
22900
  },
22554
22901
  runtimeState: PrivacyMaskStatusSchema
22555
22902
  };
22903
+ /**
22904
+ * Collapse a camera's PER-PROFILE audio flags into the one answer
22905
+ * {@link PrivacyMaskStatusSchema.shape.audioEnabled} promises.
22906
+ *
22907
+ * Both firmwares this cap talks to store the flag per stream profile, and
22908
+ * both let those profiles disagree. The rule is `some`, not `every`: privacy
22909
+ * is only satisfied when NOTHING is carrying sound, so a camera whose sub
22910
+ * stream is still audible must read as `true` and be switchable off — not as
22911
+ * `false` because the main stream happens to be muted already.
22912
+ *
22913
+ * An empty list is `null` ("this camera reported no audio flag at all"),
22914
+ * never `false`.
22915
+ *
22916
+ * Lives here rather than in each provider so the rule the schema documents
22917
+ * and the rule the providers apply cannot drift apart.
22918
+ */
22919
+ function summarisePrivacyAudio(profiles) {
22920
+ if (profiles.length === 0) return null;
22921
+ return profiles.some((p) => p.audioEnabled);
22922
+ }
22556
22923
  //#endregion
22557
22924
  //#region src/capabilities/ptz.cap.ts
22558
22925
  var PtzPresetSchema = z.object({
@@ -22937,6 +23304,21 @@ var LocateSegmentResultSchema = z.discriminatedUnion("kind", [z.object({
22937
23304
  })]);
22938
23305
  /** Raw bytes of one finalized footage segment (read off disk on the recording node). */
22939
23306
  var ReadSegmentBytesResultSchema = z.object({ data: z.instanceof(Uint8Array) });
23307
+ /**
23308
+ * One GOP of a finalized segment, cut by byte range through the segment's own
23309
+ * `mfra` (D31 on the D42 feeder path). `data` is the `ftyp`+`moov` head plus
23310
+ * the single `moof`+`mdat` covering the requested instant — standalone-
23311
+ * demuxable, never the whole file. When the segment's index cannot be parsed
23312
+ * the provider degrades INSIDE the mechanism to the whole segment (still one
23313
+ * `data`, `gopStartMs` = the segment start) — a worse read, not another path.
23314
+ */
23315
+ var ReadGopBytesResultSchema = z.object({
23316
+ data: z.instanceof(Uint8Array),
23317
+ /** Absolute epoch ms of the returned fragment's first sample. */
23318
+ gopStartMs: z.number(),
23319
+ /** Media ms the returned fragment covers. */
23320
+ gopDurMs: z.number()
23321
+ });
22940
23322
  var recordingCapability = {
22941
23323
  name: "recording",
22942
23324
  scope: "system",
@@ -23004,6 +23386,18 @@ var recordingCapability = {
23004
23386
  kind: "query",
23005
23387
  auth: "admin"
23006
23388
  }),
23389
+ /** Read the single GOP of segment `startMs` covering `epochMs`, by mfra
23390
+ * byte range — the scrub-granular read (D31 letter on the feeder path).
23391
+ * See {@link ReadGopBytesResultSchema} for the degradation contract. */
23392
+ readGopBytes: method(z.object({
23393
+ deviceId: z.number(),
23394
+ profile: z.string(),
23395
+ startMs: z.number(),
23396
+ epochMs: z.number()
23397
+ }), ReadGopBytesResultSchema, {
23398
+ kind: "query",
23399
+ auth: "admin"
23400
+ }),
23007
23401
  setDeviceConfig: method(z.object({
23008
23402
  deviceId: z.number(),
23009
23403
  config: RecordingConfigSchema
@@ -23665,6 +24059,16 @@ var StreamProfileConfigSchema = z.object({
23665
24059
  "baseline"
23666
24060
  ]).optional(),
23667
24061
  gop: z.number().optional(),
24062
+ /**
24063
+ * Whether THIS profile currently carries an audio track. READ-ONLY here.
24064
+ *
24065
+ * There is no matching field on {@link StreamProfilePatchSchema}: the
24066
+ * camera's microphone is owned by `privacy-mask` (`setAudioEnabled`), which
24067
+ * writes every profile at once so "audio off" means silent everywhere. A
24068
+ * per-profile writer beside it would let a camera be half-muted and would be
24069
+ * a second knob onto one device register — the failure D62 exists to
24070
+ * prevent. Absent when the firmware does not report the flag.
24071
+ */
23668
24072
  audio: z.boolean().optional()
23669
24073
  });
23670
24074
  var StreamParamsStatusSchema = z.object({
@@ -23705,7 +24109,13 @@ var StreamParamsOptionsSchema = z.object({
23705
24109
  ext: StreamProfileOptionsSchema.optional()
23706
24110
  });
23707
24111
  /** A partial change to one profile — every field optional; a provider
23708
- * ignores fields it doesn't support. */
24112
+ * ignores fields it doesn't support.
24113
+ *
24114
+ * There is deliberately NO `audio` here. It existed until 2026-08-07,
24115
+ * reachable from no form and honoured by exactly one provider, while the
24116
+ * camera's microphone is a whole-device fact. It now has one writer,
24117
+ * `privacyMask.setAudioEnabled`, which writes every profile — see
24118
+ * `privacy-mask.cap.ts`. */
23709
24119
  var StreamProfilePatchSchema = z.object({
23710
24120
  width: z.number().optional(),
23711
24121
  height: z.number().optional(),
@@ -23718,8 +24128,7 @@ var StreamProfilePatchSchema = z.object({
23718
24128
  "main",
23719
24129
  "baseline"
23720
24130
  ]).optional(),
23721
- gop: z.number().optional(),
23722
- audio: z.boolean().optional()
24131
+ gop: z.number().optional()
23723
24132
  });
23724
24133
  var streamParamsCapability = {
23725
24134
  name: "stream-params",
@@ -26638,10 +27047,7 @@ var BATTERY_DEVICE_PROFILE = {
26638
27047
  audioMode: "disabled",
26639
27048
  detectionMode: "on-motion"
26640
27049
  },
26641
- settings: {
26642
- "snapshot.minRefreshIntervalSec": 3600,
26643
- "streamBroker.preBufferEnabled": false
26644
- }
27050
+ settings: {}
26645
27051
  };
26646
27052
  /**
26647
27053
  * Profile registry — order matters when multiple profiles match the
@@ -27493,7 +27899,7 @@ var SystemMirror = class {
27493
27899
  }
27494
27900
  async refreshDeviceMetadata(deviceId, kind) {
27495
27901
  try {
27496
- const info = (await this.api.deviceManager.listAll.query({})).find((d) => d.id === deviceId);
27902
+ const info = await this.api.deviceManager.getDevice.query({ deviceId });
27497
27903
  if (!info) return;
27498
27904
  const wasNew = !this.devices.has(deviceId);
27499
27905
  this.devices.set(deviceId, info);
@@ -27805,6 +28211,7 @@ var CAPABILITY_NAMES = {
27805
28211
  numericSensor: "numeric-sensor",
27806
28212
  oauthIntegration: "oauth-integration",
27807
28213
  osd: "osd",
28214
+ osdManager: "osd-manager",
27808
28215
  petFeeder: "pet-feeder",
27809
28216
  pipelineAnalytics: "pipeline-analytics",
27810
28217
  pipelineExecutor: "pipeline-executor",
@@ -28236,6 +28643,10 @@ var CAPABILITY_ROUTER_KEYS = [
28236
28643
  key: "osd",
28237
28644
  name: "osd"
28238
28645
  },
28646
+ {
28647
+ key: "osdManager",
28648
+ name: "osd-manager"
28649
+ },
28239
28650
  {
28240
28651
  key: "petFeeder",
28241
28652
  name: "pet-feeder"
@@ -28549,6 +28960,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
28549
28960
  numericSensorCapability,
28550
28961
  oauthIntegrationCapability,
28551
28962
  osdCapability,
28963
+ osdManagerCapability,
28552
28964
  petFeederCapability,
28553
28965
  pipelineAnalyticsCapability,
28554
28966
  pipelineExecutorCapability,
@@ -31467,6 +31879,48 @@ var METHOD_ACCESS_MAP = Object.freeze({
31467
31879
  addonId: null,
31468
31880
  access: "create"
31469
31881
  },
31882
+ "osdManager.clearSlotBinding": {
31883
+ capName: "osd-manager",
31884
+ capScope: "system",
31885
+ addonId: null,
31886
+ access: "delete"
31887
+ },
31888
+ "osdManager.getConditionSupport": {
31889
+ capName: "osd-manager",
31890
+ capScope: "system",
31891
+ addonId: null,
31892
+ access: "view"
31893
+ },
31894
+ "osdManager.getDeviceOsd": {
31895
+ capName: "osd-manager",
31896
+ capScope: "system",
31897
+ addonId: null,
31898
+ access: "view"
31899
+ },
31900
+ "osdManager.getSourceCatalog": {
31901
+ capName: "osd-manager",
31902
+ capScope: "system",
31903
+ addonId: null,
31904
+ access: "view"
31905
+ },
31906
+ "osdManager.previewSlot": {
31907
+ capName: "osd-manager",
31908
+ capScope: "system",
31909
+ addonId: null,
31910
+ access: "create"
31911
+ },
31912
+ "osdManager.renderDevice": {
31913
+ capName: "osd-manager",
31914
+ capScope: "system",
31915
+ addonId: null,
31916
+ access: "create"
31917
+ },
31918
+ "osdManager.setSlotBinding": {
31919
+ capName: "osd-manager",
31920
+ capScope: "system",
31921
+ addonId: null,
31922
+ access: "create"
31923
+ },
31470
31924
  "petFeeder.callPet": {
31471
31925
  capName: "pet-feeder",
31472
31926
  capScope: "device",
@@ -31629,6 +32083,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
31629
32083
  addonId: null,
31630
32084
  access: "view"
31631
32085
  },
32086
+ "pipelineAnalytics.getTrainingExportSummary": {
32087
+ capName: "pipeline-analytics",
32088
+ capScope: "device",
32089
+ addonId: null,
32090
+ access: "view"
32091
+ },
32092
+ "pipelineAnalytics.getTrainingExportUrl": {
32093
+ capName: "pipeline-analytics",
32094
+ capScope: "device",
32095
+ addonId: null,
32096
+ access: "view"
32097
+ },
31632
32098
  "pipelineAnalytics.listEventKinds": {
31633
32099
  capName: "pipeline-analytics",
31634
32100
  capScope: "device",
@@ -32385,6 +32851,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
32385
32851
  addonId: null,
32386
32852
  access: "view"
32387
32853
  },
32854
+ "privacyMask.setAudioEnabled": {
32855
+ capName: "privacy-mask",
32856
+ capScope: "device",
32857
+ addonId: null,
32858
+ access: "create"
32859
+ },
32388
32860
  "privacyMask.setMask": {
32389
32861
  capName: "privacy-mask",
32390
32862
  capScope: "device",
@@ -32553,6 +33025,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
32553
33025
  addonId: null,
32554
33026
  access: "create"
32555
33027
  },
33028
+ "recording.readGopBytes": {
33029
+ capName: "recording",
33030
+ capScope: "system",
33031
+ addonId: null,
33032
+ access: "view"
33033
+ },
32556
33034
  "recording.readSegmentBytes": {
32557
33035
  capName: "recording",
32558
33036
  capScope: "system",
@@ -33093,6 +33571,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33093
33571
  addonId: null,
33094
33572
  access: "view"
33095
33573
  },
33574
+ "streamBroker.getDeviceAudioMute": {
33575
+ capName: "stream-broker",
33576
+ capScope: "system",
33577
+ addonId: null,
33578
+ access: "view"
33579
+ },
33096
33580
  "streamBroker.getPreBufferInfo": {
33097
33581
  capName: "stream-broker",
33098
33582
  capScope: "system",
@@ -33213,6 +33697,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
33213
33697
  addonId: null,
33214
33698
  access: "create"
33215
33699
  },
33700
+ "streamBroker.setDeviceAudioMute": {
33701
+ capName: "stream-broker",
33702
+ capScope: "system",
33703
+ addonId: null,
33704
+ access: "create"
33705
+ },
33216
33706
  "streamBroker.setPreBufferDuration": {
33217
33707
  capName: "stream-broker",
33218
33708
  capScope: "system",
@@ -33928,6 +34418,7 @@ var KNOWN_CAP_NAMES = [
33928
34418
  "notifier",
33929
34419
  "oauth-integration",
33930
34420
  "osd",
34421
+ "osd-manager",
33931
34422
  "pet-feeder",
33932
34423
  "pipeline-analytics",
33933
34424
  "pipeline-executor",
@@ -34075,6 +34566,7 @@ var SYSTEM_CAP_NAMES = [
34075
34566
  "notification-output",
34076
34567
  "notification-rules",
34077
34568
  "oauth-integration",
34569
+ "osd-manager",
34078
34570
  "pipeline-executor",
34079
34571
  "pipeline-orchestrator",
34080
34572
  "pipeline-runner",
@@ -34533,6 +35025,7 @@ function createSystemProxy(api) {
34533
35025
  deleteTarget: (input) => dispatch("notificationOutput", "deleteTarget", "mutation", input),
34534
35026
  setTargetEnabled: (input) => dispatch("notificationOutput", "setTargetEnabled", "mutation", input)
34535
35027
  },
35028
+ osdManager: { getConditionSupport: (input) => dispatch("osdManager", "getConditionSupport", "query", input) },
34536
35029
  pipelineExecutor: {
34537
35030
  getAvailableEngines: (input) => dispatch("pipelineExecutor", "getAvailableEngines", "query", input),
34538
35031
  getSelectedEngine: (input) => dispatch("pipelineExecutor", "getSelectedEngine", "query", input),
@@ -35074,6 +35567,68 @@ function prepareNotification(caps, n) {
35074
35567
  };
35075
35568
  }
35076
35569
  //#endregion
35570
+ //#region src/notification/schedule.ts
35571
+ var WEEKDAY_TO_DAY = {
35572
+ Sun: 0,
35573
+ Mon: 1,
35574
+ Tue: 2,
35575
+ Wed: 3,
35576
+ Thu: 4,
35577
+ Fri: 5,
35578
+ Sat: 6
35579
+ };
35580
+ /** Resolve (weekday, minute-of-day) of `atMs` in the schedule's timezone.
35581
+ * An invalid/unknown IANA name falls back to the host timezone. */
35582
+ function localDayMinute(atMs, timezone) {
35583
+ const d = new Date(atMs);
35584
+ if (timezone !== void 0) try {
35585
+ const parts = new Intl.DateTimeFormat("en-US", {
35586
+ timeZone: timezone,
35587
+ weekday: "short",
35588
+ hour: "numeric",
35589
+ minute: "numeric",
35590
+ hourCycle: "h23"
35591
+ }).formatToParts(d);
35592
+ let weekday;
35593
+ let hour;
35594
+ let minute;
35595
+ for (const p of parts) if (p.type === "weekday") weekday = p.value;
35596
+ else if (p.type === "hour") hour = Number(p.value);
35597
+ else if (p.type === "minute") minute = Number(p.value);
35598
+ const day = weekday !== void 0 ? WEEKDAY_TO_DAY[weekday] : void 0;
35599
+ if (day !== void 0 && hour !== void 0 && minute !== void 0) return {
35600
+ day,
35601
+ minute: hour * 60 + minute
35602
+ };
35603
+ } catch {}
35604
+ return {
35605
+ day: d.getDay(),
35606
+ minute: d.getHours() * 60 + d.getMinutes()
35607
+ };
35608
+ }
35609
+ /**
35610
+ * Is the schedule active at `atMs`? No schedule = always active. Windows
35611
+ * are OR'd; a window with `startMinute > endMinute` crosses midnight (it
35612
+ * starts on a listed day and spills into the next). `invert` flips the
35613
+ * result (active OUTSIDE the windows).
35614
+ */
35615
+ function isScheduleActive(schedule, atMs) {
35616
+ if (schedule === void 0) return true;
35617
+ const { day, minute } = localDayMinute(atMs, schedule.timezone);
35618
+ const prevDay = (day + 6) % 7;
35619
+ let inside = false;
35620
+ for (const w of schedule.windows) if (w.startMinute <= w.endMinute) {
35621
+ if (w.days.includes(day) && minute >= w.startMinute && minute < w.endMinute) {
35622
+ inside = true;
35623
+ break;
35624
+ }
35625
+ } else if (w.days.includes(day) && minute >= w.startMinute || w.days.includes(prevDay) && minute < w.endMinute) {
35626
+ inside = true;
35627
+ break;
35628
+ }
35629
+ return schedule.invert === true ? !inside : inside;
35630
+ }
35631
+ //#endregion
35077
35632
  //#region src/notification/timelapse-rule.ts
35078
35633
  /**
35079
35634
  * TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
@@ -35571,6 +36126,44 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
35571
36126
  return best;
35572
36127
  }
35573
36128
  //#endregion
36129
+ //#region src/utils/addon-id.ts
36130
+ /**
36131
+ * The addon id as the REGISTRY, the wire and the durable stores spell it.
36132
+ *
36133
+ * `AddonContext.id` does not agree with itself across the two context
36134
+ * factories:
36135
+ *
36136
+ * - a FORKED addon gets the bare manifest id
36137
+ * (`kernel/moleculer/addon-context-factory.ts` → `id: addonId`);
36138
+ * - an addon co-located in hub-main gets it PREFIXED
36139
+ * (`server/backend/src/core/addon/addon-registry.service.ts` →
36140
+ * ``id: `addon:${addonId}` ``).
36141
+ *
36142
+ * Everything an addon might compare `ctx.id` AGAINST carries the bare form:
36143
+ * `DeviceBindingEntry.providerAddonId`, the `device-manager` bindings store's
36144
+ * `wrapperAddonId`, `CapabilityRegistry` provider keys, manifest ids.
36145
+ *
36146
+ * So `entry.providerAddonId === this.ctx.id` is silently, permanently false
36147
+ * for a builtin — and only for a builtin, which is why it survives a green
36148
+ * suite whose fake supplies the bare id. That is exactly how camera 615's
36149
+ * virtual doorbell latched `unbound` for twelve hours on 2026-08-07 while its
36150
+ * binding was intact ([D72](../../../../docs/decisions/adr-0072.md)).
36151
+ *
36152
+ * Route every comparison between `ctx.id` and a registry/store addon id
36153
+ * through {@link isSameAddonId}. `scripts/check-addon-id-comparison.ts`
36154
+ * enforces it in the processes where the prefix exists.
36155
+ */
36156
+ /** The prefix the hub-main context factory prepends to the manifest id. */
36157
+ var ADDON_ID_PREFIX = "addon:";
36158
+ /** The manifest id, whichever spelling of `ctx.id` you were handed. */
36159
+ function bareAddonId(id) {
36160
+ return id.startsWith(ADDON_ID_PREFIX) ? id.slice(6) : id;
36161
+ }
36162
+ /** True when both ids name the same addon, prefixed or not. */
36163
+ function isSameAddonId(a, b) {
36164
+ return bareAddonId(a) === bareAddonId(b);
36165
+ }
36166
+ //#endregion
35574
36167
  //#region src/utils/cosine-similarity.ts
35575
36168
  /** Cosine similarity between two embedding vectors */
35576
36169
  function cosineSimilarity(a, b) {
@@ -36297,7 +36890,7 @@ function readDetailCropConvention(config) {
36297
36890
  square: square.success ? square.data : DEFAULT_DETAIL_CROP_CONVENTION.square
36298
36891
  };
36299
36892
  }
36300
- function isHydratedField(entry) {
36893
+ function isHydratedField$1(entry) {
36301
36894
  return typeof entry === "object" && entry !== null && "key" in entry;
36302
36895
  }
36303
36896
  /**
@@ -36312,7 +36905,7 @@ function pickDetailCropConvention(view) {
36312
36905
  if (view === null) return DEFAULT_DETAIL_CROP_CONVENTION;
36313
36906
  const flat = {};
36314
36907
  for (const section of view.sections) for (const entry of section.fields) {
36315
- if (!isHydratedField(entry) || typeof entry.key !== "string") continue;
36908
+ if (!isHydratedField$1(entry) || typeof entry.key !== "string") continue;
36316
36909
  if (entry.key === "detailCropPaddingRatio" || entry.key === "detailCropSquare") flat[entry.key] = entry.value;
36317
36910
  }
36318
36911
  return readDetailCropConvention(flat);
@@ -36399,6 +36992,245 @@ function slideInsideFrame(rect, frameWidth, frameHeight) {
36399
36992
  };
36400
36993
  }
36401
36994
  //#endregion
36995
+ //#region src/pipeline/native-lease.ts
36996
+ /**
36997
+ * THE native-frame **lease** knobs — TTL, RAM budget and demand window for the
36998
+ * decode worker's native-resolution frame retention.
36999
+ *
37000
+ * ## Why they live here and not in the addon that reads them
37001
+ *
37002
+ * The WRITER is `pipeline-orchestrator` (the cluster-wide settings authority);
37003
+ * the READER is a private child process of `addon-pipeline`'s pipeline-runner.
37004
+ * Addons never import each other, so a key owned by either side would have to
37005
+ * be hand-copied by the other — and a hand-copied key is how a setting silently
37006
+ * stops arriving while both sides still look correct. Same reasoning, same
37007
+ * placement as `detail-crop.ts` (D52's "one cluster-wide orchestrator setting").
37008
+ *
37009
+ * ## Why cluster-wide and not per-node
37010
+ *
37011
+ * The lease is a per-decode-worker RAM window. Its purpose — the late
37012
+ * cross-process native crop landing on a full-resolution frame rather than the
37013
+ * ≤640 detection fallback — is a property of the PIPELINE, not of a node's
37014
+ * hardware: a per-node TTL would mean the same camera produces different crop
37015
+ * quality depending on which node the balancer placed it on, and nobody could
37016
+ * tell that from the stored media. Node-level RAM pressure is already handled
37017
+ * by the per-session budget ceiling, which is itself one of these knobs.
37018
+ *
37019
+ * ## What each knob costs
37020
+ *
37021
+ * A retained frame is a full NATIVE-resolution copy in system RAM. With the
37022
+ * default pinned-RGB24 lease path (`CAMSTACK_SESSION_PINNED_RGB_CROP`, on):
37023
+ * 4K ≈ 24.9 MB/frame, 1080p ≈ 6.2 MB/frame. On the YUV420P path (flag off, and
37024
+ * for software-decoded sessions): 4K ≈ 12.4 MB, 1080p ≈ 3.1 MB. Worst-case
37025
+ * resident RAM for ONE busy camera ≈ frameBytes × deliveredFps × ttlSeconds,
37026
+ * clamped by the budget ceiling. See `docs/design/decode-path.md` → "Lease
37027
+ * admission" for what actually gets admitted.
37028
+ */
37029
+ /**
37030
+ * Store identity of the lease knobs in `pipeline-orchestrator`'s GLOBAL
37031
+ * (cluster-wide) settings. Keys are unique across that addon's whole schema, so
37032
+ * the reader can walk every section instead of trusting the section id.
37033
+ */
37034
+ var NATIVE_LEASE_SECTION_ID = "native-lease";
37035
+ var NATIVE_LEASE_TTL_KEY = "nativeLeaseTtlMs";
37036
+ var NATIVE_LEASE_BUDGET_KEY = "nativeLeaseBudgetMb";
37037
+ var NATIVE_LEASE_ACTIVITY_KEY = "nativeLeaseActivityMs";
37038
+ var NATIVE_LEASE_ADMISSION_KEY = "nativeLeaseAdmission";
37039
+ /**
37040
+ * WHICH delivered frames the decode worker retains a native copy of.
37041
+ *
37042
+ * - `all` — every frame the worker delivered to the runner. The shipped
37043
+ * behaviour, and the only correct one if something can ask for a crop of a
37044
+ * frame the runner never sent to inference.
37045
+ * - `inferred` — only the frames the runner ADMITTED to its detection queue.
37046
+ * A native-crop request always names a `frameId` that rode an inference
37047
+ * result, so that is the only set a request can name. How much it drops is
37048
+ * the two-plane governor's admit ratio and nothing else: measured at ~50% on
37049
+ * this cluster, not the ~80% the design sketch assumed, because the governor
37050
+ * was not throttling as hard as the sketch supposed. Read
37051
+ * `leaseAdmitted`/`leaseOffered` off the metrics line for the camera in front
37052
+ * of you rather than quoting a number from here. The newest delivered frame is
37053
+ * croppable regardless — it is still the worker's reserved slot, not a lease —
37054
+ * which covers the one-frame race between a mark and the supersede that
37055
+ * consumes it.
37056
+ */
37057
+ var NativeLeaseAdmissionSchema = z.enum(["all", "inferred"]);
37058
+ /**
37059
+ * Operator-tunable native-lease settings. Bounds are enforced HERE (not only in
37060
+ * the slider) because the value also travels to a forked child process, where a
37061
+ * junk number would silently become a 0-length or unbounded retention window.
37062
+ */
37063
+ var NativeLeaseSettingsSchema = z.object({
37064
+ /**
37065
+ * How long a retained native frame is served before it counts as a miss.
37066
+ *
37067
+ * Must cover the FULL late-crop horizon: detection inference + the
37068
+ * cross-process inference-result hop to hub post-analysis + tracking + the
37069
+ * tRPC crop round-trip back. Below ~500 ms the busiest cameras' subject crops
37070
+ * outrun it and fall back to the ≤640 detection frame; above ~3 s the resident
37071
+ * RAM per busy camera grows linearly with no measured hit-rate gain.
37072
+ */
37073
+ ttlMs: z.number().int().min(250).max(1e4),
37074
+ /**
37075
+ * Hard per-decode-worker RAM ceiling for retained native frames, in MB.
37076
+ *
37077
+ * Intended as a SAFETY ceiling with the TTL as the effective cap — but check
37078
+ * which one is actually binding before reasoning from that. At the shipped
37079
+ * 1024 MB and a 2 800 ms TTL, a 4K camera hits the CEILING first (~43 frames
37080
+ * at ~24 MB each) and the TTL never gets to expire anything; `leaseMb` /
37081
+ * `leaseFrames` on the metrics line say which. When the ceiling binds, a
37082
+ * change that admits fewer frames buys retention WINDOW at constant RAM
37083
+ * rather than giving RAM back — lower this knob if RAM is what you wanted.
37084
+ * `0` DISABLES the lease entirely and falls the worker back to the tiny
37085
+ * leak-prone GPU surface ring (~85% crop miss; that is what the lease exists
37086
+ * to replace).
37087
+ */
37088
+ budgetMb: z.number().int().min(0).max(4096),
37089
+ /**
37090
+ * Demand window: eager per-frame native retention runs only within this many
37091
+ * ms of the last native-crop request (or of the dial starting).
37092
+ *
37093
+ * `0` means ALWAYS ON — it disables the gate, it does not disable retention.
37094
+ * That is the legacy behaviour that saturated an N100 (24 native-4K downloads
37095
+ * per second on a camera with zero crop demand), so leave it non-zero unless
37096
+ * you are reproducing that.
37097
+ */
37098
+ activityMs: z.number().int().min(0).max(12e4),
37099
+ /**
37100
+ * Which delivered frames are retained at all — see
37101
+ * {@link NativeLeaseAdmissionSchema}. This is the only knob of the four that
37102
+ * changes WHAT is kept rather than for how long, so it is also the only one
37103
+ * that can turn a crop that used to hit into a miss. The worker counts every
37104
+ * crop request naming a frame it did NOT see marked
37105
+ * (`leaseUnmarkedCrops` on the session-decode metrics line): a non-zero value
37106
+ * there is the signal that some caller names frames outside the inference set
37107
+ * and that this must go back to `all`.
37108
+ */
37109
+ admission: NativeLeaseAdmissionSchema
37110
+ });
37111
+ /**
37112
+ * The values in force when the operator has set nothing — byte-for-byte the
37113
+ * constants the decode worker shipped with as env-var defaults, so making these
37114
+ * settings changed no behaviour on the day it landed.
37115
+ */
37116
+ var DEFAULT_NATIVE_LEASE_SETTINGS = {
37117
+ ttlMs: 1200,
37118
+ budgetMb: 1024,
37119
+ activityMs: 15e3,
37120
+ admission: "inferred"
37121
+ };
37122
+ /** Slider bounds for the operator-facing knobs (orchestrator settings UI). */
37123
+ var NATIVE_LEASE_TTL_FIELD = {
37124
+ min: 250,
37125
+ max: 1e4,
37126
+ step: 50,
37127
+ default: DEFAULT_NATIVE_LEASE_SETTINGS.ttlMs
37128
+ };
37129
+ var NATIVE_LEASE_BUDGET_FIELD = {
37130
+ min: 0,
37131
+ max: 4096,
37132
+ step: 64,
37133
+ default: DEFAULT_NATIVE_LEASE_SETTINGS.budgetMb
37134
+ };
37135
+ var NATIVE_LEASE_ACTIVITY_FIELD = {
37136
+ min: 0,
37137
+ max: 12e4,
37138
+ step: 1e3,
37139
+ default: DEFAULT_NATIVE_LEASE_SETTINGS.activityMs
37140
+ };
37141
+ /** Select options for the admission knob (orchestrator settings UI). */
37142
+ var NATIVE_LEASE_ADMISSION_FIELD = {
37143
+ options: [{
37144
+ value: "all",
37145
+ label: "Every delivered frame"
37146
+ }, {
37147
+ value: "inferred",
37148
+ label: "Only frames sent to inference"
37149
+ }],
37150
+ default: DEFAULT_NATIVE_LEASE_SETTINGS.admission
37151
+ };
37152
+ /**
37153
+ * Parse one knob, reporting `null` for absent, junk, out-of-bounds — AND for a
37154
+ * value equal to the shipped default.
37155
+ *
37156
+ * That last rule is not tidiness, it is the difference between the documented
37157
+ * precedence being true and being a lie. `addon-settings.getGlobalSettings`
37158
+ * returns a HYDRATED payload, and `hydrateField` fills an unstored field with
37159
+ * the schema's own `default` (verified live on the hub: a cluster that has never
37160
+ * opened the form still reports `nativeLeaseTtlMs = 1200`). A reader that took
37161
+ * that at face value would report all three knobs as "set" on every cluster on
37162
+ * the day this shipped, permanently retiring the `CAMSTACK_SESSION_NATIVE_LEASE_*`
37163
+ * emergency override that the precedence promises. There is no raw-store read on
37164
+ * this cap to distinguish the two, so the default value itself is treated as
37165
+ * "the operator has expressed no preference" — which is also what leaving a
37166
+ * slider untouched means.
37167
+ *
37168
+ * The cost is one honest edge: an operator who deliberately selects the default
37169
+ * value in order to overrule an env var does not get it. Clear the env var
37170
+ * instead; the worker's spawn line names the source, so this is visible rather
37171
+ * than mysterious.
37172
+ */
37173
+ function readKnob(knob, raw) {
37174
+ const parsed = NativeLeaseSettingsSchema.shape[knob].safeParse(raw);
37175
+ if (!parsed.success) return null;
37176
+ return parsed.data === DEFAULT_NATIVE_LEASE_SETTINGS[knob] ? null : parsed.data;
37177
+ }
37178
+ /** {@link readKnob} for the one non-numeric knob. Same default-means-unset rule. */
37179
+ function readAdmissionKnob(raw) {
37180
+ const parsed = NativeLeaseAdmissionSchema.safeParse(raw);
37181
+ if (!parsed.success) return null;
37182
+ return parsed.data === DEFAULT_NATIVE_LEASE_SETTINGS.admission ? null : parsed.data;
37183
+ }
37184
+ /**
37185
+ * Narrow a FLAT settings record to the knobs the operator set.
37186
+ *
37187
+ * Per-FIELD parse, deliberately: a junk TTL must not also discard a valid
37188
+ * budget. An absent, out-of-bounds or default-valued knob is OMITTED (not
37189
+ * clamped, not defaulted) so the caller can still fall through to the env
37190
+ * override — clamping here would turn a typo into a value nobody chose. See
37191
+ * {@link readKnob} for why the default counts as unset.
37192
+ */
37193
+ function readNativeLeaseOverride(config) {
37194
+ const ttlMs = readKnob("ttlMs", config[NATIVE_LEASE_TTL_KEY]);
37195
+ const budgetMb = readKnob("budgetMb", config[NATIVE_LEASE_BUDGET_KEY]);
37196
+ const activityMs = readKnob("activityMs", config[NATIVE_LEASE_ACTIVITY_KEY]);
37197
+ const admission = readAdmissionKnob(config[NATIVE_LEASE_ADMISSION_KEY]);
37198
+ return {
37199
+ ...ttlMs === null ? {} : { ttlMs },
37200
+ ...budgetMb === null ? {} : { budgetMb },
37201
+ ...activityMs === null ? {} : { activityMs },
37202
+ ...admission === null ? {} : { admission }
37203
+ };
37204
+ }
37205
+ function isHydratedField(entry) {
37206
+ return typeof entry === "object" && entry !== null && "key" in entry;
37207
+ }
37208
+ var LEASE_KEYS = [
37209
+ NATIVE_LEASE_TTL_KEY,
37210
+ NATIVE_LEASE_BUDGET_KEY,
37211
+ NATIVE_LEASE_ACTIVITY_KEY,
37212
+ NATIVE_LEASE_ADMISSION_KEY
37213
+ ];
37214
+ /**
37215
+ * Extract the operator's lease overrides from an
37216
+ * `addon-settings.getGlobalSettings` payload.
37217
+ *
37218
+ * Walks EVERY section rather than looking inside {@link NATIVE_LEASE_SECTION_ID}
37219
+ * alone: the keys are unique across the addon's schema, and a section rename
37220
+ * must not silently revert the whole cluster to the defaults. A `null` payload
37221
+ * (addon mid-boot) means "operator set nothing" — the env/default fallback then
37222
+ * applies, which is the correct read of "I could not ask".
37223
+ */
37224
+ function pickNativeLeaseOverride(view) {
37225
+ if (view === null) return {};
37226
+ const flat = {};
37227
+ for (const section of view.sections) for (const entry of section.fields) {
37228
+ if (!isHydratedField(entry) || typeof entry.key !== "string") continue;
37229
+ if (LEASE_KEYS.includes(entry.key)) flat[entry.key] = entry.value;
37230
+ }
37231
+ return readNativeLeaseOverride(flat);
37232
+ }
37233
+ //#endregion
36402
37234
  //#region src/helpers/bind-addon-actions.ts
36403
37235
  /**
36404
37236
  * Bind an addon's custom-action catalog to its tRPC surface, returning a
@@ -36650,4 +37482,4 @@ function enumerateInferenceDevices(hw) {
36650
37482
  return out;
36651
37483
  }
36652
37484
  //#endregion
36653
- export { ACCESSORY_LABEL, ALEXA_EGRESS_PROFILE, ALL_CAPABILITY_DEFINITIONS, APPLE_SA_TO_MACRO, AUDIO_ANALYSIS_CAP_NAME, AUDIO_BACKEND_CHOICES, AUDIO_MACRO_LABELS, AUDIO_PRESETS, AccessoriesStatusSchema, AccessoryKind, AddBrokerInputSchema, AddonAutoUpdateSchema, AddonListItemSchema, AddonPageDeclarationSchema, AddonPageInfoSchema, AdoptInputSchema as AdoptionAdoptInputSchema, AdoptResultSchema as AdoptionAdoptResultSchema, AdoptionFilterSchema, GetCandidateInputSchema as AdoptionGetCandidateInputSchema, ListCandidatesInputSchema as AdoptionListCandidatesInputSchema, ListCandidatesOutputSchema as AdoptionListCandidatesOutputSchema, ReleaseInputSchema as AdoptionReleaseInputSchema, AdoptionStatusSchema, AgentLoadSummarySchema, AirQualitySensorStatusSchema, AlarmArmModeSchema, AlarmPanelStatusSchema, AlarmStateSchema, AlertSchema, AlertSeveritySchema, AlertSourceSchema, AlertStatusSchema, AmbientLightSensorStatusSchema, ApiKeyRecordSchema, ApiKeySummarySchema, ArchiveEntrySchema, ArchiveManifestSchema, AttachmentMediaTypeSchema, AttachmentSchema, AudioAnalysisResultSchema, AudioAnalysisSettingsSchema, AudioChunkInputSchema, AudioClassSummarySchema, AudioClassificationLabelSchema, AudioClassificationResultSchema, AudioCodecInfoSchema, AudioDecodeSessionConfigSchema, AudioEncodeSchema, AudioEncodeSessionConfigSchema, AudioEncodedChunkSchema, AudioEventSchema, AudioLevelSchema, AudioMetricsHistoryPointSchema, AudioMetricsHistorySchema, AudioMetricsSnapshotSchema, AudioPcmChunkSchema, AuthResultSchema, AutoUpdateSettingsSchema, AutomationControlStatusSchema, AvailableIntegrationTypeSchema, BACKEND_TO_FORMAT, BASE_LIVE_EGRESS_PROFILE, BATTERY_DEVICE_PROFILE, BacklightModeSchema, BackupDestinationInfoSchema, BackupEntrySchema, BaseAddon, BaseDevice, BaseDeviceProvider, BatteryStatusSchema, BinaryStatusSchema, BoundingBoxSchema, BrightnessStatusSchema, AddInputSchema as BrokerAddInputSchema, BrokerAudioClientSchema, BrokerClientsSchema, BrokerConnectionDetailsSchema, BrokerConsumerAttributionSchema, BrokerConsumerKindSchema, BrokerDecodedClientSchema, BrokerEncodedClientSchema, GetStateInputSchema as BrokerGetStateInputSchema, BrokerInfoSchema, BrokerProviderInfoSchema, PublishInputSchema as BrokerPublishInputSchema, RegistryStatusSchema as BrokerRegistryStatusSchema, BrokerRtspClientSchema, BrokerStatsSchema, BrokerStatusEnum, BrokerStatusSchema, SubscribeInputSchema as BrokerSubscribeInputSchema, SubscribeResultSchema as BrokerSubscribeResultSchema, TestConnectionResultSchema as BrokerTestConnectionResultSchema, UnsubscribeInputSchema as BrokerUnsubscribeInputSchema, CAMERA_SWITCH_CATALOG, CAMERA_SWITCH_ORDER, CAM_PROFILE_ORDER, CAPABILITY_NAMES, CAPABILITY_ROUTER_KEYS, CAP_NAMES_WITH_STATUS, CAP_NODE_PIN_CONTEXT_KEY, CAP_PROVIDER_KIND_MAP, COCO_80_LABELS, COCO_TO_MACRO, CamProfileSchema, CamStreamDescriptorSchema, CamStreamKindSchema, CamStreamResolutionSchema, CameraAssignmentStatusSchema, CameraAudioStatusSchema, CameraBrokerProfileSchema, CameraBrokerStatusSchema, CameraCredentialsSchema, CameraCredentialsStatusSchema, CameraDecoderShmSchema, CameraDecoderStatusSchema, CameraDetectionPhaseSchema, CameraDetectionProvisioningSchema, CameraDetectionProvisioningStateSchema, CameraDetectionStatusSchema, CameraMetricsSchema, CameraMetricsWithDeviceIdSchema, CameraMotionStatusSchema, CameraRecordingModeSchema, CameraRecordingStatusSchema, CameraSourceStatusSchema, CameraSourceStreamSchema, CameraStatusSchema, CameraStreamSchema, CameraSwitchAuthoritySchema, CameraSwitchGroupSchema, CameraSwitchIdSchema, CameraSwitchSchema, CameraSwitchUnavailableReasonSchema, CandidateQueryFilterSchema, CapScopeSchema, CapabilityBindingsSchema, CarbonMonoxideStatusSchema, ChargingStatus, ClientNetworkStatsSchema, ClimateControlStatusSchema, ClipPlaybackSchema, ClipSchema, ClusterAddonNodeDeploymentSchema, ClusterAddonStatusEntrySchema, CollectionColumnSchema, CollectionIndexSchema, ColorStatusSchema, ConfigEntrySchema, ConfigSectionWithValuesSchema, ConfigTabDeclarationSchema, ConnectivityStatusSchema, ConsumableItemSchema, ConsumablesStatusSchema, ContactStatusSchema, ControlKindSchema, ControlStatusSchema, ConvertArtifactSchema, ConvertResultSchema, ConvertTargetSchema, CoreBlockCompileResultSchema, CoreBlockInputSchema, CoreBlockPlacementSchema, CoreBlockSchema, CoreBlockStatusSchema, CoverStateSchema, CoverStatusSchema, CreateApiKeyInputSchema, CreateApiKeyResultSchema, CreateIntegrationInputSchema, CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, CreateUserInputSchema, CustomActionInputSchema, CustomModelDescriptorSchema, DATAPLANE_SECRET_HEADER, DEFAULT_ADDON_PLACEMENT, DEFAULT_AUDIO_ANALYZER_CONFIG, DEFAULT_DECODER_HWACCEL_CONFIG, DEFAULT_DETAIL_CROP_CONVENTION, DEFAULT_EVENT_COLOR, DEFAULT_FEATURES, DEFAULT_RETENTION, DEFAULT_SCRUB_THUMBNAIL_PRESET, DETAIL_CROP_PADDING_FIELD, DETAIL_CROP_PADDING_KEY, DETAIL_CROP_SECTION_ID, DETAIL_CROP_SQUARE_KEY, DETECTION_PIPELINE_CAP_NAME, DEVICE_BACKEND_TO_FORMAT, DEVICE_CAP_NAMES, DEVICE_PROFILES, DEVICE_SCOPED_CAPS, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATE_READERS, DEVICE_STATUS_METHOD, DEVICE_TYPE_CONTROL_KIND, DEVICE_TYPE_INFO, EngineInfoSchema as DataStoreEngineInfoSchema, DayNightModeSchema, DayNightOptionsSchema, DayNightSettingsPatchSchema, DayNightStatusSchema, DecodedAudioChunkSchema, DecodedFrameSchema, DecoderSessionConfigSchema, DecoderStatsSchema, DeleteIntegrationResultSchema, DetailCropConventionSchema, DetectionSourceSchema, DeviceCodeSeveritySchema, DeviceConfig, DeviceDiscoveryStatusSchema, ExposeInputSchema as DeviceExportExposeInputSchema, DeviceExportStatusSchema, UnexposeInputSchema as DeviceExportUnexposeInputSchema, DeviceFeature, DeviceInfoSchema, DeviceLinkModeSchema, DeviceNetworkStatsSchema, DeviceRole, DeviceRuntimeState, DeviceStatusSchema, DeviceType, DiscoveredChildDeviceSchema, DiscoveredChildStatusSchema, DiscoveredDeviceSchema, DiscoveredTargetSchema, DisposerChain, DoorbellPressEventSchema, DoorbellStatusSchema, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_PAD_MS, EVENT_TAXONOMY, EXPRESSION_BUILTINS, EXPRESSION_BUILTIN_NAMES, EXPRESSION_COMPILE_CACHE_CAPACITY, EXPRESSION_IDENTIFIER_RE, EXPRESSION_INJECTED_NOW, ElementConfigStore, EmbeddingInfoSchema, EmbeddingResultSchema, EncodeProfileSchema, EncodedPacketSchema, EnrichedWidgetMetadataSchema, EnumSensorDateTimeFormatSchema, EnumSensorStatusSchema, EventCategory, EventEmitterStatusSchema, EventFireSchema, EventItemSchema, EventKindCategorySchema, EventKindDescriptorSchema, EventKindIconSchema, EventKindSchema, EventKindsForDeviceSchema, EventSourceType, ExportDownloadSchema, ExportOptionsSchema, ExportRecordSchema, ExportSetupFieldSchema, ExportSetupSchema, ExportSpeedSchema, ExportStateSchema, ExportTimelapseSchema, ExposedDeviceSchema, ExposureModeSchema, ExpressionEvalError, ExpressionParseError, FanControlStatusSchema, FanDirectionSchema, FeatureManifestSchema, FeatureProbeStatusSchema, FloodStatusSchema, FrameHandleFormatSchema, FrameHandleSchema, FrameInputSchema, GasStatusSchema, GetStreamWithCodecInputSchema, GlobalMetricsSchema, HAP_AUDIO_BASE, HAP_AUDIO_BITRATE_KBPS, HAP_AUDIO_VBV_KBITS, HAP_KEYFRAME_INTERVAL_SEC, HF_BASE_URL, HF_REPO, HWACCEL_OPTIONS, HealthStatusSchema, HistoryPointSchema, HistoryResolutionEnum, HumidifierStatusSchema, HumiditySensorStatusSchema, HvacModeSchema, ImageContractSchema, ImageContractStateSchema, ImageRotateSchema, ImageSettingsOptionsSchema, ImageSettingsPatchSchema, ImageSettingsStatusSchema, ImageStatusSchema, IngestOwnerSchema, InstalledPackageSchema, IntegrationLiteSchema, IntegrationWithStateSchema, IntercomAbilitySchema, IntercomStatusSchema, KNOWN_CAP_NAMES, KeyEventSchema, LOG_LEVEL_RANK, LabelDefinitionSchema, LawnMowerActivitySchema, LawnMowerControlStatusSchema, LinkedDeviceSchema, LlmDefaultSchema, LlmDefaultSelectorSchema, LlmErrorCodeSchema, LlmGenerateBaseInputSchema, LlmGenerateErrSchema, LlmGenerateOkSchema, LlmGenerateResultSchema, LlmImageSchema, LlmNodeModelSchema, LlmProfileKindDescriptorSchema, LlmProfileKindSchema, LlmProfileSchema, LlmRuntimeCompleteInputSchema, LlmRuntimeDiskUsageSchema, LlmRuntimeNodeSchema, LlmRuntimeStatusSchema, LlmUsageRollupSchema, LlmUsageSchema, LocateSegmentResultSchema, LocationStatSchema, LockControlStatusSchema, LockStateSchema, LogEntrySchema, LogLevelSchema, LogStreamEntrySchema, LoginMethodContributionSchema, LoginStageEnum, MACRO_LABELS, MAX_EXPRESSION_AST_NODES, MAX_EXPRESSION_BINDINGS, MAX_EXPRESSION_CALL_ARGS, MAX_EXPRESSION_EVAL_STEPS, MAX_EXPRESSION_SOURCE_LENGTH, METHOD_ACCESS_MAP, MODEL_FORMATS, MOTION_TRIGGER_FEATURE, ManagedModelCatalogEntrySchema, ManagedModelRefSchema, ManagedRuntimeConfigSchema, MaskGridDimsSchema, MaskGridShapeSchema, MaskLineShapeSchema, MaskPointSchema, MaskPolygonShapeSchema, MaskPolygonVerticesSchema, MaskRectShapeSchema, MaskShapeKindSchema, MaskShapeSchema, MediaFileInfoSchema, MediaFileSchema, MediaPlayerRepeatSchema, MediaPlayerStateSchema, MediaPlayerStatusSchema, MeshPeerSchema, MeshStatusSchema, MethodAccessSchema, ModelCatalogEntrySchema, ModelConvertInputSchema, ModelConvertMetadataSchema, ModelDistributeInputSchema, ModelDistributeResultSchema, ModelExtraFileSchema, ModelFormatEntrySchema, ModelFormatsSchema, ModelSubstitutionSchema, ModelVariantGroupSchema, MotionAnalysisResultSchema, MotionEventSchema, MotionOnMotionChangedDataSchema, MotionRegionSchema, MotionSourceEnum, MotionSourcesSchema, MotionStatusSchema, MotionTriggerRuntimeStateSchema, MotionTriggerStatusSchema, MotionZoneOptionsSchema, MotionZonePatchSchema, MotionZoneRegionSchema, MotionZoneStatusSchema, StatusSchema as MqttBrokerStatusSchema, MutationFilterSchema, NC_BASE_CONDITION_KEYS, NC_CONDITION_CATALOG, NC_HISTORY_LIMIT_DEFAULT, NC_HISTORY_LIMIT_MAX, NC_MAX_PER_TRACK_IMMEDIATE, NC_SNOOZE_MAX_MINUTES, NC_TAXONOMY, NativeCropBboxSchema, NativeCropRefSchema, NativeCropResultSchema, NativeDetectionSchema, NativeObjectClassEnum, NativeObjectDetectionRuntimeStateSchema, NativeObjectDetectionStatusSchema, NcAlarmConfigSchema, NcAlarmModeCoverageSchema, NcAlarmSettingsPatchSchema, NcAlarmSettingsSchema, NcConditionDescriptorSchema, NcConditionsSchema, NcCrossingSchema, NcDeliverySchema, NcDeviceStateConditionSchema, NcHistoryEntrySchema, NcHistoryFilterSchema, NcHistoryRecordKindSchema, NcHistoryStatusSchema, NcHistorySubjectSchema, NcMediaFrameSchema, NcMediaPolicySchema, NcOccupancyConditionSchema, NcPlateMatcherSchema, NcRuleActionSchema, NcRuleActionSequenceSchema, NcRuleActionsSchema, NcRuleInputSchema, NcRuleNotificationButtonSchema, NcRulePatchSchema, NcRuleSchema, NcRuleTargetSchema, NcScheduleSchema, NcScheduleWindowSchema, NcSnoozeInputSchema, NcSnoozeSchema, NcSnoozeScopeSchema, NcSnoozeSuppressedSchema, NcTaxonomyEntrySchema, NcTaxonomySchema, NcTestResultSchema, NcThrottleGranularitySchema, NcThrottleSchema, NcZoneConditionSchema, NetworkAccessStatusSchema, NetworkAddressSchema, NetworkEndpointSchema, NotificationActionIconSchema, NotificationActionSchema, NotificationFormatSchema, NotificationSchema, NotifierStatusSchema, NumericSensorStatusSchema, OPS_LOG_DEFAULT_LIMIT, OPS_LOG_RING_DEFAULT_MAX, OauthIntegrationDescriptorSchema, ObjectEventSchema, OpsLogDomainSchema, OpsLogEntrySchema, OpsLogOpSchema, OpsLogQueryInputSchema, OpsLogReasonSchema, OrchestratorMetricsSchema, OsdOverlayKindEnum, OsdOverlayPatchSchema, OsdOverlaySchema, OsdPositionEnum, OsdStatusSchema, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, PIPELINE_FLOW_CAPABILITY_NAMES, PIPELINE_OWNER_CAPABILITY_NAMES, PROVIDER_KIND_CAP_NAMES, PYTHON_SCRIPT, PackageUpdateSchema, PackageVersionInfoSchema, PasskeyLoginMethodSchema, PasskeySummarySchema, PcmSampleFormatSchema, PerScopeBreakdownSchema, PetFeederStatusSchema, PickStreamPreferencesSchema, PickStreamRequirementsSchema, PickedCamStreamSchema, PipelineAssignmentSchema, PipelineDefaultStepSchema, PipelineEngineChoiceSchema, PipelineRunResultBridge, PipelineStepInputSchema, PipelineValidationIssueSchema, PipelineValidationResultSchema, PlaceholderReasonSchema, PolygonPointSchema, PowerMeterStatusSchema, PresenceStatusSchema, PressureSensorStatusSchema, PrivacyMaskOptionsSchema, PrivacyMaskPatchSchema, PrivacyMaskRegionSchema, PrivacyMaskShapeSchema, PrivacyMaskStatusSchema, ProfileRtspEntrySchema, ProfileSlotSchema, ProfileSlotStatusSchema, ProviderStatusSchema, PtzAutotrackRuntimeStateSchema, PtzAutotrackSettingsSchema, PtzAutotrackStatusSchema, PtzAutotrackTargetOptionSchema, PtzMoveCommandSchema, PtzOptionsSchema, PtzPositionSchema, PtzPresetSchema, PtzStatusSchema, QueryFilterSchema, RATE_CONTROL_RELAXED, RATE_CONTROL_TIGHT, REACHABILITY_FAILURES_TO_OFFLINE, REACHABILITY_POLL_INTERVAL_MS, REACHABILITY_PROBE_TIMEOUT_MS, RECOGNITION_TYPES, RESERVED_BINDING_NAMES, RUNTIME_DEFAULTS, RUNTIME_TO_FORMAT, RawStateResultSchema, ReadSegmentBytesResultSchema, ReadinessRegistry, ReadinessTimeoutError, RecentTracksPageSchema, RecentTracksQueryInput, RecordingAvailabilitySchema, RecordingBandModeSchema, RecordingBandSchema, RecordingBandTriggersSchema, RecordingConfigSchema, RecordingDaysSchema, RecordingDeviceUsageSchema, RecordingLocationUsageSchema, RecordingManifestSchema, RecordingRangeSchema, RecordingRetentionSchema, RecordingStatusSchema, RecordingStorageModeSchema, RecordingStorageUsageSchema, RecordingTriggersSchema, RecordingWeekdaySchema, RedirectLoginMethodSchema, RelocateFootageInputSchema, RelocateJobSchema, RelocateJobStateSchema, RelocateMediaInputSchema, RenderedAsSchema, ReportMotionInputSchema, RingBuffer, RtpSourceSchema, RtspRestreamEntrySchema, RunnerCameraConfigSchema, RunnerCameraDeviceUIFields, RunnerFrameSourceSchema, RunnerInferenceDeviceSchema, RunnerLocalLoadSchema, RunnerLocalMetricsSchema, SCOPE_PRESETS, SCRUB_THUMBNAIL_PRESETS, SCRUB_THUMBNAIL_PRESET_LABELS, SCRUB_THUMBNAIL_PRESET_ORDER, SENSOR_FEATURES, SENSOR_MAP, SOURCE_INFO_METADATA_KEY, STREAM_PROFILE_META, STREAM_QUALITY_LABELS, SUB_DETECTION_TYPES, SYSTEM_CAP_NAMES, SceneCheckSchema, SceneConditionSchema, SceneMonitorSchema, SceneMonitorStateSchema, SceneMonitorStatusSchema, SceneReferenceSchema, ScopedTokenSchema, ScopedTokenSummarySchema, ScoredObjectEventSchema, ScriptRunnerStatusSchema, ScrubThumbnailPresetSchema, SearchResultSchema, SendEmailInputSchema, SendEmailResultSchema, SendResultSchema, SensorEventSchema, ServerBootModeSchema, ServerPackageStatusSchema, ServerRollbackInfoSchema, ServerUpdateActionResultSchema, ServerUpdateCheckResultSchema, ServerUpdateStateSchema, SettingsPatchSchema, SettingsRecordSchema, SettingsSchemaWithValuesSchema, SettingsUpdateResultSchema, ShmRingStatsSchema, SmokeStatusSchema, SmtpStatusSchema, SnapshotImageSchema, SourceInfoSchema, SpatialDetectionSchema, SsoBridgeClaimsSchema, StartEmbeddedInputSchema, StationaryObjectSchema, AbortUploadInputSchema as StorageAbortUploadInputSchema, BeginDownloadInputSchema as StorageBeginDownloadInputSchema, BeginDownloadResultSchema as StorageBeginDownloadResultSchema, BeginUploadInputSchema as StorageBeginUploadInputSchema, BeginUploadResultSchema as StorageBeginUploadResultSchema, EndDownloadInputSchema as StorageEndDownloadInputSchema, FinalizeUploadInputSchema as StorageFinalizeUploadInputSchema, StorageLocationDeclarationSchema, StorageLocationRefSchema, StorageLocationSchema, StorageLocationTypeSchema, ProviderInfoSchema as StorageProviderInfoSchema, ReadChunkInputSchema as StorageReadChunkInputSchema, TestLocationResultSchema as StorageTestLocationResultSchema, WriteChunkInputSchema as StorageWriteChunkInputSchema, StreamCodecSchema, StreamFormatSchema, StreamNetworkStatsSchema, StreamParamsOptionsSchema, StreamParamsStatusSchema, StreamProfileConfigSchema, StreamProfileOptionsSchema, StreamProfilePatchSchema, StreamProfileSchema, StreamSourceEntrySchema, StreamSourceSchema, SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, SubscribeFramesInputSchema, SubscribeFramesResultSchema, SwitchStatusSchema, SystemMetricsSchema, SystemMirror, TAXONOMY_COLORS, TIMEZONES, TRANSCODE_DOWN_MAX_BITRATE_KBPS, TRANSCODE_DOWN_MAX_HEIGHT, TamperStatusSchema, TankStatusSchema, TargetKindCapsSchema, TargetKindLevelSchema, TargetKindSchema, TargetSchema, TemperatureSensorStatusSchema, TerminalProfileInfoSchema, TerminalSessionInfoSchema, TestConnectionResultSchema$1 as TestConnectionResultSchema, TestResultSchema, TimelapseRuleInputSchema, TimelapseRulePatchSchema, TimelapseRuleSchema, TimelapseTemplateSchema, ToastSchema, TokenScopeSchema, TopologyNodeSchema, TopologyProcessSchema, TopologyServiceSchema, TrackCascadeCountsSchema, TrackEnvelopeSchema, TrackFlagsPatchSchema, TrackFlagsSchema, TrackProjectionSchema, TrackSchema, TrackSourceSchema, TrackStateSchema, TrackZoneFilterSchema, TrackedDetectionSchema, TurnServerSchema, UNIT_TABLE, BrokerInfoSchema$1 as UnifiedBrokerInfoSchema, UnitConversionError, UpdateIntegrationInputSchema, UpdateStatusSchema, UpdateUserInputSchema, UserRecordSchema, UserSummarySchema, VacuumControlStatusSchema, VacuumStateSchema, ValveStateSchema, ValveStatusSchema, VectorDeclareIndexInputSchema, VectorDeleteByFilterInputSchema, VectorDeleteInputSchema, VectorDeleteResultSchema, VectorFilterSchema, VectorGetInputSchema, VectorGetResultSchema, VectorItemSchema, VectorMatchSchema, VectorMetadataSchema, VectorMetricSchema, VectorQueryInputSchema, VectorQueryResultSchema, VectorStatsInputSchema, VectorStatsResultSchema, VectorUpsertInputSchema, VectorUpsertResultSchema, VibrationStatusSchema, VideoEncodeSchema, WEBRTC_EGRESS_PROFILE, WELL_KNOWN_TABS, WELL_KNOWN_TAB_MAP, WaterHeaterStatusSchema, WeatherStatusSchema, WebrtcStreamChoiceSchema, WebrtcStreamTargetSchema, WhiteBalanceModeSchema, WidgetHostEnum, WidgetLoginMethodSchema, WidgetMetadataSchema, WidgetRemoteSchema, WidgetSizeEnum, YAMNET_TO_MACRO, ZoneCrossingDirectionSchema, ZoneCrossingSchema, ZoneKindEnum, ZoneRuleModeEnum, ZoneRuleSchema, ZoneRuleStageEnum, ZoneRulesArraySchema, ZoneSchema, ZoneScopeBreakdownSchema, accessoriesCapability, accessoryStableId, addonPagesCapability, addonPagesSourceCapability, addonRoutesCapability, addonSettingsCapability, addonWidgetsCapability, addonWidgetsSourceCapability, addonsCapability, adminUiCapability, airQualitySensorCapability, alarmPanelCapability, alertsCapability, ambientLightSensorCapability, applyTransform, asBoolean, asJsonArray, asJsonObject, asNumber, asString, audioAnalysisCapability, audioAnalyzerCapability, audioCodecCapability, audioMetricsCapability, audioPlanFromEncodeProfile, authProviderCapability, autoAssignProfiles, automationControlCapability, backupCapability, batteryCapability, bestLocationMatch, binaryCapability, bindAddonActions, brightnessCapability, brokerCapability, buildAddonRouteProvider, buildAudioArgs, buildEventKindDescriptor, buildFfmpegArgs, buildInputArgs, buildModelVariantGroups, buildNcTaxonomy, buildStreamParamsConfigSchema, buildVideoArgs, buttonCapability, cameraCredentialsCapability, cameraPipelineConfigCapability, cameraStreamsCapability, canConvertUnit, canonicalEgressPlan, carbonMonoxideCapability, cellsToRects, classifyStream, classifyStreams, climateControlCapability, collectHydratedFieldEntries, collectHydratedFieldValues, colorCapability, colorForKind, compileExpression, compileExpressionSafe, connectivityCapability, consumablesCapability, contactCapability, controlCapability, convertUnit, coreBlocksCapability, cosineSimilarity, coverCapability, createDeviceProxy, createDurableState, createEvent, createExpressionScope, createHwAccelCache, createLazyTrpcSource, createMirrorSource, createRuntimeStateBridge, createSliceHandle, createSystemProxy, customAction, customModelRegistryCapability, dataStoreProviderCapability, dayNightCapability, decodeVectorBase64, decoderCapability, defaultDeviceFor, defineCustomActions, deriveCameraSwitches, deriveDetailCropRect, deriveRecordingMode, describeModelVariant, detectionPipelineCapability, deviceAdoptionCapability, deviceBackendToFormat, deviceCustomAction, deviceDiscoveryCapability, deviceExportCapability, deviceManagerCapability, deviceMatchesProfile, deviceOpsCapability, deviceProviderCapability, deviceStateCapability, deviceStatusCapability, doorbellCapability, egressTranscodeSharingKey, embeddingEncoderCapability, emitDownForOwnedCaps, emitReadiness, encodeProfileFromStreamShape, encodeVectorBase64, enumSensorCapability, enumerateInferenceDevices, enumerateItemArrayFields, enumerateSchemaFields, errMsg, evaluateAst, evaluateLinkExpression, evaluateZoneRules, event, eventEmitterCapability, eventsCapability, expandCapMethods, extractNestedAddonId, extractSourceInfoFromMetadata, faceGalleryCapability, fanControlCapability, featureProbeCapability, filesystemBrowseCapability, findTimezone, floodCapability, formatForBackend, formatForRuntime, gasCapability, getAudioMacroClassIds, getByPath, getCapsByProviderKind, getTaxonomyEntry, hasMotionTrigger, hfModelUrl, htmlToText, humidifierCapability, humiditySensorCapability, hydrateSchema, imageCapability, imageSettingsCapability, integrationsCapability, intercomCapability, invocationFromEncodeProfile, isAgentOnlyPlacement, isArrayOutputSchema, isBaseConditionKey, isCollectionArrayMethod, isDeployableToAgent, isDeviceConfigCap, isDeviceScopedCap, isEvent, isNode, isObjectInput, isSoftwareDecode, isVoidInput, jobKindSchema, kebabToCamel, knownValues, lawnMowerControlCapability, lifecycleJobSchema, lifecycleJobScopeSchema, lifecycleJobStateSchema, lifecycleTaskSchema, llmCapability, llmRuntimeCapability, localNetworkCapability, locationSimilarity, lockControlCapability, logBannerArgs, logDestinationCapability, logLevelAtMost, loginMethodCapability, looseSchema, makeProfileBrokerId, makeSourceBrokerId, mapAudioLabelToMacro, markdownToHtmlLite, markdownToText, maskUrlCredentials, mediaPlayerCapability, mergeSourceInfo, meshNetworkCapability, method, metricsProviderCapability, modelConvertCapability, modelDistributorCapability, modelFormatForRuntime, motionCapability, motionDetectionCapability, motionTriggerCapability, motionZonesCapability, mqttBrokerCapability, nativeObjectDetectionCapability, networkAccessCapability, networkQualityCapability, nodePin, nodesCapability, normalizeAddonInitResult, normalizeUnit, notificationOutputCapability, notificationRulesCapability, notifierCapability, numericSensorCapability, oauthIntegrationCapability, objectInputDeclaresAddonId, osdCapability, parseCameraStreamConfig, parseExpression, parseJsonArray, parseJsonObject, parseJsonUnknown, parseProfileBrokerId, parseStreamParamsFormPatch, petFeederCapability, pickAccessoryControl, pickDetailCropConvention, pickPreferredRtspEntry, pickVideoEncoder, pickerForCondition, pipelineAnalyticsCapability, pipelineExecutorCapability, pipelineOrchestratorCapability, pipelineRunnerCapability, plateGalleryCapability, platformProbeCapability, powerMeterCapability, prepareNotification, presenceCapability, pressureSensorCapability, privacyMaskCapability, procedureAuthKey, ptzAutotrackCapability, ptzCapability, pythonScriptForBackend, readDetailCropConvention, readDeviceStateFrom, readNodePin, readinessKey, rebootCapability, recordingCapability, recordingExportCapability, rectsToCells, requiresPython, resolveAddonExecution, resolveAddonGroup, resolveAddonPlacement, resolveAddonRuntime, resolveCapMount, resolveDetectionRuntime, resolveDeviceControlKind, resolveDeviceProfile, resolveEgressDecodeHwAccel, resolveFormat, resolveHydratedFieldValue, resolveModelFormat, resolveMutate, resolveRunnerId, resolveScrubThumbnailGeometry, resolveVariantModelId, runInferenceStep, runtimeDevices, sceneMonitorCapability, scopeKey, scoreRuntimes, scriptRunnerCapability, selectAssignedProfileSlots, serverManagementCapability, setByPath, settingsStoreCapability, sleep, sleepCancellable, smokeCapability, smtpProviderCapability, snapshotCapability, ssoBridgeCapability, startReachabilityPoll, stateVocabularyFor, storageCapability, storageEvictableCapability, storageProviderCapability, streamBrokerCapability, streamCatalogCapability, streamParamsCapability, streamPixels, streamQualityLabel, subKindsOf, supportedRuntimes, switchCapability, switchedOffIds, synthesizeSourceInfo, systemCapability, tamperCapability, taskLogEntrySchema, taskPhaseSchema, taskTargetSchema, temperatureSensorCapability, terminalSessionCapability, textToHtml, toDeviceSummary, toExpressionValue, toStreamSourceEntry, toastCapability, tokenize, transcodeBody, tryConvertUnit, turnProviderCapability, unitDimension, unitsForDimension, updateCapability, userManagementCapability, userPasskeysCapability, vacuumControlCapability, validateExpressionSource, valveCapability, vectorDimFromBase64, vectorStoreCapability, vibrationCapability, videoclipsCapability, viewerUiCapability, waterHeaterCapability, weatherCapability, webrtcClientHintsSchema, webrtcSessionCapability, wiringAddonHealthSchema, wiringHealthSnapshotSchema, wiringNodeHealthSchema, wiringProbeKindSchema, wiringProbeResultSchema, zodEntriesToConfigUI, zoneAnalyticsCapability, zoneRulesCapability, zonesCapability };
37485
+ export { ACCESSORY_LABEL, ALEXA_EGRESS_PROFILE, ALL_CAPABILITY_DEFINITIONS, APPLE_SA_TO_MACRO, AUDIO_ANALYSIS_CAP_NAME, AUDIO_BACKEND_CHOICES, AUDIO_MACRO_LABELS, AUDIO_PRESETS, AccessoriesStatusSchema, AccessoryKind, AddBrokerInputSchema, AddonAutoUpdateSchema, AddonListItemSchema, AddonPageDeclarationSchema, AddonPageInfoSchema, AdoptInputSchema as AdoptionAdoptInputSchema, AdoptResultSchema as AdoptionAdoptResultSchema, AdoptionFilterSchema, GetCandidateInputSchema as AdoptionGetCandidateInputSchema, ListCandidatesInputSchema as AdoptionListCandidatesInputSchema, ListCandidatesOutputSchema as AdoptionListCandidatesOutputSchema, ReleaseInputSchema as AdoptionReleaseInputSchema, AdoptionStatusSchema, AgentLoadSummarySchema, AirQualitySensorStatusSchema, AlarmArmModeSchema, AlarmPanelStatusSchema, AlarmStateSchema, AlertSchema, AlertSeveritySchema, AlertSourceSchema, AlertStatusSchema, AmbientLightSensorStatusSchema, ApiKeyRecordSchema, ApiKeySummarySchema, ArchiveEntrySchema, ArchiveManifestSchema, AttachmentMediaTypeSchema, AttachmentSchema, AudioAnalysisResultSchema, AudioAnalysisSettingsSchema, AudioChunkInputSchema, AudioClassSummarySchema, AudioClassificationLabelSchema, AudioClassificationResultSchema, AudioCodecInfoSchema, AudioDecodeSessionConfigSchema, AudioEncodeSchema, AudioEncodeSessionConfigSchema, AudioEncodedChunkSchema, AudioEventSchema, AudioLevelSchema, AudioMetricsHistoryPointSchema, AudioMetricsHistorySchema, AudioMetricsSnapshotSchema, AudioPcmChunkSchema, AuthResultSchema, AutoUpdateSettingsSchema, AutomationControlStatusSchema, AvailableIntegrationTypeSchema, BACKEND_TO_FORMAT, BASE_LIVE_EGRESS_PROFILE, BATTERY_DEVICE_PROFILE, BacklightModeSchema, BackupDestinationInfoSchema, BackupEntrySchema, BaseAddon, BaseDevice, BaseDeviceProvider, BatteryStatusSchema, BinaryStatusSchema, BoundingBoxSchema, BrightnessStatusSchema, AddInputSchema as BrokerAddInputSchema, BrokerAudioClientSchema, BrokerClientsSchema, BrokerConnectionDetailsSchema, BrokerConsumerAttributionSchema, BrokerConsumerKindSchema, BrokerDecodedClientSchema, BrokerEncodedClientSchema, GetStateInputSchema as BrokerGetStateInputSchema, BrokerInfoSchema, BrokerProviderInfoSchema, PublishInputSchema as BrokerPublishInputSchema, RegistryStatusSchema as BrokerRegistryStatusSchema, BrokerRtspClientSchema, BrokerStatsSchema, BrokerStatusEnum, BrokerStatusSchema, SubscribeInputSchema as BrokerSubscribeInputSchema, SubscribeResultSchema as BrokerSubscribeResultSchema, TestConnectionResultSchema as BrokerTestConnectionResultSchema, UnsubscribeInputSchema as BrokerUnsubscribeInputSchema, CAMERA_SWITCH_CATALOG, CAMERA_SWITCH_ORDER, CAM_PROFILE_ORDER, CAPABILITY_NAMES, CAPABILITY_ROUTER_KEYS, CAP_NAMES_WITH_STATUS, CAP_NODE_PIN_CONTEXT_KEY, CAP_PROVIDER_KIND_MAP, COCO_80_LABELS, COCO_TO_MACRO, CamProfileSchema, CamStreamDescriptorSchema, CamStreamKindSchema, CamStreamResolutionSchema, CameraAssignmentStatusSchema, CameraAudioStatusSchema, CameraBrokerProfileSchema, CameraBrokerStatusSchema, CameraCredentialsSchema, CameraCredentialsStatusSchema, CameraDecoderShmSchema, CameraDecoderStatusSchema, CameraDetectionPhaseSchema, CameraDetectionProvisioningSchema, CameraDetectionProvisioningStateSchema, CameraDetectionStatusSchema, CameraMetricsSchema, CameraMetricsWithDeviceIdSchema, CameraMotionStatusSchema, CameraRecordingModeSchema, CameraRecordingStatusSchema, CameraSourceStatusSchema, CameraSourceStreamSchema, CameraStatusSchema, CameraStreamSchema, CameraSwitchAuthoritySchema, CameraSwitchGroupSchema, CameraSwitchIdSchema, CameraSwitchSchema, CameraSwitchUnavailableReasonSchema, CandidateQueryFilterSchema, CapScopeSchema, CapabilityBindingsSchema, CarbonMonoxideStatusSchema, ChargingStatus, ClientNetworkStatsSchema, ClimateControlStatusSchema, ClipPlaybackSchema, ClipSchema, ClusterAddonNodeDeploymentSchema, ClusterAddonStatusEntrySchema, CollectionColumnSchema, CollectionIndexSchema, ColorStatusSchema, ConfigEntrySchema, ConfigSectionWithValuesSchema, ConfigTabDeclarationSchema, ConnectivityStatusSchema, ConsumableItemSchema, ConsumablesStatusSchema, ContactStatusSchema, ControlKindSchema, ControlStatusSchema, ConvertArtifactSchema, ConvertResultSchema, ConvertTargetSchema, CoreBlockCompileResultSchema, CoreBlockInputSchema, CoreBlockPlacementSchema, CoreBlockSchema, CoreBlockStatusSchema, CoverStateSchema, CoverStatusSchema, CreateApiKeyInputSchema, CreateApiKeyResultSchema, CreateIntegrationInputSchema, CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, CreateUserInputSchema, CustomActionInputSchema, CustomModelDescriptorSchema, DATAPLANE_SECRET_HEADER, DEFAULT_ADDON_PLACEMENT, DEFAULT_AUDIO_ANALYZER_CONFIG, DEFAULT_DECODER_HWACCEL_CONFIG, DEFAULT_DETAIL_CROP_CONVENTION, DEFAULT_EVENT_COLOR, DEFAULT_FEATURES, DEFAULT_NATIVE_LEASE_SETTINGS, DEFAULT_RETENTION, DEFAULT_SCRUB_THUMBNAIL_PRESET, DETAIL_CROP_PADDING_FIELD, DETAIL_CROP_PADDING_KEY, DETAIL_CROP_SECTION_ID, DETAIL_CROP_SQUARE_KEY, DETECTION_PIPELINE_CAP_NAME, DEVICE_BACKEND_TO_FORMAT, DEVICE_CAP_NAMES, DEVICE_PROFILES, DEVICE_SCOPED_CAPS, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATE_READERS, DEVICE_STATUS_METHOD, DEVICE_TYPE_CONTROL_KIND, DEVICE_TYPE_INFO, EngineInfoSchema as DataStoreEngineInfoSchema, DayNightModeSchema, DayNightOptionsSchema, DayNightSettingsPatchSchema, DayNightStatusSchema, DecodedAudioChunkSchema, DecodedFrameSchema, DecoderSessionConfigSchema, DecoderStatsSchema, DeleteIntegrationResultSchema, DetailCropConventionSchema, DetectionSourceSchema, DeviceCodeSeveritySchema, DeviceConfig, DeviceDiscoveryStatusSchema, ExposeInputSchema as DeviceExportExposeInputSchema, DeviceExportStatusSchema, UnexposeInputSchema as DeviceExportUnexposeInputSchema, DeviceFeature, DeviceInfoSchema, DeviceLinkModeSchema, DeviceNetworkStatsSchema, DeviceRole, DeviceRuntimeState, DeviceStatusSchema, DeviceType, DiscoveredChildDeviceSchema, DiscoveredChildStatusSchema, DiscoveredDeviceSchema, DiscoveredTargetSchema, DisposerChain, DoorbellPressEventSchema, DoorbellStatusSchema, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_PAD_MS, EVENT_TAXONOMY, EXPRESSION_BUILTINS, EXPRESSION_BUILTIN_NAMES, EXPRESSION_COMPILE_CACHE_CAPACITY, EXPRESSION_IDENTIFIER_RE, EXPRESSION_INJECTED_NOW, EgressEncodeSchema, EgressRateControlSchema, EgressTranscodeRequestSchema, EgressTranscodeSchema, ElementConfigStore, EmbeddingInfoSchema, EmbeddingResultSchema, EncodeProfileSchema, EncodedPacketSchema, EnrichedWidgetMetadataSchema, EnumSensorDateTimeFormatSchema, EnumSensorStatusSchema, EventCategory, EventEmitterStatusSchema, EventFireSchema, EventItemSchema, EventKindCategorySchema, EventKindDescriptorSchema, EventKindIconSchema, EventKindSchema, EventKindsForDeviceSchema, EventSourceType, ExportDownloadSchema, ExportOptionsSchema, ExportRecordSchema, ExportSetupFieldSchema, ExportSetupSchema, ExportSpeedSchema, ExportStateSchema, ExportTimelapseSchema, ExposedDeviceSchema, ExposureModeSchema, ExpressionEvalError, ExpressionParseError, FanControlStatusSchema, FanDirectionSchema, FeatureManifestSchema, FeatureProbeStatusSchema, FloodStatusSchema, Fmp4BoxSplitter, FrameHandleFormatSchema, FrameHandleSchema, FrameInputSchema, GasStatusSchema, GetStreamWithCodecInputSchema, GlobalMetricsSchema, HAP_AUDIO_BASE, HAP_AUDIO_BITRATE_KBPS, HAP_AUDIO_VBV_KBITS, HAP_KEYFRAME_INTERVAL_SEC, HF_BASE_URL, HF_REPO, HWACCEL_OPTIONS, HealthStatusSchema, HistoryPointSchema, HistoryResolutionEnum, HumidifierStatusSchema, HumiditySensorStatusSchema, HvacModeSchema, ImageContractSchema, ImageContractStateSchema, ImageRotateSchema, ImageSettingsOptionsSchema, ImageSettingsPatchSchema, ImageSettingsStatusSchema, ImageStatusSchema, IngestOwnerSchema, InstalledPackageSchema, IntegrationLiteSchema, IntegrationWithStateSchema, IntercomAbilitySchema, IntercomStatusSchema, KNOWN_CAP_NAMES, KeyEventSchema, LOG_LEVEL_RANK, LabelDefinitionSchema, LawnMowerActivitySchema, LawnMowerControlStatusSchema, LinkedDeviceSchema, LlmDefaultSchema, LlmDefaultSelectorSchema, LlmErrorCodeSchema, LlmGenerateBaseInputSchema, LlmGenerateErrSchema, LlmGenerateOkSchema, LlmGenerateResultSchema, LlmImageSchema, LlmNodeModelSchema, LlmProfileKindDescriptorSchema, LlmProfileKindSchema, LlmProfileSchema, LlmRuntimeCompleteInputSchema, LlmRuntimeDiskUsageSchema, LlmRuntimeNodeSchema, LlmRuntimeStatusSchema, LlmUsageRollupSchema, LlmUsageSchema, LocateSegmentResultSchema, LocationStatSchema, LockControlStatusSchema, LockStateSchema, LogEntrySchema, LogLevelSchema, LogStreamEntrySchema, LoginMethodContributionSchema, LoginStageEnum, MACRO_LABELS, MAX_EXPRESSION_AST_NODES, MAX_EXPRESSION_BINDINGS, MAX_EXPRESSION_CALL_ARGS, MAX_EXPRESSION_EVAL_STEPS, MAX_EXPRESSION_SOURCE_LENGTH, METHOD_ACCESS_MAP, MODEL_FORMATS, MOTION_TRIGGER_FEATURE, ManagedModelCatalogEntrySchema, ManagedModelRefSchema, ManagedRuntimeConfigSchema, MaskGridDimsSchema, MaskGridShapeSchema, MaskLineShapeSchema, MaskPointSchema, MaskPolygonShapeSchema, MaskPolygonVerticesSchema, MaskRectShapeSchema, MaskShapeKindSchema, MaskShapeSchema, MediaFileInfoSchema, MediaFileSchema, MediaPlayerRepeatSchema, MediaPlayerStateSchema, MediaPlayerStatusSchema, MeshPeerSchema, MeshStatusSchema, MethodAccessSchema, ModelCatalogEntrySchema, ModelConvertInputSchema, ModelConvertMetadataSchema, ModelDistributeInputSchema, ModelDistributeResultSchema, ModelExtraFileSchema, ModelFormatEntrySchema, ModelFormatsSchema, ModelSubstitutionSchema, ModelVariantGroupSchema, MotionAnalysisResultSchema, MotionEventSchema, MotionOnMotionChangedDataSchema, MotionRegionSchema, MotionSourceEnum, MotionSourcesSchema, MotionStatusSchema, MotionTriggerRuntimeStateSchema, MotionTriggerStatusSchema, MotionZoneOptionsSchema, MotionZonePatchSchema, MotionZoneRegionSchema, MotionZoneStatusSchema, StatusSchema as MqttBrokerStatusSchema, MutationFilterSchema, NATIVE_LEASE_ACTIVITY_FIELD, NATIVE_LEASE_ACTIVITY_KEY, NATIVE_LEASE_ADMISSION_FIELD, NATIVE_LEASE_ADMISSION_KEY, NATIVE_LEASE_BUDGET_FIELD, NATIVE_LEASE_BUDGET_KEY, NATIVE_LEASE_SECTION_ID, NATIVE_LEASE_TTL_FIELD, NATIVE_LEASE_TTL_KEY, NC_BASE_CONDITION_KEYS, NC_CONDITION_CATALOG, NC_HISTORY_LIMIT_DEFAULT, NC_HISTORY_LIMIT_MAX, NC_MAX_PER_TRACK_IMMEDIATE, NC_SNOOZE_MAX_MINUTES, NC_TAXONOMY, NativeCropBboxSchema, NativeCropRefSchema, NativeCropResultSchema, NativeDetectionSchema, NativeLeaseAdmissionSchema, NativeLeaseSettingsSchema, NativeObjectClassEnum, NativeObjectDetectionRuntimeStateSchema, NativeObjectDetectionStatusSchema, NcAlarmConfigSchema, NcAlarmModeCoverageSchema, NcAlarmSettingsPatchSchema, NcAlarmSettingsSchema, NcConditionDescriptorSchema, NcConditionsSchema, NcCrossingSchema, NcDeliverySchema, NcDeviceStateConditionSchema, NcHistoryEntrySchema, NcHistoryFilterSchema, NcHistoryRecordKindSchema, NcHistoryStatusSchema, NcHistorySubjectSchema, NcMediaFrameSchema, NcMediaPolicySchema, NcOccupancyConditionSchema, NcPlateMatcherSchema, NcRuleActionSchema, NcRuleActionSequenceSchema, NcRuleActionsSchema, NcRuleInputSchema, NcRuleNotificationButtonSchema, NcRulePatchSchema, NcRuleSchema, NcRuleTargetSchema, NcScheduleSchema, NcScheduleWindowSchema, NcSnoozeInputSchema, NcSnoozeSchema, NcSnoozeScopeSchema, NcSnoozeSuppressedSchema, NcTaxonomyEntrySchema, NcTaxonomySchema, NcTestResultSchema, NcThrottleGranularitySchema, NcThrottleSchema, NcZoneConditionSchema, NetworkAccessStatusSchema, NetworkAddressSchema, NetworkEndpointSchema, NotificationActionIconSchema, NotificationActionSchema, NotificationFormatSchema, NotificationSchema, NotifierStatusSchema, NumericSensorStatusSchema, OPS_LOG_DEFAULT_LIMIT, OPS_LOG_RING_DEFAULT_MAX, OauthIntegrationDescriptorSchema, ObjectEventSchema, OpsLogDomainSchema, OpsLogEntrySchema, OpsLogOpSchema, OpsLogQueryInputSchema, OpsLogReasonSchema, OrchestratorMetricsSchema, OsdOverlayKindEnum, OsdOverlayPatchSchema, OsdOverlaySchema, OsdPositionEnum, OsdRenderOutcomeEnum, OsdRenderResultSchema, OsdSlotBindingSchema, OsdSlotViewSchema, OsdSourceOptionSchema, OsdSourceSchema, OsdSourceValueTypeEnum, OsdStatusSchema, PET_FEEDER_MANUAL_FEED_MAX, PET_FEEDER_MANUAL_FEED_MIN, PIPELINE_FLOW_CAPABILITY_NAMES, PIPELINE_OWNER_CAPABILITY_NAMES, PRIVACY_MASK_CAP_NAME, PROVIDER_KIND_CAP_NAMES, PYTHON_SCRIPT, PackageUpdateSchema, PackageVersionInfoSchema, PasskeyLoginMethodSchema, PasskeySummarySchema, PcmSampleFormatSchema, PerScopeBreakdownSchema, PetFeederStatusSchema, PickStreamPreferencesSchema, PickStreamRequirementsSchema, PickedCamStreamSchema, PipelineAssignmentSchema, PipelineDefaultStepSchema, PipelineEngineChoiceSchema, PipelineRunResultBridge, PipelineStepInputSchema, PipelineValidationIssueSchema, PipelineValidationResultSchema, PlaceholderReasonSchema, PolygonPointSchema, PowerMeterStatusSchema, PresenceStatusSchema, PressureSensorStatusSchema, PrivacyMaskOptionsSchema, PrivacyMaskPatchSchema, PrivacyMaskRegionSchema, PrivacyMaskShapeSchema, PrivacyMaskStatusSchema, ProfileRtspEntrySchema, ProfileSlotSchema, ProfileSlotStatusSchema, ProviderStatusSchema, PtzAutotrackRuntimeStateSchema, PtzAutotrackSettingsSchema, PtzAutotrackStatusSchema, PtzAutotrackTargetOptionSchema, PtzMoveCommandSchema, PtzOptionsSchema, PtzPositionSchema, PtzPresetSchema, PtzStatusSchema, QueryFilterSchema, RATE_CONTROL_RELAXED, RATE_CONTROL_TIGHT, REACHABILITY_FAILURES_TO_OFFLINE, REACHABILITY_POLL_INTERVAL_MS, REACHABILITY_PROBE_TIMEOUT_MS, RECOGNITION_TYPES, RESERVED_BINDING_NAMES, RUNTIME_DEFAULTS, RUNTIME_TO_FORMAT, RawStateResultSchema, ReadGopBytesResultSchema, ReadSegmentBytesResultSchema, ReadinessRegistry, ReadinessTimeoutError, RecentTracksPageSchema, RecentTracksQueryInput, RecordingAvailabilitySchema, RecordingBandModeSchema, RecordingBandSchema, RecordingBandTriggersSchema, RecordingConfigSchema, RecordingDaysSchema, RecordingDeviceUsageSchema, RecordingLocationUsageSchema, RecordingManifestSchema, RecordingRangeSchema, RecordingRetentionSchema, RecordingStatusSchema, RecordingStorageModeSchema, RecordingStorageUsageSchema, RecordingTriggersSchema, RecordingWeekdaySchema, RedirectLoginMethodSchema, RelocateFootageInputSchema, RelocateJobSchema, RelocateJobStateSchema, RelocateMediaInputSchema, RenderedAsSchema, ReportMotionInputSchema, RetrainStatusSchema, RingBuffer, RtpSourceSchema, RtspRestreamEntrySchema, RunnerCameraConfigSchema, RunnerCameraDeviceUIFields, RunnerFrameSourceSchema, RunnerInferenceDeviceSchema, RunnerLocalLoadSchema, RunnerLocalMetricsSchema, SCOPE_PRESETS, SCRUB_THUMBNAIL_PRESETS, SCRUB_THUMBNAIL_PRESET_LABELS, SCRUB_THUMBNAIL_PRESET_ORDER, SENSOR_FEATURES, SENSOR_MAP, SOURCE_INFO_METADATA_KEY, STREAM_PROFILE_META, STREAM_QUALITY_LABELS, SUB_DETECTION_TYPES, SYSTEM_CAP_NAMES, SceneCheckSchema, SceneConditionSchema, SceneMonitorSchema, SceneMonitorStateSchema, SceneMonitorStatusSchema, SceneReferenceSchema, ScopedTokenSchema, ScopedTokenSummarySchema, ScoredObjectEventSchema, ScriptRunnerStatusSchema, ScrubThumbnailPresetSchema, SearchResultSchema, SendEmailInputSchema, SendEmailResultSchema, SendResultSchema, SensorEventSchema, ServerBootModeSchema, ServerPackageStatusSchema, ServerRollbackInfoSchema, ServerUpdateActionResultSchema, ServerUpdateCheckResultSchema, ServerUpdateStateSchema, SettingsPatchSchema, SettingsRecordSchema, SettingsSchemaWithValuesSchema, SettingsUpdateResultSchema, ShmRingStatsSchema, SmokeStatusSchema, SmtpStatusSchema, SnapshotImageSchema, SourceInfoSchema, SpatialDetectionSchema, SsoBridgeClaimsSchema, StartEmbeddedInputSchema, StationaryObjectSchema, AbortUploadInputSchema as StorageAbortUploadInputSchema, BeginDownloadInputSchema as StorageBeginDownloadInputSchema, BeginDownloadResultSchema as StorageBeginDownloadResultSchema, BeginUploadInputSchema as StorageBeginUploadInputSchema, BeginUploadResultSchema as StorageBeginUploadResultSchema, EndDownloadInputSchema as StorageEndDownloadInputSchema, FinalizeUploadInputSchema as StorageFinalizeUploadInputSchema, StorageLocationDeclarationSchema, StorageLocationRefSchema, StorageLocationSchema, StorageLocationTypeSchema, ProviderInfoSchema as StorageProviderInfoSchema, ReadChunkInputSchema as StorageReadChunkInputSchema, TestLocationResultSchema as StorageTestLocationResultSchema, WriteChunkInputSchema as StorageWriteChunkInputSchema, StreamCodecSchema, StreamFormatSchema, StreamNetworkStatsSchema, StreamParamsOptionsSchema, StreamParamsStatusSchema, StreamProfileConfigSchema, StreamProfileOptionsSchema, StreamProfilePatchSchema, StreamProfileSchema, StreamSourceEntrySchema, StreamSourceSchema, SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, SubscribeFramesInputSchema, SubscribeFramesResultSchema, SwitchStatusSchema, SystemMetricsSchema, SystemMirror, TAXONOMY_COLORS, TIMEZONES, TRANSCODE_DOWN_MAX_BITRATE_KBPS, TRANSCODE_DOWN_MAX_HEIGHT, TamperStatusSchema, TankStatusSchema, TargetKindCapsSchema, TargetKindLevelSchema, TargetKindSchema, TargetSchema, TemperatureSensorStatusSchema, TerminalProfileInfoSchema, TerminalSessionInfoSchema, TestConnectionResultSchema$1 as TestConnectionResultSchema, TestResultSchema, TimelapseRuleInputSchema, TimelapseRulePatchSchema, TimelapseRuleSchema, TimelapseTemplateSchema, ToastSchema, TokenScopeSchema, TopologyNodeSchema, TopologyProcessSchema, TopologyServiceSchema, TrackCascadeCountsSchema, TrackEnvelopeSchema, TrackFlagsPatchSchema, TrackFlagsSchema, TrackProjectionSchema, TrackSchema, TrackSourceSchema, TrackStateSchema, TrackZoneFilterSchema, TrackedDetectionSchema, TrainingExportDeviceTotalsSchema, TrainingExportSummarySchema, TurnServerSchema, UNIT_TABLE, BrokerInfoSchema$1 as UnifiedBrokerInfoSchema, UnitConversionError, UpdateIntegrationInputSchema, UpdateStatusSchema, UpdateUserInputSchema, UserRecordSchema, UserSummarySchema, VacuumControlStatusSchema, VacuumStateSchema, ValveStateSchema, ValveStatusSchema, VectorDeclareIndexInputSchema, VectorDeleteByFilterInputSchema, VectorDeleteInputSchema, VectorDeleteResultSchema, VectorFilterSchema, VectorGetInputSchema, VectorGetResultSchema, VectorItemSchema, VectorMatchSchema, VectorMetadataSchema, VectorMetricSchema, VectorQueryInputSchema, VectorQueryResultSchema, VectorStatsInputSchema, VectorStatsResultSchema, VectorUpsertInputSchema, VectorUpsertResultSchema, VibrationStatusSchema, VideoEncodeSchema, WEBRTC_EGRESS_PROFILE, WELL_KNOWN_TABS, WELL_KNOWN_TAB_MAP, WaterHeaterStatusSchema, WeatherStatusSchema, WebrtcStreamChoiceSchema, WebrtcStreamTargetSchema, WhiteBalanceModeSchema, WidgetHostEnum, WidgetLoginMethodSchema, WidgetMetadataSchema, WidgetRemoteSchema, WidgetSizeEnum, YAMNET_TO_MACRO, ZoneCrossingDirectionSchema, ZoneCrossingSchema, ZoneKindEnum, ZoneRuleModeEnum, ZoneRuleSchema, ZoneRuleStageEnum, ZoneRulesArraySchema, ZoneSchema, ZoneScopeBreakdownSchema, accessoriesCapability, accessoryStableId, addonPagesCapability, addonPagesSourceCapability, addonRoutesCapability, addonSettingsCapability, addonWidgetsCapability, addonWidgetsSourceCapability, addonsCapability, adminUiCapability, airQualitySensorCapability, alarmPanelCapability, alertsCapability, ambientLightSensorCapability, applyTransform, asBoolean, asJsonArray, asJsonObject, asNumber, asString, audioAnalysisCapability, audioAnalyzerCapability, audioCodecCapability, audioMetricsCapability, audioPlanFromEncodeProfile, authProviderCapability, autoAssignProfiles, automationControlCapability, backupCapability, bareAddonId, batteryCapability, bestLocationMatch, binaryCapability, bindAddonActions, brightnessCapability, brokerCapability, buildAddonRouteProvider, buildAudioArgs, buildEventKindDescriptor, buildFfmpegArgs, buildInputArgs, buildModelVariantGroups, buildNcTaxonomy, buildStreamParamsConfigSchema, buildVideoArgs, buttonCapability, cameraCredentialsCapability, cameraPipelineConfigCapability, cameraStreamsCapability, canConvertUnit, canonicalEgressPlan, carbonMonoxideCapability, cellsToRects, classifyStream, classifyStreams, climateControlCapability, collectHydratedFieldEntries, collectHydratedFieldValues, colorCapability, colorForKind, compileExpression, compileExpressionSafe, connectivityCapability, consumablesCapability, contactCapability, controlCapability, convertUnit, coreBlocksCapability, cosineSimilarity, coverCapability, createDeviceProxy, createDurableState, createEvent, createExpressionScope, createHwAccelCache, createLazyTrpcSource, createMirrorSource, createRuntimeStateBridge, createSliceHandle, createSystemProxy, customAction, customModelRegistryCapability, dataStoreProviderCapability, dayNightCapability, decodeVectorBase64, decoderCapability, defaultDeviceFor, defineCustomActions, deriveCameraSwitches, deriveDetailCropRect, deriveRecordingMode, describeModelVariant, detectionPipelineCapability, deviceAdoptionCapability, deviceBackendToFormat, deviceCustomAction, deviceDiscoveryCapability, deviceExportCapability, deviceManagerCapability, deviceMatchesProfile, deviceOpsCapability, deviceProviderCapability, deviceStateCapability, deviceStatusCapability, doorbellCapability, egressTranscodeSharingKey, egressTransportFromRequest, embeddingEncoderCapability, emitDownForOwnedCaps, emitReadiness, encodeProfileFromStreamShape, encodeVectorBase64, enumSensorCapability, enumerateInferenceDevices, enumerateItemArrayFields, enumerateSchemaFields, errMsg, evaluateAst, evaluateLinkExpression, evaluateZoneRules, event, eventEmitterCapability, eventsCapability, expandCapMethods, extractNestedAddonId, extractSourceInfoFromMetadata, faceGalleryCapability, fanControlCapability, featureProbeCapability, filesystemBrowseCapability, findTimezone, floodCapability, formatForBackend, formatForRuntime, gasCapability, getAudioMacroClassIds, getByPath, getCapsByProviderKind, getTaxonomyEntry, hasMotionTrigger, hfModelUrl, htmlToText, humidifierCapability, humiditySensorCapability, hydrateSchema, imageCapability, imageSettingsCapability, integrationsCapability, intercomCapability, invocationFromEncodeProfile, isAgentOnlyPlacement, isArrayOutputSchema, isBaseConditionKey, isCollectionArrayMethod, isDeployableToAgent, isDeviceConfigCap, isDeviceScopedCap, isEvent, isNode, isObjectInput, isSameAddonId, isScheduleActive, isSoftwareDecode, isVoidInput, jobKindSchema, kebabToCamel, knownValues, lawnMowerControlCapability, lifecycleJobSchema, lifecycleJobScopeSchema, lifecycleJobStateSchema, lifecycleTaskSchema, llmCapability, llmRuntimeCapability, localNetworkCapability, locationSimilarity, lockControlCapability, logBannerArgs, logDestinationCapability, logLevelAtMost, loginMethodCapability, looseSchema, makeProfileBrokerId, makeSourceBrokerId, mapAudioLabelToMacro, markdownToHtmlLite, markdownToText, maskUrlCredentials, mediaPlayerCapability, mergeSourceInfo, meshNetworkCapability, method, metricsProviderCapability, modelConvertCapability, modelDistributorCapability, modelFormatForRuntime, motionCapability, motionDetectionCapability, motionTriggerCapability, motionZonesCapability, mqttBrokerCapability, nativeObjectDetectionCapability, networkAccessCapability, networkQualityCapability, nodePin, nodesCapability, normalizeAddonInitResult, normalizeUnit, notificationOutputCapability, notificationRulesCapability, notifierCapability, numericSensorCapability, oauthIntegrationCapability, objectInputDeclaresAddonId, osdCapability, osdManagerCapability, parseCameraStreamConfig, parseExpression, parseJsonArray, parseJsonObject, parseJsonUnknown, parseProfileBrokerId, parseStreamParamsFormPatch, petFeederCapability, pickAccessoryControl, pickDetailCropConvention, pickNativeLeaseOverride, pickPreferredRtspEntry, pickVideoEncoder, pickerForCondition, pipelineAnalyticsCapability, pipelineExecutorCapability, pipelineOrchestratorCapability, pipelineRunnerCapability, plateGalleryCapability, platformProbeCapability, powerMeterCapability, prepareNotification, presenceCapability, pressureSensorCapability, privacyMaskCapability, procedureAuthKey, ptzAutotrackCapability, ptzCapability, pythonScriptForBackend, readDetailCropConvention, readDeviceStateFrom, readNativeLeaseOverride, readNodePin, readinessKey, rebootCapability, recordingCapability, recordingExportCapability, rectsToCells, requiresPython, resolveAddonExecution, resolveAddonGroup, resolveAddonPlacement, resolveAddonRuntime, resolveCapMount, resolveDetectionRuntime, resolveDeviceControlKind, resolveDeviceProfile, resolveEgressDecodeHwAccel, resolveFormat, resolveHydratedFieldValue, resolveModelFormat, resolveMutate, resolveRunnerId, resolveScrubThumbnailGeometry, resolveVariantModelId, runInferenceStep, runtimeDevices, sceneMonitorCapability, scopeKey, scoreRuntimes, scriptRunnerCapability, selectAssignedProfileSlots, serverManagementCapability, setByPath, settingsStoreCapability, sleep, sleepCancellable, smokeCapability, smtpProviderCapability, snapshotCapability, ssoBridgeCapability, startReachabilityPoll, stateVocabularyFor, storageCapability, storageEvictableCapability, storageProviderCapability, streamBrokerCapability, streamCatalogCapability, streamParamsCapability, streamPixels, streamQualityLabel, subKindsOf, summarisePrivacyAudio, supportedRuntimes, switchCapability, switchedOffIds, synthesizeSourceInfo, systemCapability, tamperCapability, taskLogEntrySchema, taskPhaseSchema, taskTargetSchema, temperatureSensorCapability, terminalSessionCapability, textToHtml, toDeviceSummary, toExpressionValue, toNodeId, toStreamSourceEntry, toastCapability, tokenize, transcodeBody, tryConvertUnit, turnProviderCapability, unitDimension, unitsForDimension, updateCapability, userManagementCapability, userPasskeysCapability, vacuumControlCapability, validateExpressionSource, valveCapability, vectorDimFromBase64, vectorStoreCapability, vibrationCapability, videoclipsCapability, viewerUiCapability, waterHeaterCapability, weatherCapability, webrtcClientHintsSchema, webrtcSessionCapability, wiringAddonHealthSchema, wiringHealthSnapshotSchema, wiringNodeHealthSchema, wiringProbeKindSchema, wiringProbeResultSchema, zodEntriesToConfigUI, zoneAnalyticsCapability, zoneRulesCapability, zonesCapability };