@camstack/addon-provider-dreo 0.2.26 → 0.2.27

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 (3) hide show
  1. package/dist/addon.js +248 -16
  2. package/dist/addon.mjs +248 -16
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -8056,6 +8056,15 @@ var LabelDefinitionSchema = object({
8056
8056
  description: string().optional(),
8057
8057
  icon: string().optional()
8058
8058
  });
8059
+ var ClassMapDefinitionSchema = object({
8060
+ mapping: record(string(), _enum([
8061
+ "person",
8062
+ "vehicle",
8063
+ "animal",
8064
+ "package"
8065
+ ])),
8066
+ preserveOriginal: boolean()
8067
+ });
8059
8068
  var MODEL_FORMATS = [
8060
8069
  "onnx",
8061
8070
  "coreml",
@@ -8234,7 +8243,13 @@ var ModelCatalogEntrySchema = object({
8234
8243
  * `id` stays the source of truth for resolution/download/persistence; grouping
8235
8244
  * is a presentation overlay resolved back to an `id`.
8236
8245
  */
8237
- group: ModelVariantGroupSchema.optional()
8246
+ group: ModelVariantGroupSchema.optional(),
8247
+ /**
8248
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8249
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8250
+ * labels already ARE the CamStack macros (Scrypted identity map).
8251
+ */
8252
+ classMap: ClassMapDefinitionSchema.optional()
8238
8253
  });
8239
8254
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8240
8255
  format: literal("openvino"),
@@ -8263,7 +8278,8 @@ var ModelConvertMetadataSchema = object({
8263
8278
  "ocr",
8264
8279
  "segmentation"
8265
8280
  ]),
8266
- faceAlignment: boolean().optional()
8281
+ faceAlignment: boolean().optional(),
8282
+ classMap: ClassMapDefinitionSchema.optional()
8267
8283
  });
8268
8284
  var ConvertResultSchema = object({
8269
8285
  entry: ModelCatalogEntrySchema,
@@ -17573,6 +17589,33 @@ var NativeCropRefSchema = object({
17573
17589
  h: number()
17574
17590
  })
17575
17591
  });
17592
+ object({
17593
+ crop: object({
17594
+ left: number(),
17595
+ top: number(),
17596
+ width: number().positive(),
17597
+ height: number().positive()
17598
+ }).optional(),
17599
+ content: object({
17600
+ width: number().int().positive(),
17601
+ height: number().int().positive()
17602
+ }),
17603
+ fit: _enum(["stretch", "contain"]),
17604
+ format: _enum([
17605
+ "rgb",
17606
+ "gray",
17607
+ "jpeg"
17608
+ ])
17609
+ });
17610
+ var FrameRefSchema = object({
17611
+ registryId: string().min(1),
17612
+ id: string().min(1),
17613
+ width: number().int().positive(),
17614
+ height: number().int().positive(),
17615
+ format: _enum(["rgb", "gray"]),
17616
+ timestamp: number(),
17617
+ capturedAt: number().optional()
17618
+ });
17576
17619
  var ModelFormatSchema$1 = _enum([
17577
17620
  "onnx",
17578
17621
  "coreml",
@@ -17817,6 +17860,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17817
17860
  steps: array(PipelineStepInputSchema).min(1),
17818
17861
  frame: FrameInputSchema.optional(),
17819
17862
  /**
17863
+ * Process-local lazy frame. Valid only when caller and provider resolve
17864
+ * in the same execution-group process; split/cross-node callers use
17865
+ * `frame`/`image` inline compatibility instead.
17866
+ */
17867
+ frameRef: FrameRefSchema.optional(),
17868
+ /**
17820
17869
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17821
17870
  * the decoded pixels live in. One more member of the one-of
17822
17871
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18112,7 +18161,10 @@ var NativeCropResultSchema = object({
18112
18161
  * Which source served this crop, so a quality-sensitive consumer (the native
18113
18162
  * `keyFrame`) can reject a degraded fallback:
18114
18163
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18115
- * quality path).
18164
+ * quality path). A subject-tile serve is also native-resolution and stays
18165
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18166
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18167
+ * internal crop result (`nativeHits` vs `tileHits`).
18116
18168
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18117
18169
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18118
18170
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18603,12 +18655,41 @@ var RunnerLocalLoadSchema = object({
18603
18655
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18604
18656
  * working unchanged when they switch to reading from the runner cap.
18605
18657
  */
18658
+ var FrameLazyCountersSchema = object({
18659
+ framesDecoded: number(),
18660
+ framesAdmitted: number(),
18661
+ framesDroppedPixelFree: number(),
18662
+ viewsMaterialized: number(),
18663
+ viewsSkipped: number(),
18664
+ workerToRunnerBytes: number(),
18665
+ runnerToPoolRawBytes: number(),
18666
+ runnerToPoolJpegBytes: number(),
18667
+ onDemandFullFrameRequests: number(),
18668
+ onDemandCropRequests: number(),
18669
+ nativeHits: number(),
18670
+ nativeMisses: number(),
18671
+ tileHits: number(),
18672
+ tileMisses: number(),
18673
+ fallbackHits: number(),
18674
+ fallbackMisses: number(),
18675
+ retainedWritesAvoided: number(),
18676
+ residentRefs: number(),
18677
+ residentBytes: number(),
18678
+ releases: number(),
18679
+ evictions: number(),
18680
+ staleMisses: number()
18681
+ });
18682
+ var FrameLazyMetricsSchema = object({
18683
+ node: FrameLazyCountersSchema,
18684
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18685
+ });
18606
18686
  var RunnerLocalMetricsSchema = object({
18607
18687
  nodeId: string(),
18608
18688
  activeCameras: number(),
18609
18689
  throttledCameras: number(),
18610
18690
  avgInferenceTimeMs: number(),
18611
- queueDepth: number()
18691
+ queueDepth: number(),
18692
+ frameLazy: FrameLazyMetricsSchema.optional()
18612
18693
  });
18613
18694
  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({
18614
18695
  handle: FrameHandleSchema,
@@ -19908,6 +19989,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19908
19989
  location: StorageLocationSchema,
19909
19990
  relativePath: string()
19910
19991
  }), _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" });
19992
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19993
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19994
+ var ProfileSettingsBagSchema = record(string(), unknown());
19911
19995
  /**
19912
19996
  * A live terminal session hosted by the provider addon. Output and input do
19913
19997
  * NOT flow through the capability — they use the addon data plane
@@ -19937,7 +20021,14 @@ var TerminalSessionInfoSchema = object({
19937
20021
  var TerminalProfileInfoSchema = object({
19938
20022
  profileId: string(),
19939
20023
  label: string(),
19940
- description: string().optional()
20024
+ description: string().optional(),
20025
+ /** Spawn defaults the instance form copies on create. */
20026
+ executable: string().optional(),
20027
+ args: array(string()).readonly().optional(),
20028
+ cwd: string().optional(),
20029
+ environment: array(string()).readonly().optional(),
20030
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20031
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19941
20032
  });
19942
20033
  /**
19943
20034
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19950,7 +20041,12 @@ var TerminalInstanceInfoSchema = object({
19950
20041
  profileId: string(),
19951
20042
  profileLabel: string(),
19952
20043
  name: string(),
19953
- enabled: boolean()
20044
+ enabled: boolean(),
20045
+ executable: string(),
20046
+ args: array(string()).readonly(),
20047
+ cwd: string(),
20048
+ environment: array(string()).readonly(),
20049
+ profileSettings: ProfileSettingsBagSchema
19954
20050
  });
19955
20051
  var TerminalLegacyCameraSchema = object({
19956
20052
  stableId: string(),
@@ -19980,7 +20076,23 @@ var TerminalOutputBatchSchema = object({
19980
20076
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19981
20077
  targetNodeId: string().min(1),
19982
20078
  profileId: string().min(1),
19983
- name: string().trim().min(1).max(160).optional()
20079
+ name: string().trim().min(1).max(160).optional(),
20080
+ executable: string().max(1024).optional(),
20081
+ args: array(string().max(2048)).max(64).optional(),
20082
+ cwd: string().max(1024).optional(),
20083
+ environment: array(string().max(4096)).max(64).optional(),
20084
+ profileSettings: ProfileSettingsBagSchema.optional()
20085
+ }), TerminalInstanceInfoSchema, {
20086
+ kind: "mutation",
20087
+ auth: "admin"
20088
+ }), method(object({
20089
+ instanceId: string().min(1),
20090
+ name: string().trim().min(1).max(160).optional(),
20091
+ executable: string().max(1024).optional(),
20092
+ args: array(string().max(2048)).max(64).optional(),
20093
+ cwd: string().max(1024).optional(),
20094
+ environment: array(string().max(4096)).max(64).optional(),
20095
+ profileSettings: ProfileSettingsBagSchema.optional()
19984
20096
  }), TerminalInstanceInfoSchema, {
19985
20097
  kind: "mutation",
19986
20098
  auth: "admin"
@@ -20002,7 +20114,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20002
20114
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20003
20115
  profileId: string(),
20004
20116
  cols: number().int().positive(),
20005
- rows: number().int().positive()
20117
+ rows: number().int().positive(),
20118
+ executable: string().max(1024).optional(),
20119
+ args: array(string().max(2048)).max(64).optional(),
20120
+ cwd: string().max(1024).optional(),
20121
+ environment: array(string().max(4096)).max(64).optional()
20006
20122
  }), TerminalSessionInfoSchema, {
20007
20123
  kind: "mutation",
20008
20124
  auth: "admin"
@@ -23885,10 +24001,10 @@ var lawnMowerControlCapability = {
23885
24001
  *
23886
24002
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23887
24003
  * to receive an ordered list of candidate base URLs it should race
23888
- * on connect — LAN IPv4 first (lowest latency when on same network),
23889
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23890
- * race them with short timeouts and stick with the winner for the
23891
- * session.
24004
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24005
+ * when on the same network), then public hostname (if a tunnel is
24006
+ * up). The SDK can race them with short timeouts and stick with the
24007
+ * winner for the session.
23892
24008
  *
23893
24009
  * Why hub-only: agents are not directly addressable by the operator's
23894
24010
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24043,6 +24159,17 @@ var NotificationEndpointSchema = object({
24043
24159
  /** What the ranking currently resolves to (null when nothing is reachable). */
24044
24160
  resolved: string().nullable()
24045
24161
  });
24162
+ /**
24163
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24164
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24165
+ * currently expands to, so the UI can show the effective set either way.
24166
+ */
24167
+ var ViewerEndpointsSchema = object({
24168
+ /** The operator's explicit race set, or empty for AUTO. */
24169
+ baseUrls: array(string()).readonly(),
24170
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24171
+ resolved: array(string()).readonly()
24172
+ });
24046
24173
  var AllowedAddressesSchema = object({
24047
24174
  /**
24048
24175
  * Allowlist of interface addresses operators have explicitly opted
@@ -24051,6 +24178,20 @@ var AllowedAddressesSchema = object({
24051
24178
  * Network Addresses admin page and persisted by the addon.
24052
24179
  */
24053
24180
  addresses: array(string()).readonly() });
24181
+ var TlsStatusSchema = object({
24182
+ mode: _enum([
24183
+ "generated",
24184
+ "uploaded",
24185
+ "disabled"
24186
+ ]),
24187
+ leafFingerprintSha256: string().nullable(),
24188
+ caFingerprintSha256: string().nullable(),
24189
+ validTo: string().nullable(),
24190
+ sans: array(string()),
24191
+ caCertPem: string().nullable(),
24192
+ reissueError: string().nullable(),
24193
+ restartRequired: boolean()
24194
+ });
24054
24195
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24055
24196
  /**
24056
24197
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24060,17 +24201,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24060
24201
  */
24061
24202
  port: number().int().min(1).max(65535).optional(),
24062
24203
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24063
- * candidate. Default `true`. */
24204
+ * candidate. Default `false` — loopback is not a client route. */
24064
24205
  includeLoopback: boolean().optional(),
24065
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24066
- * Default `false`. */
24206
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24207
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24208
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24067
24209
  ipv4Only: boolean().optional(),
24068
24210
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24069
24211
  * Pass `'https'` when the caller is itself loaded over HTTPS
24070
24212
  * to avoid mixed-content blocks in the browser. The public
24071
24213
  * tunnel always emits `https://` regardless. */
24072
24214
  scheme: _enum(["http", "https"]).optional()
24073
- }), 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" });
24215
+ }), 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, {
24216
+ kind: "mutation",
24217
+ auth: "admin"
24218
+ }), method(object({
24219
+ certPem: string().min(1),
24220
+ keyPem: string().min(1),
24221
+ caPem: string().optional()
24222
+ }), TlsStatusSchema, {
24223
+ kind: "mutation",
24224
+ auth: "admin"
24225
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24226
+ kind: "mutation",
24227
+ auth: "admin"
24228
+ });
24074
24229
  var LockControlStatusSchema = object({
24075
24230
  /** Lifecycle state of the lock. `jammed` means the motor reported
24076
24231
  * failure to reach the target — operator intervention required. */
@@ -32097,6 +32252,12 @@ Object.freeze({
32097
32252
  addonId: null,
32098
32253
  access: "create"
32099
32254
  },
32255
+ "localNetwork.downloadCa": {
32256
+ capName: "local-network",
32257
+ capScope: "system",
32258
+ addonId: null,
32259
+ access: "view"
32260
+ },
32100
32261
  "localNetwork.getAllowedAddresses": {
32101
32262
  capName: "local-network",
32102
32263
  capScope: "system",
@@ -32121,18 +32282,42 @@ Object.freeze({
32121
32282
  addonId: null,
32122
32283
  access: "view"
32123
32284
  },
32285
+ "localNetwork.getTlsStatus": {
32286
+ capName: "local-network",
32287
+ capScope: "system",
32288
+ addonId: null,
32289
+ access: "view"
32290
+ },
32291
+ "localNetwork.getViewerEndpoints": {
32292
+ capName: "local-network",
32293
+ capScope: "system",
32294
+ addonId: null,
32295
+ access: "view"
32296
+ },
32124
32297
  "localNetwork.list": {
32125
32298
  capName: "local-network",
32126
32299
  capScope: "system",
32127
32300
  addonId: null,
32128
32301
  access: "view"
32129
32302
  },
32303
+ "localNetwork.regenerateCertificate": {
32304
+ capName: "local-network",
32305
+ capScope: "system",
32306
+ addonId: null,
32307
+ access: "create"
32308
+ },
32130
32309
  "localNetwork.resetAllowlistToBestMatch": {
32131
32310
  capName: "local-network",
32132
32311
  capScope: "system",
32133
32312
  addonId: null,
32134
32313
  access: "delete"
32135
32314
  },
32315
+ "localNetwork.revertToGeneratedCertificate": {
32316
+ capName: "local-network",
32317
+ capScope: "system",
32318
+ addonId: null,
32319
+ access: "create"
32320
+ },
32136
32321
  "localNetwork.setAllowedAddresses": {
32137
32322
  capName: "local-network",
32138
32323
  capScope: "system",
@@ -32145,6 +32330,18 @@ Object.freeze({
32145
32330
  addonId: null,
32146
32331
  access: "create"
32147
32332
  },
32333
+ "localNetwork.setViewerEndpoints": {
32334
+ capName: "local-network",
32335
+ capScope: "system",
32336
+ addonId: null,
32337
+ access: "create"
32338
+ },
32339
+ "localNetwork.uploadCertificate": {
32340
+ capName: "local-network",
32341
+ capScope: "system",
32342
+ addonId: null,
32343
+ access: "create"
32344
+ },
32148
32345
  "lockControl.lock": {
32149
32346
  capName: "lock-control",
32150
32347
  capScope: "device",
@@ -35025,6 +35222,12 @@ Object.freeze({
35025
35222
  addonId: null,
35026
35223
  access: "create"
35027
35224
  },
35225
+ "terminalSession.updateInstance": {
35226
+ capName: "terminal-session",
35227
+ capScope: "system",
35228
+ addonId: null,
35229
+ access: "create"
35230
+ },
35028
35231
  "terminalSession.writeInput": {
35029
35232
  capName: "terminal-session",
35030
35233
  capScope: "system",
@@ -37512,6 +37715,35 @@ Object.freeze(Object.fromEntries([{
37512
37715
  }]
37513
37716
  }].map((s) => [s.stepId, s.defaultModelId])));
37514
37717
  string().min(1);
37718
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37719
+ stepId: "face-embedding",
37720
+ key: "minLandmarkFaceSize",
37721
+ label: "Min face size for recognition (detection px)",
37722
+ description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
37723
+ type: "slider",
37724
+ min: 0,
37725
+ max: 64,
37726
+ step: 2,
37727
+ default: 24
37728
+ }];
37729
+ function clusterStepSettingKey(stepId, fieldKey) {
37730
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37731
+ }
37732
+ var ClusterSettingNumberSchema = number().finite();
37733
+ function readClusterStepSettings(config) {
37734
+ const out = {};
37735
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37736
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37737
+ const value = parsed.success ? parsed.data : field.default;
37738
+ const existing = out[field.stepId] ?? {};
37739
+ out[field.stepId] = {
37740
+ ...existing,
37741
+ [field.key]: value
37742
+ };
37743
+ }
37744
+ return out;
37745
+ }
37746
+ readClusterStepSettings({});
37515
37747
  object({
37516
37748
  /**
37517
37749
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -8057,6 +8057,15 @@ var LabelDefinitionSchema = object({
8057
8057
  description: string().optional(),
8058
8058
  icon: string().optional()
8059
8059
  });
8060
+ var ClassMapDefinitionSchema = object({
8061
+ mapping: record(string(), _enum([
8062
+ "person",
8063
+ "vehicle",
8064
+ "animal",
8065
+ "package"
8066
+ ])),
8067
+ preserveOriginal: boolean()
8068
+ });
8060
8069
  var MODEL_FORMATS = [
8061
8070
  "onnx",
8062
8071
  "coreml",
@@ -8235,7 +8244,13 @@ var ModelCatalogEntrySchema = object({
8235
8244
  * `id` stays the source of truth for resolution/download/persistence; grouping
8236
8245
  * is a presentation overlay resolved back to an `id`.
8237
8246
  */
8238
- group: ModelVariantGroupSchema.optional()
8247
+ group: ModelVariantGroupSchema.optional(),
8248
+ /**
8249
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8250
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8251
+ * labels already ARE the CamStack macros (Scrypted identity map).
8252
+ */
8253
+ classMap: ClassMapDefinitionSchema.optional()
8239
8254
  });
8240
8255
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8241
8256
  format: literal("openvino"),
@@ -8264,7 +8279,8 @@ var ModelConvertMetadataSchema = object({
8264
8279
  "ocr",
8265
8280
  "segmentation"
8266
8281
  ]),
8267
- faceAlignment: boolean().optional()
8282
+ faceAlignment: boolean().optional(),
8283
+ classMap: ClassMapDefinitionSchema.optional()
8268
8284
  });
8269
8285
  var ConvertResultSchema = object({
8270
8286
  entry: ModelCatalogEntrySchema,
@@ -17574,6 +17590,33 @@ var NativeCropRefSchema = object({
17574
17590
  h: number()
17575
17591
  })
17576
17592
  });
17593
+ object({
17594
+ crop: object({
17595
+ left: number(),
17596
+ top: number(),
17597
+ width: number().positive(),
17598
+ height: number().positive()
17599
+ }).optional(),
17600
+ content: object({
17601
+ width: number().int().positive(),
17602
+ height: number().int().positive()
17603
+ }),
17604
+ fit: _enum(["stretch", "contain"]),
17605
+ format: _enum([
17606
+ "rgb",
17607
+ "gray",
17608
+ "jpeg"
17609
+ ])
17610
+ });
17611
+ var FrameRefSchema = object({
17612
+ registryId: string().min(1),
17613
+ id: string().min(1),
17614
+ width: number().int().positive(),
17615
+ height: number().int().positive(),
17616
+ format: _enum(["rgb", "gray"]),
17617
+ timestamp: number(),
17618
+ capturedAt: number().optional()
17619
+ });
17577
17620
  var ModelFormatSchema$1 = _enum([
17578
17621
  "onnx",
17579
17622
  "coreml",
@@ -17818,6 +17861,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17818
17861
  steps: array(PipelineStepInputSchema).min(1),
17819
17862
  frame: FrameInputSchema.optional(),
17820
17863
  /**
17864
+ * Process-local lazy frame. Valid only when caller and provider resolve
17865
+ * in the same execution-group process; split/cross-node callers use
17866
+ * `frame`/`image` inline compatibility instead.
17867
+ */
17868
+ frameRef: FrameRefSchema.optional(),
17869
+ /**
17821
17870
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17822
17871
  * the decoded pixels live in. One more member of the one-of
17823
17872
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18113,7 +18162,10 @@ var NativeCropResultSchema = object({
18113
18162
  * Which source served this crop, so a quality-sensitive consumer (the native
18114
18163
  * `keyFrame`) can reject a degraded fallback:
18115
18164
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18116
- * quality path).
18165
+ * quality path). A subject-tile serve is also native-resolution and stays
18166
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18167
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18168
+ * internal crop result (`nativeHits` vs `tileHits`).
18117
18169
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18118
18170
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18119
18171
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18604,12 +18656,41 @@ var RunnerLocalLoadSchema = object({
18604
18656
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18605
18657
  * working unchanged when they switch to reading from the runner cap.
18606
18658
  */
18659
+ var FrameLazyCountersSchema = object({
18660
+ framesDecoded: number(),
18661
+ framesAdmitted: number(),
18662
+ framesDroppedPixelFree: number(),
18663
+ viewsMaterialized: number(),
18664
+ viewsSkipped: number(),
18665
+ workerToRunnerBytes: number(),
18666
+ runnerToPoolRawBytes: number(),
18667
+ runnerToPoolJpegBytes: number(),
18668
+ onDemandFullFrameRequests: number(),
18669
+ onDemandCropRequests: number(),
18670
+ nativeHits: number(),
18671
+ nativeMisses: number(),
18672
+ tileHits: number(),
18673
+ tileMisses: number(),
18674
+ fallbackHits: number(),
18675
+ fallbackMisses: number(),
18676
+ retainedWritesAvoided: number(),
18677
+ residentRefs: number(),
18678
+ residentBytes: number(),
18679
+ releases: number(),
18680
+ evictions: number(),
18681
+ staleMisses: number()
18682
+ });
18683
+ var FrameLazyMetricsSchema = object({
18684
+ node: FrameLazyCountersSchema,
18685
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18686
+ });
18607
18687
  var RunnerLocalMetricsSchema = object({
18608
18688
  nodeId: string(),
18609
18689
  activeCameras: number(),
18610
18690
  throttledCameras: number(),
18611
18691
  avgInferenceTimeMs: number(),
18612
- queueDepth: number()
18692
+ queueDepth: number(),
18693
+ frameLazy: FrameLazyMetricsSchema.optional()
18613
18694
  });
18614
18695
  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({
18615
18696
  handle: FrameHandleSchema,
@@ -19909,6 +19990,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19909
19990
  location: StorageLocationSchema,
19910
19991
  relativePath: string()
19911
19992
  }), _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" });
19993
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
19994
+ var ProfileSettingsSchemaBridge = unknown().nullable();
19995
+ var ProfileSettingsBagSchema = record(string(), unknown());
19912
19996
  /**
19913
19997
  * A live terminal session hosted by the provider addon. Output and input do
19914
19998
  * NOT flow through the capability — they use the addon data plane
@@ -19938,7 +20022,14 @@ var TerminalSessionInfoSchema = object({
19938
20022
  var TerminalProfileInfoSchema = object({
19939
20023
  profileId: string(),
19940
20024
  label: string(),
19941
- description: string().optional()
20025
+ description: string().optional(),
20026
+ /** Spawn defaults the instance form copies on create. */
20027
+ executable: string().optional(),
20028
+ args: array(string()).readonly().optional(),
20029
+ cwd: string().optional(),
20030
+ environment: array(string()).readonly().optional(),
20031
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20032
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19942
20033
  });
19943
20034
  /**
19944
20035
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19951,7 +20042,12 @@ var TerminalInstanceInfoSchema = object({
19951
20042
  profileId: string(),
19952
20043
  profileLabel: string(),
19953
20044
  name: string(),
19954
- enabled: boolean()
20045
+ enabled: boolean(),
20046
+ executable: string(),
20047
+ args: array(string()).readonly(),
20048
+ cwd: string(),
20049
+ environment: array(string()).readonly(),
20050
+ profileSettings: ProfileSettingsBagSchema
19955
20051
  });
19956
20052
  var TerminalLegacyCameraSchema = object({
19957
20053
  stableId: string(),
@@ -19981,7 +20077,23 @@ var TerminalOutputBatchSchema = object({
19981
20077
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
19982
20078
  targetNodeId: string().min(1),
19983
20079
  profileId: string().min(1),
19984
- name: string().trim().min(1).max(160).optional()
20080
+ name: string().trim().min(1).max(160).optional(),
20081
+ executable: string().max(1024).optional(),
20082
+ args: array(string().max(2048)).max(64).optional(),
20083
+ cwd: string().max(1024).optional(),
20084
+ environment: array(string().max(4096)).max(64).optional(),
20085
+ profileSettings: ProfileSettingsBagSchema.optional()
20086
+ }), TerminalInstanceInfoSchema, {
20087
+ kind: "mutation",
20088
+ auth: "admin"
20089
+ }), method(object({
20090
+ instanceId: string().min(1),
20091
+ name: string().trim().min(1).max(160).optional(),
20092
+ executable: string().max(1024).optional(),
20093
+ args: array(string().max(2048)).max(64).optional(),
20094
+ cwd: string().max(1024).optional(),
20095
+ environment: array(string().max(4096)).max(64).optional(),
20096
+ profileSettings: ProfileSettingsBagSchema.optional()
19985
20097
  }), TerminalInstanceInfoSchema, {
19986
20098
  kind: "mutation",
19987
20099
  auth: "admin"
@@ -20003,7 +20115,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20003
20115
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20004
20116
  profileId: string(),
20005
20117
  cols: number().int().positive(),
20006
- rows: number().int().positive()
20118
+ rows: number().int().positive(),
20119
+ executable: string().max(1024).optional(),
20120
+ args: array(string().max(2048)).max(64).optional(),
20121
+ cwd: string().max(1024).optional(),
20122
+ environment: array(string().max(4096)).max(64).optional()
20007
20123
  }), TerminalSessionInfoSchema, {
20008
20124
  kind: "mutation",
20009
20125
  auth: "admin"
@@ -23886,10 +24002,10 @@ var lawnMowerControlCapability = {
23886
24002
  *
23887
24003
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23888
24004
  * to receive an ordered list of candidate base URLs it should race
23889
- * on connect — LAN IPv4 first (lowest latency when on same network),
23890
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23891
- * race them with short timeouts and stick with the winner for the
23892
- * session.
24005
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24006
+ * when on the same network), then public hostname (if a tunnel is
24007
+ * up). The SDK can race them with short timeouts and stick with the
24008
+ * winner for the session.
23893
24009
  *
23894
24010
  * Why hub-only: agents are not directly addressable by the operator's
23895
24011
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24044,6 +24160,17 @@ var NotificationEndpointSchema = object({
24044
24160
  /** What the ranking currently resolves to (null when nothing is reachable). */
24045
24161
  resolved: string().nullable()
24046
24162
  });
24163
+ /**
24164
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24165
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24166
+ * currently expands to, so the UI can show the effective set either way.
24167
+ */
24168
+ var ViewerEndpointsSchema = object({
24169
+ /** The operator's explicit race set, or empty for AUTO. */
24170
+ baseUrls: array(string()).readonly(),
24171
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24172
+ resolved: array(string()).readonly()
24173
+ });
24047
24174
  var AllowedAddressesSchema = object({
24048
24175
  /**
24049
24176
  * Allowlist of interface addresses operators have explicitly opted
@@ -24052,6 +24179,20 @@ var AllowedAddressesSchema = object({
24052
24179
  * Network Addresses admin page and persisted by the addon.
24053
24180
  */
24054
24181
  addresses: array(string()).readonly() });
24182
+ var TlsStatusSchema = object({
24183
+ mode: _enum([
24184
+ "generated",
24185
+ "uploaded",
24186
+ "disabled"
24187
+ ]),
24188
+ leafFingerprintSha256: string().nullable(),
24189
+ caFingerprintSha256: string().nullable(),
24190
+ validTo: string().nullable(),
24191
+ sans: array(string()),
24192
+ caCertPem: string().nullable(),
24193
+ reissueError: string().nullable(),
24194
+ restartRequired: boolean()
24195
+ });
24055
24196
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24056
24197
  /**
24057
24198
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24061,17 +24202,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24061
24202
  */
24062
24203
  port: number().int().min(1).max(65535).optional(),
24063
24204
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24064
- * candidate. Default `true`. */
24205
+ * candidate. Default `false` — loopback is not a client route. */
24065
24206
  includeLoopback: boolean().optional(),
24066
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24067
- * Default `false`. */
24207
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24208
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24209
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24068
24210
  ipv4Only: boolean().optional(),
24069
24211
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24070
24212
  * Pass `'https'` when the caller is itself loaded over HTTPS
24071
24213
  * to avoid mixed-content blocks in the browser. The public
24072
24214
  * tunnel always emits `https://` regardless. */
24073
24215
  scheme: _enum(["http", "https"]).optional()
24074
- }), 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" });
24216
+ }), 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, {
24217
+ kind: "mutation",
24218
+ auth: "admin"
24219
+ }), method(object({
24220
+ certPem: string().min(1),
24221
+ keyPem: string().min(1),
24222
+ caPem: string().optional()
24223
+ }), TlsStatusSchema, {
24224
+ kind: "mutation",
24225
+ auth: "admin"
24226
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24227
+ kind: "mutation",
24228
+ auth: "admin"
24229
+ });
24075
24230
  var LockControlStatusSchema = object({
24076
24231
  /** Lifecycle state of the lock. `jammed` means the motor reported
24077
24232
  * failure to reach the target — operator intervention required. */
@@ -32098,6 +32253,12 @@ Object.freeze({
32098
32253
  addonId: null,
32099
32254
  access: "create"
32100
32255
  },
32256
+ "localNetwork.downloadCa": {
32257
+ capName: "local-network",
32258
+ capScope: "system",
32259
+ addonId: null,
32260
+ access: "view"
32261
+ },
32101
32262
  "localNetwork.getAllowedAddresses": {
32102
32263
  capName: "local-network",
32103
32264
  capScope: "system",
@@ -32122,18 +32283,42 @@ Object.freeze({
32122
32283
  addonId: null,
32123
32284
  access: "view"
32124
32285
  },
32286
+ "localNetwork.getTlsStatus": {
32287
+ capName: "local-network",
32288
+ capScope: "system",
32289
+ addonId: null,
32290
+ access: "view"
32291
+ },
32292
+ "localNetwork.getViewerEndpoints": {
32293
+ capName: "local-network",
32294
+ capScope: "system",
32295
+ addonId: null,
32296
+ access: "view"
32297
+ },
32125
32298
  "localNetwork.list": {
32126
32299
  capName: "local-network",
32127
32300
  capScope: "system",
32128
32301
  addonId: null,
32129
32302
  access: "view"
32130
32303
  },
32304
+ "localNetwork.regenerateCertificate": {
32305
+ capName: "local-network",
32306
+ capScope: "system",
32307
+ addonId: null,
32308
+ access: "create"
32309
+ },
32131
32310
  "localNetwork.resetAllowlistToBestMatch": {
32132
32311
  capName: "local-network",
32133
32312
  capScope: "system",
32134
32313
  addonId: null,
32135
32314
  access: "delete"
32136
32315
  },
32316
+ "localNetwork.revertToGeneratedCertificate": {
32317
+ capName: "local-network",
32318
+ capScope: "system",
32319
+ addonId: null,
32320
+ access: "create"
32321
+ },
32137
32322
  "localNetwork.setAllowedAddresses": {
32138
32323
  capName: "local-network",
32139
32324
  capScope: "system",
@@ -32146,6 +32331,18 @@ Object.freeze({
32146
32331
  addonId: null,
32147
32332
  access: "create"
32148
32333
  },
32334
+ "localNetwork.setViewerEndpoints": {
32335
+ capName: "local-network",
32336
+ capScope: "system",
32337
+ addonId: null,
32338
+ access: "create"
32339
+ },
32340
+ "localNetwork.uploadCertificate": {
32341
+ capName: "local-network",
32342
+ capScope: "system",
32343
+ addonId: null,
32344
+ access: "create"
32345
+ },
32149
32346
  "lockControl.lock": {
32150
32347
  capName: "lock-control",
32151
32348
  capScope: "device",
@@ -35026,6 +35223,12 @@ Object.freeze({
35026
35223
  addonId: null,
35027
35224
  access: "create"
35028
35225
  },
35226
+ "terminalSession.updateInstance": {
35227
+ capName: "terminal-session",
35228
+ capScope: "system",
35229
+ addonId: null,
35230
+ access: "create"
35231
+ },
35029
35232
  "terminalSession.writeInput": {
35030
35233
  capName: "terminal-session",
35031
35234
  capScope: "system",
@@ -37513,6 +37716,35 @@ Object.freeze(Object.fromEntries([{
37513
37716
  }]
37514
37717
  }].map((s) => [s.stepId, s.defaultModelId])));
37515
37718
  string().min(1);
37719
+ var CLUSTER_STEP_SETTING_FIELDS = [{
37720
+ stepId: "face-embedding",
37721
+ key: "minLandmarkFaceSize",
37722
+ label: "Min face size for recognition (detection px)",
37723
+ description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
37724
+ type: "slider",
37725
+ min: 0,
37726
+ max: 64,
37727
+ step: 2,
37728
+ default: 24
37729
+ }];
37730
+ function clusterStepSettingKey(stepId, fieldKey) {
37731
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
37732
+ }
37733
+ var ClusterSettingNumberSchema = number().finite();
37734
+ function readClusterStepSettings(config) {
37735
+ const out = {};
37736
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
37737
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
37738
+ const value = parsed.success ? parsed.data : field.default;
37739
+ const existing = out[field.stepId] ?? {};
37740
+ out[field.stepId] = {
37741
+ ...existing,
37742
+ [field.key]: value
37743
+ };
37744
+ }
37745
+ return out;
37746
+ }
37747
+ readClusterStepSettings({});
37516
37748
  object({
37517
37749
  /**
37518
37750
  * Fraction of the box's own size added on EACH side before cutting.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-dreo",
3
- "version": "0.2.26",
3
+ "version": "0.2.27",
4
4
  "description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
5
5
  "keywords": [
6
6
  "camstack",