@camstack/addon-post-analysis 1.2.109 → 1.2.115

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.
@@ -8260,6 +8260,15 @@ var LabelDefinitionSchema = object({
8260
8260
  description: string().optional(),
8261
8261
  icon: string().optional()
8262
8262
  });
8263
+ var ClassMapDefinitionSchema = object({
8264
+ mapping: record(string(), _enum([
8265
+ "person",
8266
+ "vehicle",
8267
+ "animal",
8268
+ "package"
8269
+ ])),
8270
+ preserveOriginal: boolean()
8271
+ });
8263
8272
  var MODEL_FORMATS = [
8264
8273
  "onnx",
8265
8274
  "coreml",
@@ -8438,7 +8447,13 @@ var ModelCatalogEntrySchema = object({
8438
8447
  * `id` stays the source of truth for resolution/download/persistence; grouping
8439
8448
  * is a presentation overlay resolved back to an `id`.
8440
8449
  */
8441
- group: ModelVariantGroupSchema.optional()
8450
+ group: ModelVariantGroupSchema.optional(),
8451
+ /**
8452
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8453
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8454
+ * labels already ARE the CamStack macros (Scrypted identity map).
8455
+ */
8456
+ classMap: ClassMapDefinitionSchema.optional()
8442
8457
  });
8443
8458
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8444
8459
  format: literal("openvino"),
@@ -8467,7 +8482,8 @@ var ModelConvertMetadataSchema = object({
8467
8482
  "ocr",
8468
8483
  "segmentation"
8469
8484
  ]),
8470
- faceAlignment: boolean().optional()
8485
+ faceAlignment: boolean().optional(),
8486
+ classMap: ClassMapDefinitionSchema.optional()
8471
8487
  });
8472
8488
  var ConvertResultSchema = object({
8473
8489
  entry: ModelCatalogEntrySchema,
@@ -14963,12 +14979,15 @@ var NcOccupancyConditionSchema = object({
14963
14979
  * there is no second switch that can disagree with the first and every rule
14964
14980
  * authored before the decision migrates for free (`audioModeOf`):
14965
14981
  *
14966
- * - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
14967
- * classifier labels with one of them. No window, no percentage:
14968
- * `hitPercent` and `samplingSeconds` are ignored, and the rule's own
14969
- * `throttle` cooldown is the only brake. The per-label confidence floor is
14970
- * the analyzer's (`classificationMinScore`, per device) — a label only
14971
- * reaches this condition if the classifier was already confident enough.
14982
+ * - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
14983
+ * labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
14984
+ * `hitPercent` and `samplingSeconds` are still ignored — a percentage of
14985
+ * frames is the wrong question for a classifier that labels 1–3 frames
14986
+ * per episode. The count window is the brake that drops a single-frame
14987
+ * false positive; the rule's own `throttle` cooldown is the other. The
14988
+ * per-label confidence floor is the analyzer's (`classificationMinScore`,
14989
+ * per device) — a label only reaches this condition if the classifier was
14990
+ * already confident enough. `confirmHits: 1` restores first-frame fire.
14972
14991
  * - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
14973
14992
  * the condition: at least `hitPercent`% of the samples over
14974
14993
  * `samplingSeconds` must be at or above `dbThreshold` dBFS (see
@@ -14995,14 +15014,22 @@ var NcOccupancyConditionSchema = object({
14995
15014
  * an operator who typed `dog` mean the same thing.
14996
15015
  */
14997
15016
  var NcAudioConditionSchema = object({
14998
- /** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
15017
+ /** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
14999
15018
  labels: array(string().min(1)).min(1).optional(),
15000
15019
  /** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
15001
15020
  dbThreshold: number().min(-96).max(0).optional(),
15002
15021
  /** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
15003
15022
  hitPercent: number().int().min(1).max(100).default(60),
15004
15023
  /** LEVEL MODE ONLY: length of the sampling window in seconds. */
15005
- samplingSeconds: number().int().min(1).max(300).default(10)
15024
+ samplingSeconds: number().int().min(1).max(300).default(10),
15025
+ /**
15026
+ * LABEL MODE: how many labelled frames must land inside
15027
+ * {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
15028
+ * Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
15029
+ */
15030
+ confirmHits: number().int().min(1).max(20).optional(),
15031
+ /** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
15032
+ confirmWindowSec: number().int().min(1).max(60).optional()
15006
15033
  });
15007
15034
  /**
15008
15035
  * Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
@@ -17997,7 +18024,9 @@ var TrackCascadeCountsSchema = object({
17997
18024
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
17998
18025
  plates: number().int(),
17999
18026
  /** Per-track CLIP search vectors removed (best-effort). */
18000
- embeddings: number().int()
18027
+ embeddings: number().int(),
18028
+ /** Group membership + group rows removed with their last member (best-effort). */
18029
+ groups: number().int()
18001
18030
  });
18002
18031
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18003
18032
  var DiskReconcileCountsSchema = object({
@@ -18762,6 +18791,33 @@ var NativeCropRefSchema = object({
18762
18791
  h: number()
18763
18792
  })
18764
18793
  });
18794
+ object({
18795
+ crop: object({
18796
+ left: number(),
18797
+ top: number(),
18798
+ width: number().positive(),
18799
+ height: number().positive()
18800
+ }).optional(),
18801
+ content: object({
18802
+ width: number().int().positive(),
18803
+ height: number().int().positive()
18804
+ }),
18805
+ fit: _enum(["stretch", "contain"]),
18806
+ format: _enum([
18807
+ "rgb",
18808
+ "gray",
18809
+ "jpeg"
18810
+ ])
18811
+ });
18812
+ var FrameRefSchema = object({
18813
+ registryId: string().min(1),
18814
+ id: string().min(1),
18815
+ width: number().int().positive(),
18816
+ height: number().int().positive(),
18817
+ format: _enum(["rgb", "gray"]),
18818
+ timestamp: number(),
18819
+ capturedAt: number().optional()
18820
+ });
18765
18821
  var ModelFormatSchema$1 = _enum([
18766
18822
  "onnx",
18767
18823
  "coreml",
@@ -19006,6 +19062,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
19006
19062
  steps: array(PipelineStepInputSchema).min(1),
19007
19063
  frame: FrameInputSchema.optional(),
19008
19064
  /**
19065
+ * Process-local lazy frame. Valid only when caller and provider resolve
19066
+ * in the same execution-group process; split/cross-node callers use
19067
+ * `frame`/`image` inline compatibility instead.
19068
+ */
19069
+ frameRef: FrameRefSchema.optional(),
19070
+ /**
19009
19071
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
19010
19072
  * the decoded pixels live in. One more member of the one-of
19011
19073
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -19301,7 +19363,10 @@ var NativeCropResultSchema = object({
19301
19363
  * Which source served this crop, so a quality-sensitive consumer (the native
19302
19364
  * `keyFrame`) can reject a degraded fallback:
19303
19365
  * - `native` — cut from the decode worker's retained NATIVE surface (the
19304
- * quality path).
19366
+ * quality path). A subject-tile serve is also native-resolution and stays
19367
+ * `native` here: the public enum cannot name `tile` without a breaking cap
19368
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
19369
+ * internal crop result (`nativeHits` vs `tileHits`).
19305
19370
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
19306
19371
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
19307
19372
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -19792,12 +19857,41 @@ var RunnerLocalLoadSchema = object({
19792
19857
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
19793
19858
  * working unchanged when they switch to reading from the runner cap.
19794
19859
  */
19860
+ var FrameLazyCountersSchema = object({
19861
+ framesDecoded: number(),
19862
+ framesAdmitted: number(),
19863
+ framesDroppedPixelFree: number(),
19864
+ viewsMaterialized: number(),
19865
+ viewsSkipped: number(),
19866
+ workerToRunnerBytes: number(),
19867
+ runnerToPoolRawBytes: number(),
19868
+ runnerToPoolJpegBytes: number(),
19869
+ onDemandFullFrameRequests: number(),
19870
+ onDemandCropRequests: number(),
19871
+ nativeHits: number(),
19872
+ nativeMisses: number(),
19873
+ tileHits: number(),
19874
+ tileMisses: number(),
19875
+ fallbackHits: number(),
19876
+ fallbackMisses: number(),
19877
+ retainedWritesAvoided: number(),
19878
+ residentRefs: number(),
19879
+ residentBytes: number(),
19880
+ releases: number(),
19881
+ evictions: number(),
19882
+ staleMisses: number()
19883
+ });
19884
+ var FrameLazyMetricsSchema = object({
19885
+ node: FrameLazyCountersSchema,
19886
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
19887
+ });
19795
19888
  var RunnerLocalMetricsSchema = object({
19796
19889
  nodeId: string(),
19797
19890
  activeCameras: number(),
19798
19891
  throttledCameras: number(),
19799
19892
  avgInferenceTimeMs: number(),
19800
- queueDepth: number()
19893
+ queueDepth: number(),
19894
+ frameLazy: FrameLazyMetricsSchema.optional()
19801
19895
  });
19802
19896
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
19803
19897
  handle: FrameHandleSchema,
@@ -21127,6 +21221,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
21127
21221
  location: StorageLocationSchema,
21128
21222
  relativePath: string()
21129
21223
  }), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
21224
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
21225
+ var ProfileSettingsSchemaBridge = unknown().nullable();
21226
+ var ProfileSettingsBagSchema = record(string(), unknown());
21130
21227
  /**
21131
21228
  * A live terminal session hosted by the provider addon. Output and input do
21132
21229
  * NOT flow through the capability — they use the addon data plane
@@ -21161,7 +21258,9 @@ var TerminalProfileInfoSchema = object({
21161
21258
  executable: string().optional(),
21162
21259
  args: array(string()).readonly().optional(),
21163
21260
  cwd: string().optional(),
21164
- environment: array(string()).readonly().optional()
21261
+ environment: array(string()).readonly().optional(),
21262
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
21263
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
21165
21264
  });
21166
21265
  /**
21167
21266
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -21178,7 +21277,8 @@ var TerminalInstanceInfoSchema = object({
21178
21277
  executable: string(),
21179
21278
  args: array(string()).readonly(),
21180
21279
  cwd: string(),
21181
- environment: array(string()).readonly()
21280
+ environment: array(string()).readonly(),
21281
+ profileSettings: ProfileSettingsBagSchema
21182
21282
  });
21183
21283
  var TerminalLegacyCameraSchema = object({
21184
21284
  stableId: string(),
@@ -21212,7 +21312,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
21212
21312
  executable: string().max(1024).optional(),
21213
21313
  args: array(string().max(2048)).max(64).optional(),
21214
21314
  cwd: string().max(1024).optional(),
21215
- environment: array(string().max(4096)).max(64).optional()
21315
+ environment: array(string().max(4096)).max(64).optional(),
21316
+ profileSettings: ProfileSettingsBagSchema.optional()
21216
21317
  }), TerminalInstanceInfoSchema, {
21217
21318
  kind: "mutation",
21218
21319
  auth: "admin"
@@ -21222,7 +21323,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
21222
21323
  executable: string().max(1024).optional(),
21223
21324
  args: array(string().max(2048)).max(64).optional(),
21224
21325
  cwd: string().max(1024).optional(),
21225
- environment: array(string().max(4096)).max(64).optional()
21326
+ environment: array(string().max(4096)).max(64).optional(),
21327
+ profileSettings: ProfileSettingsBagSchema.optional()
21226
21328
  }), TerminalInstanceInfoSchema, {
21227
21329
  kind: "mutation",
21228
21330
  auth: "admin"
@@ -25163,10 +25265,10 @@ var lawnMowerControlCapability = {
25163
25265
  *
25164
25266
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
25165
25267
  * to receive an ordered list of candidate base URLs it should race
25166
- * on connect — LAN IPv4 first (lowest latency when on same network),
25167
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
25168
- * race them with short timeouts and stick with the winner for the
25169
- * session.
25268
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
25269
+ * when on the same network), then public hostname (if a tunnel is
25270
+ * up). The SDK can race them with short timeouts and stick with the
25271
+ * winner for the session.
25170
25272
  *
25171
25273
  * Why hub-only: agents are not directly addressable by the operator's
25172
25274
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -25321,6 +25423,17 @@ var NotificationEndpointSchema = object({
25321
25423
  /** What the ranking currently resolves to (null when nothing is reachable). */
25322
25424
  resolved: string().nullable()
25323
25425
  });
25426
+ /**
25427
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
25428
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
25429
+ * currently expands to, so the UI can show the effective set either way.
25430
+ */
25431
+ var ViewerEndpointsSchema = object({
25432
+ /** The operator's explicit race set, or empty for AUTO. */
25433
+ baseUrls: array(string()).readonly(),
25434
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
25435
+ resolved: array(string()).readonly()
25436
+ });
25324
25437
  var AllowedAddressesSchema = object({
25325
25438
  /**
25326
25439
  * Allowlist of interface addresses operators have explicitly opted
@@ -25352,17 +25465,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
25352
25465
  */
25353
25466
  port: number().int().min(1).max(65535).optional(),
25354
25467
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
25355
- * candidate. Default `true`. */
25468
+ * candidate. Default `false` — loopback is not a client route. */
25356
25469
  includeLoopback: boolean().optional(),
25357
- /** Skip IPv6 entries. Some legacy clients can't parse them.
25358
- * Default `false`. */
25470
+ /** Skip IPv6 entries. Default `false` — the palette includes stable
25471
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
25472
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
25359
25473
  ipv4Only: boolean().optional(),
25360
25474
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
25361
25475
  * Pass `'https'` when the caller is itself loaded over HTTPS
25362
25476
  * to avoid mixed-content blocks in the browser. The public
25363
25477
  * tunnel always emits `https://` regardless. */
25364
25478
  scheme: _enum(["http", "https"]).optional()
25365
- }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
25479
+ }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
25366
25480
  kind: "mutation",
25367
25481
  auth: "admin"
25368
25482
  }), method(object({
@@ -33549,6 +33663,12 @@ Object.freeze({
33549
33663
  addonId: null,
33550
33664
  access: "view"
33551
33665
  },
33666
+ "localNetwork.getViewerEndpoints": {
33667
+ capName: "local-network",
33668
+ capScope: "system",
33669
+ addonId: null,
33670
+ access: "view"
33671
+ },
33552
33672
  "localNetwork.list": {
33553
33673
  capName: "local-network",
33554
33674
  capScope: "system",
@@ -33585,6 +33705,12 @@ Object.freeze({
33585
33705
  addonId: null,
33586
33706
  access: "create"
33587
33707
  },
33708
+ "localNetwork.setViewerEndpoints": {
33709
+ capName: "local-network",
33710
+ capScope: "system",
33711
+ addonId: null,
33712
+ access: "create"
33713
+ },
33588
33714
  "localNetwork.uploadCertificate": {
33589
33715
  capName: "local-network",
33590
33716
  capScope: "system",
@@ -8291,6 +8291,15 @@ var LabelDefinitionSchema = object({
8291
8291
  description: string().optional(),
8292
8292
  icon: string().optional()
8293
8293
  });
8294
+ var ClassMapDefinitionSchema = object({
8295
+ mapping: record(string(), _enum([
8296
+ "person",
8297
+ "vehicle",
8298
+ "animal",
8299
+ "package"
8300
+ ])),
8301
+ preserveOriginal: boolean()
8302
+ });
8294
8303
  var MODEL_FORMATS = [
8295
8304
  "onnx",
8296
8305
  "coreml",
@@ -8469,7 +8478,13 @@ var ModelCatalogEntrySchema = object({
8469
8478
  * `id` stays the source of truth for resolution/download/persistence; grouping
8470
8479
  * is a presentation overlay resolved back to an `id`.
8471
8480
  */
8472
- group: ModelVariantGroupSchema.optional()
8481
+ group: ModelVariantGroupSchema.optional(),
8482
+ /**
8483
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8484
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8485
+ * labels already ARE the CamStack macros (Scrypted identity map).
8486
+ */
8487
+ classMap: ClassMapDefinitionSchema.optional()
8473
8488
  });
8474
8489
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8475
8490
  format: literal("openvino"),
@@ -8498,7 +8513,8 @@ var ModelConvertMetadataSchema = object({
8498
8513
  "ocr",
8499
8514
  "segmentation"
8500
8515
  ]),
8501
- faceAlignment: boolean().optional()
8516
+ faceAlignment: boolean().optional(),
8517
+ classMap: ClassMapDefinitionSchema.optional()
8502
8518
  });
8503
8519
  var ConvertResultSchema = object({
8504
8520
  entry: ModelCatalogEntrySchema,
@@ -14994,12 +15010,15 @@ var NcOccupancyConditionSchema = object({
14994
15010
  * there is no second switch that can disagree with the first and every rule
14995
15011
  * authored before the decision migrates for free (`audioModeOf`):
14996
15012
  *
14997
- * - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
14998
- * classifier labels with one of them. No window, no percentage:
14999
- * `hitPercent` and `samplingSeconds` are ignored, and the rule's own
15000
- * `throttle` cooldown is the only brake. The per-label confidence floor is
15001
- * the analyzer's (`classificationMinScore`, per device) — a label only
15002
- * reaches this condition if the classifier was already confident enough.
15013
+ * - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
15014
+ * labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
15015
+ * `hitPercent` and `samplingSeconds` are still ignored — a percentage of
15016
+ * frames is the wrong question for a classifier that labels 1–3 frames
15017
+ * per episode. The count window is the brake that drops a single-frame
15018
+ * false positive; the rule's own `throttle` cooldown is the other. The
15019
+ * per-label confidence floor is the analyzer's (`classificationMinScore`,
15020
+ * per device) — a label only reaches this condition if the classifier was
15021
+ * already confident enough. `confirmHits: 1` restores first-frame fire.
15003
15022
  * - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
15004
15023
  * the condition: at least `hitPercent`% of the samples over
15005
15024
  * `samplingSeconds` must be at or above `dbThreshold` dBFS (see
@@ -15026,14 +15045,22 @@ var NcOccupancyConditionSchema = object({
15026
15045
  * an operator who typed `dog` mean the same thing.
15027
15046
  */
15028
15047
  var NcAudioConditionSchema = object({
15029
- /** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
15048
+ /** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
15030
15049
  labels: array(string().min(1)).min(1).optional(),
15031
15050
  /** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
15032
15051
  dbThreshold: number().min(-96).max(0).optional(),
15033
15052
  /** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
15034
15053
  hitPercent: number().int().min(1).max(100).default(60),
15035
15054
  /** LEVEL MODE ONLY: length of the sampling window in seconds. */
15036
- samplingSeconds: number().int().min(1).max(300).default(10)
15055
+ samplingSeconds: number().int().min(1).max(300).default(10),
15056
+ /**
15057
+ * LABEL MODE: how many labelled frames must land inside
15058
+ * {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
15059
+ * Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
15060
+ */
15061
+ confirmHits: number().int().min(1).max(20).optional(),
15062
+ /** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
15063
+ confirmWindowSec: number().int().min(1).max(60).optional()
15037
15064
  });
15038
15065
  /**
15039
15066
  * Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
@@ -18028,7 +18055,9 @@ var TrackCascadeCountsSchema = object({
18028
18055
  /** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
18029
18056
  plates: number().int(),
18030
18057
  /** Per-track CLIP search vectors removed (best-effort). */
18031
- embeddings: number().int()
18058
+ embeddings: number().int(),
18059
+ /** Group membership + group rows removed with their last member (best-effort). */
18060
+ groups: number().int()
18032
18061
  });
18033
18062
  /** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
18034
18063
  var DiskReconcileCountsSchema = object({
@@ -18793,6 +18822,33 @@ var NativeCropRefSchema = object({
18793
18822
  h: number()
18794
18823
  })
18795
18824
  });
18825
+ object({
18826
+ crop: object({
18827
+ left: number(),
18828
+ top: number(),
18829
+ width: number().positive(),
18830
+ height: number().positive()
18831
+ }).optional(),
18832
+ content: object({
18833
+ width: number().int().positive(),
18834
+ height: number().int().positive()
18835
+ }),
18836
+ fit: _enum(["stretch", "contain"]),
18837
+ format: _enum([
18838
+ "rgb",
18839
+ "gray",
18840
+ "jpeg"
18841
+ ])
18842
+ });
18843
+ var FrameRefSchema = object({
18844
+ registryId: string().min(1),
18845
+ id: string().min(1),
18846
+ width: number().int().positive(),
18847
+ height: number().int().positive(),
18848
+ format: _enum(["rgb", "gray"]),
18849
+ timestamp: number(),
18850
+ capturedAt: number().optional()
18851
+ });
18796
18852
  var ModelFormatSchema$1 = _enum([
18797
18853
  "onnx",
18798
18854
  "coreml",
@@ -19037,6 +19093,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
19037
19093
  steps: array(PipelineStepInputSchema).min(1),
19038
19094
  frame: FrameInputSchema.optional(),
19039
19095
  /**
19096
+ * Process-local lazy frame. Valid only when caller and provider resolve
19097
+ * in the same execution-group process; split/cross-node callers use
19098
+ * `frame`/`image` inline compatibility instead.
19099
+ */
19100
+ frameRef: FrameRefSchema.optional(),
19101
+ /**
19040
19102
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
19041
19103
  * the decoded pixels live in. One more member of the one-of
19042
19104
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -19332,7 +19394,10 @@ var NativeCropResultSchema = object({
19332
19394
  * Which source served this crop, so a quality-sensitive consumer (the native
19333
19395
  * `keyFrame`) can reject a degraded fallback:
19334
19396
  * - `native` — cut from the decode worker's retained NATIVE surface (the
19335
- * quality path).
19397
+ * quality path). A subject-tile serve is also native-resolution and stays
19398
+ * `native` here: the public enum cannot name `tile` without a breaking cap
19399
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
19400
+ * internal crop result (`nativeHits` vs `tileHits`).
19336
19401
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
19337
19402
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
19338
19403
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -19823,12 +19888,41 @@ var RunnerLocalLoadSchema = object({
19823
19888
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
19824
19889
  * working unchanged when they switch to reading from the runner cap.
19825
19890
  */
19891
+ var FrameLazyCountersSchema = object({
19892
+ framesDecoded: number(),
19893
+ framesAdmitted: number(),
19894
+ framesDroppedPixelFree: number(),
19895
+ viewsMaterialized: number(),
19896
+ viewsSkipped: number(),
19897
+ workerToRunnerBytes: number(),
19898
+ runnerToPoolRawBytes: number(),
19899
+ runnerToPoolJpegBytes: number(),
19900
+ onDemandFullFrameRequests: number(),
19901
+ onDemandCropRequests: number(),
19902
+ nativeHits: number(),
19903
+ nativeMisses: number(),
19904
+ tileHits: number(),
19905
+ tileMisses: number(),
19906
+ fallbackHits: number(),
19907
+ fallbackMisses: number(),
19908
+ retainedWritesAvoided: number(),
19909
+ residentRefs: number(),
19910
+ residentBytes: number(),
19911
+ releases: number(),
19912
+ evictions: number(),
19913
+ staleMisses: number()
19914
+ });
19915
+ var FrameLazyMetricsSchema = object({
19916
+ node: FrameLazyCountersSchema,
19917
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
19918
+ });
19826
19919
  var RunnerLocalMetricsSchema = object({
19827
19920
  nodeId: string(),
19828
19921
  activeCameras: number(),
19829
19922
  throttledCameras: number(),
19830
19923
  avgInferenceTimeMs: number(),
19831
- queueDepth: number()
19924
+ queueDepth: number(),
19925
+ frameLazy: FrameLazyMetricsSchema.optional()
19832
19926
  });
19833
19927
  method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mutation" }), method(object({ deviceId: number() }), object({ success: literal(true) }), { kind: "mutation" }), method(ReportMotionInputSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), RunnerLocalLoadSchema), method(_void(), RunnerLocalMetricsSchema), method(object({ deviceId: number() }), CameraMetricsSchema.nullable()), method(_void(), array(CameraMetricsWithDeviceIdSchema).readonly()), method(_void(), array(number()).readonly()), method(object({
19834
19928
  handle: FrameHandleSchema,
@@ -21158,6 +21252,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
21158
21252
  location: StorageLocationSchema,
21159
21253
  relativePath: string()
21160
21254
  }), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
21255
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
21256
+ var ProfileSettingsSchemaBridge = unknown().nullable();
21257
+ var ProfileSettingsBagSchema = record(string(), unknown());
21161
21258
  /**
21162
21259
  * A live terminal session hosted by the provider addon. Output and input do
21163
21260
  * NOT flow through the capability — they use the addon data plane
@@ -21192,7 +21289,9 @@ var TerminalProfileInfoSchema = object({
21192
21289
  executable: string().optional(),
21193
21290
  args: array(string()).readonly().optional(),
21194
21291
  cwd: string().optional(),
21195
- environment: array(string()).readonly().optional()
21292
+ environment: array(string()).readonly().optional(),
21293
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
21294
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
21196
21295
  });
21197
21296
  /**
21198
21297
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -21209,7 +21308,8 @@ var TerminalInstanceInfoSchema = object({
21209
21308
  executable: string(),
21210
21309
  args: array(string()).readonly(),
21211
21310
  cwd: string(),
21212
- environment: array(string()).readonly()
21311
+ environment: array(string()).readonly(),
21312
+ profileSettings: ProfileSettingsBagSchema
21213
21313
  });
21214
21314
  var TerminalLegacyCameraSchema = object({
21215
21315
  stableId: string(),
@@ -21243,7 +21343,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
21243
21343
  executable: string().max(1024).optional(),
21244
21344
  args: array(string().max(2048)).max(64).optional(),
21245
21345
  cwd: string().max(1024).optional(),
21246
- environment: array(string().max(4096)).max(64).optional()
21346
+ environment: array(string().max(4096)).max(64).optional(),
21347
+ profileSettings: ProfileSettingsBagSchema.optional()
21247
21348
  }), TerminalInstanceInfoSchema, {
21248
21349
  kind: "mutation",
21249
21350
  auth: "admin"
@@ -21253,7 +21354,8 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
21253
21354
  executable: string().max(1024).optional(),
21254
21355
  args: array(string().max(2048)).max(64).optional(),
21255
21356
  cwd: string().max(1024).optional(),
21256
- environment: array(string().max(4096)).max(64).optional()
21357
+ environment: array(string().max(4096)).max(64).optional(),
21358
+ profileSettings: ProfileSettingsBagSchema.optional()
21257
21359
  }), TerminalInstanceInfoSchema, {
21258
21360
  kind: "mutation",
21259
21361
  auth: "admin"
@@ -25194,10 +25296,10 @@ var lawnMowerControlCapability = {
25194
25296
  *
25195
25297
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
25196
25298
  * to receive an ordered list of candidate base URLs it should race
25197
- * on connect — LAN IPv4 first (lowest latency when on same network),
25198
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
25199
- * race them with short timeouts and stick with the winner for the
25200
- * session.
25299
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
25300
+ * when on the same network), then public hostname (if a tunnel is
25301
+ * up). The SDK can race them with short timeouts and stick with the
25302
+ * winner for the session.
25201
25303
  *
25202
25304
  * Why hub-only: agents are not directly addressable by the operator's
25203
25305
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -25352,6 +25454,17 @@ var NotificationEndpointSchema = object({
25352
25454
  /** What the ranking currently resolves to (null when nothing is reachable). */
25353
25455
  resolved: string().nullable()
25354
25456
  });
25457
+ /**
25458
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
25459
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
25460
+ * currently expands to, so the UI can show the effective set either way.
25461
+ */
25462
+ var ViewerEndpointsSchema = object({
25463
+ /** The operator's explicit race set, or empty for AUTO. */
25464
+ baseUrls: array(string()).readonly(),
25465
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
25466
+ resolved: array(string()).readonly()
25467
+ });
25355
25468
  var AllowedAddressesSchema = object({
25356
25469
  /**
25357
25470
  * Allowlist of interface addresses operators have explicitly opted
@@ -25383,17 +25496,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
25383
25496
  */
25384
25497
  port: number().int().min(1).max(65535).optional(),
25385
25498
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
25386
- * candidate. Default `true`. */
25499
+ * candidate. Default `false` — loopback is not a client route. */
25387
25500
  includeLoopback: boolean().optional(),
25388
- /** Skip IPv6 entries. Some legacy clients can't parse them.
25389
- * Default `false`. */
25501
+ /** Skip IPv6 entries. Default `false` — the palette includes stable
25502
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
25503
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
25390
25504
  ipv4Only: boolean().optional(),
25391
25505
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
25392
25506
  * Pass `'https'` when the caller is itself loaded over HTTPS
25393
25507
  * to avoid mixed-content blocks in the browser. The public
25394
25508
  * tunnel always emits `https://` regardless. */
25395
25509
  scheme: _enum(["http", "https"]).optional()
25396
- }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
25510
+ }), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
25397
25511
  kind: "mutation",
25398
25512
  auth: "admin"
25399
25513
  }), method(object({
@@ -33580,6 +33694,12 @@ Object.freeze({
33580
33694
  addonId: null,
33581
33695
  access: "view"
33582
33696
  },
33697
+ "localNetwork.getViewerEndpoints": {
33698
+ capName: "local-network",
33699
+ capScope: "system",
33700
+ addonId: null,
33701
+ access: "view"
33702
+ },
33583
33703
  "localNetwork.list": {
33584
33704
  capName: "local-network",
33585
33705
  capScope: "system",
@@ -33616,6 +33736,12 @@ Object.freeze({
33616
33736
  addonId: null,
33617
33737
  access: "create"
33618
33738
  },
33739
+ "localNetwork.setViewerEndpoints": {
33740
+ capName: "local-network",
33741
+ capScope: "system",
33742
+ addonId: null,
33743
+ access: "create"
33744
+ },
33619
33745
  "localNetwork.uploadCertificate": {
33620
33746
  capName: "local-network",
33621
33747
  capScope: "system",