@camstack/addon-provider-amcrest 0.2.27 → 0.2.28

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
@@ -8013,6 +8013,15 @@ var LabelDefinitionSchema = object({
8013
8013
  description: string().optional(),
8014
8014
  icon: string().optional()
8015
8015
  });
8016
+ var ClassMapDefinitionSchema = object({
8017
+ mapping: record(string(), _enum([
8018
+ "person",
8019
+ "vehicle",
8020
+ "animal",
8021
+ "package"
8022
+ ])),
8023
+ preserveOriginal: boolean()
8024
+ });
8016
8025
  var MODEL_FORMATS = [
8017
8026
  "onnx",
8018
8027
  "coreml",
@@ -8191,7 +8200,13 @@ var ModelCatalogEntrySchema = object({
8191
8200
  * `id` stays the source of truth for resolution/download/persistence; grouping
8192
8201
  * is a presentation overlay resolved back to an `id`.
8193
8202
  */
8194
- group: ModelVariantGroupSchema.optional()
8203
+ group: ModelVariantGroupSchema.optional(),
8204
+ /**
8205
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8206
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8207
+ * labels already ARE the CamStack macros (Scrypted identity map).
8208
+ */
8209
+ classMap: ClassMapDefinitionSchema.optional()
8195
8210
  });
8196
8211
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8197
8212
  format: literal("openvino"),
@@ -8220,7 +8235,8 @@ var ModelConvertMetadataSchema = object({
8220
8235
  "ocr",
8221
8236
  "segmentation"
8222
8237
  ]),
8223
- faceAlignment: boolean().optional()
8238
+ faceAlignment: boolean().optional(),
8239
+ classMap: ClassMapDefinitionSchema.optional()
8224
8240
  });
8225
8241
  var ConvertResultSchema = object({
8226
8242
  entry: ModelCatalogEntrySchema,
@@ -17513,6 +17529,33 @@ var NativeCropRefSchema = object({
17513
17529
  h: number()
17514
17530
  })
17515
17531
  });
17532
+ object({
17533
+ crop: object({
17534
+ left: number(),
17535
+ top: number(),
17536
+ width: number().positive(),
17537
+ height: number().positive()
17538
+ }).optional(),
17539
+ content: object({
17540
+ width: number().int().positive(),
17541
+ height: number().int().positive()
17542
+ }),
17543
+ fit: _enum(["stretch", "contain"]),
17544
+ format: _enum([
17545
+ "rgb",
17546
+ "gray",
17547
+ "jpeg"
17548
+ ])
17549
+ });
17550
+ var FrameRefSchema = object({
17551
+ registryId: string().min(1),
17552
+ id: string().min(1),
17553
+ width: number().int().positive(),
17554
+ height: number().int().positive(),
17555
+ format: _enum(["rgb", "gray"]),
17556
+ timestamp: number(),
17557
+ capturedAt: number().optional()
17558
+ });
17516
17559
  var ModelFormatSchema$1 = _enum([
17517
17560
  "onnx",
17518
17561
  "coreml",
@@ -17757,6 +17800,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17757
17800
  steps: array(PipelineStepInputSchema).min(1),
17758
17801
  frame: FrameInputSchema.optional(),
17759
17802
  /**
17803
+ * Process-local lazy frame. Valid only when caller and provider resolve
17804
+ * in the same execution-group process; split/cross-node callers use
17805
+ * `frame`/`image` inline compatibility instead.
17806
+ */
17807
+ frameRef: FrameRefSchema.optional(),
17808
+ /**
17760
17809
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17761
17810
  * the decoded pixels live in. One more member of the one-of
17762
17811
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18052,7 +18101,10 @@ var NativeCropResultSchema = object({
18052
18101
  * Which source served this crop, so a quality-sensitive consumer (the native
18053
18102
  * `keyFrame`) can reject a degraded fallback:
18054
18103
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18055
- * quality path).
18104
+ * quality path). A subject-tile serve is also native-resolution and stays
18105
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18106
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18107
+ * internal crop result (`nativeHits` vs `tileHits`).
18056
18108
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18057
18109
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18058
18110
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18543,12 +18595,41 @@ var RunnerLocalLoadSchema = object({
18543
18595
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18544
18596
  * working unchanged when they switch to reading from the runner cap.
18545
18597
  */
18598
+ var FrameLazyCountersSchema = object({
18599
+ framesDecoded: number(),
18600
+ framesAdmitted: number(),
18601
+ framesDroppedPixelFree: number(),
18602
+ viewsMaterialized: number(),
18603
+ viewsSkipped: number(),
18604
+ workerToRunnerBytes: number(),
18605
+ runnerToPoolRawBytes: number(),
18606
+ runnerToPoolJpegBytes: number(),
18607
+ onDemandFullFrameRequests: number(),
18608
+ onDemandCropRequests: number(),
18609
+ nativeHits: number(),
18610
+ nativeMisses: number(),
18611
+ tileHits: number(),
18612
+ tileMisses: number(),
18613
+ fallbackHits: number(),
18614
+ fallbackMisses: number(),
18615
+ retainedWritesAvoided: number(),
18616
+ residentRefs: number(),
18617
+ residentBytes: number(),
18618
+ releases: number(),
18619
+ evictions: number(),
18620
+ staleMisses: number()
18621
+ });
18622
+ var FrameLazyMetricsSchema = object({
18623
+ node: FrameLazyCountersSchema,
18624
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18625
+ });
18546
18626
  var RunnerLocalMetricsSchema = object({
18547
18627
  nodeId: string(),
18548
18628
  activeCameras: number(),
18549
18629
  throttledCameras: number(),
18550
18630
  avgInferenceTimeMs: number(),
18551
- queueDepth: number()
18631
+ queueDepth: number(),
18632
+ frameLazy: FrameLazyMetricsSchema.optional()
18552
18633
  });
18553
18634
  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({
18554
18635
  handle: FrameHandleSchema,
@@ -19952,6 +20033,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19952
20033
  location: StorageLocationSchema,
19953
20034
  relativePath: string()
19954
20035
  }), _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" });
20036
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20037
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20038
+ var ProfileSettingsBagSchema = record(string(), unknown());
19955
20039
  /**
19956
20040
  * A live terminal session hosted by the provider addon. Output and input do
19957
20041
  * NOT flow through the capability — they use the addon data plane
@@ -19981,7 +20065,14 @@ var TerminalSessionInfoSchema = object({
19981
20065
  var TerminalProfileInfoSchema = object({
19982
20066
  profileId: string(),
19983
20067
  label: string(),
19984
- description: string().optional()
20068
+ description: string().optional(),
20069
+ /** Spawn defaults the instance form copies on create. */
20070
+ executable: string().optional(),
20071
+ args: array(string()).readonly().optional(),
20072
+ cwd: string().optional(),
20073
+ environment: array(string()).readonly().optional(),
20074
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20075
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19985
20076
  });
19986
20077
  /**
19987
20078
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19994,7 +20085,12 @@ var TerminalInstanceInfoSchema = object({
19994
20085
  profileId: string(),
19995
20086
  profileLabel: string(),
19996
20087
  name: string(),
19997
- enabled: boolean()
20088
+ enabled: boolean(),
20089
+ executable: string(),
20090
+ args: array(string()).readonly(),
20091
+ cwd: string(),
20092
+ environment: array(string()).readonly(),
20093
+ profileSettings: ProfileSettingsBagSchema
19998
20094
  });
19999
20095
  var TerminalLegacyCameraSchema = object({
20000
20096
  stableId: string(),
@@ -20024,7 +20120,23 @@ var TerminalOutputBatchSchema = object({
20024
20120
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20025
20121
  targetNodeId: string().min(1),
20026
20122
  profileId: string().min(1),
20027
- name: string().trim().min(1).max(160).optional()
20123
+ name: string().trim().min(1).max(160).optional(),
20124
+ executable: string().max(1024).optional(),
20125
+ args: array(string().max(2048)).max(64).optional(),
20126
+ cwd: string().max(1024).optional(),
20127
+ environment: array(string().max(4096)).max(64).optional(),
20128
+ profileSettings: ProfileSettingsBagSchema.optional()
20129
+ }), TerminalInstanceInfoSchema, {
20130
+ kind: "mutation",
20131
+ auth: "admin"
20132
+ }), method(object({
20133
+ instanceId: string().min(1),
20134
+ name: string().trim().min(1).max(160).optional(),
20135
+ executable: string().max(1024).optional(),
20136
+ args: array(string().max(2048)).max(64).optional(),
20137
+ cwd: string().max(1024).optional(),
20138
+ environment: array(string().max(4096)).max(64).optional(),
20139
+ profileSettings: ProfileSettingsBagSchema.optional()
20028
20140
  }), TerminalInstanceInfoSchema, {
20029
20141
  kind: "mutation",
20030
20142
  auth: "admin"
@@ -20046,7 +20158,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20046
20158
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20047
20159
  profileId: string(),
20048
20160
  cols: number().int().positive(),
20049
- rows: number().int().positive()
20161
+ rows: number().int().positive(),
20162
+ executable: string().max(1024).optional(),
20163
+ args: array(string().max(2048)).max(64).optional(),
20164
+ cwd: string().max(1024).optional(),
20165
+ environment: array(string().max(4096)).max(64).optional()
20050
20166
  }), TerminalSessionInfoSchema, {
20051
20167
  kind: "mutation",
20052
20168
  auth: "admin"
@@ -23921,10 +24037,10 @@ var lawnMowerControlCapability = {
23921
24037
  *
23922
24038
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23923
24039
  * to receive an ordered list of candidate base URLs it should race
23924
- * on connect — LAN IPv4 first (lowest latency when on same network),
23925
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23926
- * race them with short timeouts and stick with the winner for the
23927
- * session.
24040
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24041
+ * when on the same network), then public hostname (if a tunnel is
24042
+ * up). The SDK can race them with short timeouts and stick with the
24043
+ * winner for the session.
23928
24044
  *
23929
24045
  * Why hub-only: agents are not directly addressable by the operator's
23930
24046
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24079,6 +24195,17 @@ var NotificationEndpointSchema = object({
24079
24195
  /** What the ranking currently resolves to (null when nothing is reachable). */
24080
24196
  resolved: string().nullable()
24081
24197
  });
24198
+ /**
24199
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24200
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24201
+ * currently expands to, so the UI can show the effective set either way.
24202
+ */
24203
+ var ViewerEndpointsSchema = object({
24204
+ /** The operator's explicit race set, or empty for AUTO. */
24205
+ baseUrls: array(string()).readonly(),
24206
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24207
+ resolved: array(string()).readonly()
24208
+ });
24082
24209
  var AllowedAddressesSchema = object({
24083
24210
  /**
24084
24211
  * Allowlist of interface addresses operators have explicitly opted
@@ -24087,6 +24214,20 @@ var AllowedAddressesSchema = object({
24087
24214
  * Network Addresses admin page and persisted by the addon.
24088
24215
  */
24089
24216
  addresses: array(string()).readonly() });
24217
+ var TlsStatusSchema = object({
24218
+ mode: _enum([
24219
+ "generated",
24220
+ "uploaded",
24221
+ "disabled"
24222
+ ]),
24223
+ leafFingerprintSha256: string().nullable(),
24224
+ caFingerprintSha256: string().nullable(),
24225
+ validTo: string().nullable(),
24226
+ sans: array(string()),
24227
+ caCertPem: string().nullable(),
24228
+ reissueError: string().nullable(),
24229
+ restartRequired: boolean()
24230
+ });
24090
24231
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24091
24232
  /**
24092
24233
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24096,17 +24237,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24096
24237
  */
24097
24238
  port: number().int().min(1).max(65535).optional(),
24098
24239
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24099
- * candidate. Default `true`. */
24240
+ * candidate. Default `false` — loopback is not a client route. */
24100
24241
  includeLoopback: boolean().optional(),
24101
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24102
- * Default `false`. */
24242
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24243
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24244
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24103
24245
  ipv4Only: boolean().optional(),
24104
24246
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24105
24247
  * Pass `'https'` when the caller is itself loaded over HTTPS
24106
24248
  * to avoid mixed-content blocks in the browser. The public
24107
24249
  * tunnel always emits `https://` regardless. */
24108
24250
  scheme: _enum(["http", "https"]).optional()
24109
- }), 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" });
24251
+ }), 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, {
24252
+ kind: "mutation",
24253
+ auth: "admin"
24254
+ }), method(object({
24255
+ certPem: string().min(1),
24256
+ keyPem: string().min(1),
24257
+ caPem: string().optional()
24258
+ }), TlsStatusSchema, {
24259
+ kind: "mutation",
24260
+ auth: "admin"
24261
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24262
+ kind: "mutation",
24263
+ auth: "admin"
24264
+ });
24110
24265
  var LockControlStatusSchema = object({
24111
24266
  /** Lifecycle state of the lock. `jammed` means the motor reported
24112
24267
  * failure to reach the target — operator intervention required. */
@@ -32625,6 +32780,12 @@ Object.freeze({
32625
32780
  addonId: null,
32626
32781
  access: "create"
32627
32782
  },
32783
+ "localNetwork.downloadCa": {
32784
+ capName: "local-network",
32785
+ capScope: "system",
32786
+ addonId: null,
32787
+ access: "view"
32788
+ },
32628
32789
  "localNetwork.getAllowedAddresses": {
32629
32790
  capName: "local-network",
32630
32791
  capScope: "system",
@@ -32649,18 +32810,42 @@ Object.freeze({
32649
32810
  addonId: null,
32650
32811
  access: "view"
32651
32812
  },
32813
+ "localNetwork.getTlsStatus": {
32814
+ capName: "local-network",
32815
+ capScope: "system",
32816
+ addonId: null,
32817
+ access: "view"
32818
+ },
32819
+ "localNetwork.getViewerEndpoints": {
32820
+ capName: "local-network",
32821
+ capScope: "system",
32822
+ addonId: null,
32823
+ access: "view"
32824
+ },
32652
32825
  "localNetwork.list": {
32653
32826
  capName: "local-network",
32654
32827
  capScope: "system",
32655
32828
  addonId: null,
32656
32829
  access: "view"
32657
32830
  },
32831
+ "localNetwork.regenerateCertificate": {
32832
+ capName: "local-network",
32833
+ capScope: "system",
32834
+ addonId: null,
32835
+ access: "create"
32836
+ },
32658
32837
  "localNetwork.resetAllowlistToBestMatch": {
32659
32838
  capName: "local-network",
32660
32839
  capScope: "system",
32661
32840
  addonId: null,
32662
32841
  access: "delete"
32663
32842
  },
32843
+ "localNetwork.revertToGeneratedCertificate": {
32844
+ capName: "local-network",
32845
+ capScope: "system",
32846
+ addonId: null,
32847
+ access: "create"
32848
+ },
32664
32849
  "localNetwork.setAllowedAddresses": {
32665
32850
  capName: "local-network",
32666
32851
  capScope: "system",
@@ -32673,6 +32858,18 @@ Object.freeze({
32673
32858
  addonId: null,
32674
32859
  access: "create"
32675
32860
  },
32861
+ "localNetwork.setViewerEndpoints": {
32862
+ capName: "local-network",
32863
+ capScope: "system",
32864
+ addonId: null,
32865
+ access: "create"
32866
+ },
32867
+ "localNetwork.uploadCertificate": {
32868
+ capName: "local-network",
32869
+ capScope: "system",
32870
+ addonId: null,
32871
+ access: "create"
32872
+ },
32676
32873
  "lockControl.lock": {
32677
32874
  capName: "lock-control",
32678
32875
  capScope: "device",
@@ -35553,6 +35750,12 @@ Object.freeze({
35553
35750
  addonId: null,
35554
35751
  access: "create"
35555
35752
  },
35753
+ "terminalSession.updateInstance": {
35754
+ capName: "terminal-session",
35755
+ capScope: "system",
35756
+ addonId: null,
35757
+ access: "create"
35758
+ },
35556
35759
  "terminalSession.writeInput": {
35557
35760
  capName: "terminal-session",
35558
35761
  capScope: "system",
@@ -38040,6 +38243,35 @@ Object.freeze(Object.fromEntries([{
38040
38243
  }]
38041
38244
  }].map((s) => [s.stepId, s.defaultModelId])));
38042
38245
  string().min(1);
38246
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38247
+ stepId: "face-embedding",
38248
+ key: "minLandmarkFaceSize",
38249
+ label: "Min face size for recognition (detection px)",
38250
+ 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.",
38251
+ type: "slider",
38252
+ min: 0,
38253
+ max: 64,
38254
+ step: 2,
38255
+ default: 24
38256
+ }];
38257
+ function clusterStepSettingKey(stepId, fieldKey) {
38258
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38259
+ }
38260
+ var ClusterSettingNumberSchema = number().finite();
38261
+ function readClusterStepSettings(config) {
38262
+ const out = {};
38263
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38264
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38265
+ const value = parsed.success ? parsed.data : field.default;
38266
+ const existing = out[field.stepId] ?? {};
38267
+ out[field.stepId] = {
38268
+ ...existing,
38269
+ [field.key]: value
38270
+ };
38271
+ }
38272
+ return out;
38273
+ }
38274
+ readClusterStepSettings({});
38043
38275
  object({
38044
38276
  /**
38045
38277
  * Fraction of the box's own size added on EACH side before cutting.
package/dist/addon.mjs CHANGED
@@ -8014,6 +8014,15 @@ var LabelDefinitionSchema = object({
8014
8014
  description: string().optional(),
8015
8015
  icon: string().optional()
8016
8016
  });
8017
+ var ClassMapDefinitionSchema = object({
8018
+ mapping: record(string(), _enum([
8019
+ "person",
8020
+ "vehicle",
8021
+ "animal",
8022
+ "package"
8023
+ ])),
8024
+ preserveOriginal: boolean()
8025
+ });
8017
8026
  var MODEL_FORMATS = [
8018
8027
  "onnx",
8019
8028
  "coreml",
@@ -8192,7 +8201,13 @@ var ModelCatalogEntrySchema = object({
8192
8201
  * `id` stays the source of truth for resolution/download/persistence; grouping
8193
8202
  * is a presentation overlay resolved back to an `id`.
8194
8203
  */
8195
- group: ModelVariantGroupSchema.optional()
8204
+ group: ModelVariantGroupSchema.optional(),
8205
+ /**
8206
+ * Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
8207
+ * applies (Frigate / COCO public catalog). Set on a custom model whose raw
8208
+ * labels already ARE the CamStack macros (Scrypted identity map).
8209
+ */
8210
+ classMap: ClassMapDefinitionSchema.optional()
8196
8211
  });
8197
8212
  var ConvertTargetSchema = discriminatedUnion("format", [object({
8198
8213
  format: literal("openvino"),
@@ -8221,7 +8236,8 @@ var ModelConvertMetadataSchema = object({
8221
8236
  "ocr",
8222
8237
  "segmentation"
8223
8238
  ]),
8224
- faceAlignment: boolean().optional()
8239
+ faceAlignment: boolean().optional(),
8240
+ classMap: ClassMapDefinitionSchema.optional()
8225
8241
  });
8226
8242
  var ConvertResultSchema = object({
8227
8243
  entry: ModelCatalogEntrySchema,
@@ -17514,6 +17530,33 @@ var NativeCropRefSchema = object({
17514
17530
  h: number()
17515
17531
  })
17516
17532
  });
17533
+ object({
17534
+ crop: object({
17535
+ left: number(),
17536
+ top: number(),
17537
+ width: number().positive(),
17538
+ height: number().positive()
17539
+ }).optional(),
17540
+ content: object({
17541
+ width: number().int().positive(),
17542
+ height: number().int().positive()
17543
+ }),
17544
+ fit: _enum(["stretch", "contain"]),
17545
+ format: _enum([
17546
+ "rgb",
17547
+ "gray",
17548
+ "jpeg"
17549
+ ])
17550
+ });
17551
+ var FrameRefSchema = object({
17552
+ registryId: string().min(1),
17553
+ id: string().min(1),
17554
+ width: number().int().positive(),
17555
+ height: number().int().positive(),
17556
+ format: _enum(["rgb", "gray"]),
17557
+ timestamp: number(),
17558
+ capturedAt: number().optional()
17559
+ });
17517
17560
  var ModelFormatSchema$1 = _enum([
17518
17561
  "onnx",
17519
17562
  "coreml",
@@ -17758,6 +17801,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
17758
17801
  steps: array(PipelineStepInputSchema).min(1),
17759
17802
  frame: FrameInputSchema.optional(),
17760
17803
  /**
17804
+ * Process-local lazy frame. Valid only when caller and provider resolve
17805
+ * in the same execution-group process; split/cross-node callers use
17806
+ * `frame`/`image` inline compatibility instead.
17807
+ */
17808
+ frameRef: FrameRefSchema.optional(),
17809
+ /**
17761
17810
  * CB5 shm passthrough — a `FrameHandle` naming the same ring slot
17762
17811
  * the decoded pixels live in. One more member of the one-of
17763
17812
  * frame/frameHandle/image/imageBase64/referenceImage group.
@@ -18053,7 +18102,10 @@ var NativeCropResultSchema = object({
18053
18102
  * Which source served this crop, so a quality-sensitive consumer (the native
18054
18103
  * `keyFrame`) can reject a degraded fallback:
18055
18104
  * - `native` — cut from the decode worker's retained NATIVE surface (the
18056
- * quality path).
18105
+ * quality path). A subject-tile serve is also native-resolution and stays
18106
+ * `native` here: the public enum cannot name `tile` without a breaking cap
18107
+ * change. Runner telemetry distinguishes lease vs tile via `source` on the
18108
+ * internal crop result (`nativeHits` vs `tileHits`).
18057
18109
  * - `ram-fullframe` — the native surface MISSED but the request was full-frame,
18058
18110
  * so the ≤640 RAM `RetainedFrameStore` served it (honest lower-res; legit for
18059
18111
  * the blank-frame guard / 640-snapshot resolve, NOT for the clean keyFrame).
@@ -18544,12 +18596,41 @@ var RunnerLocalLoadSchema = object({
18544
18596
  * legacy `OrchestratorMetricsSchema` shape so existing dashboards keep
18545
18597
  * working unchanged when they switch to reading from the runner cap.
18546
18598
  */
18599
+ var FrameLazyCountersSchema = object({
18600
+ framesDecoded: number(),
18601
+ framesAdmitted: number(),
18602
+ framesDroppedPixelFree: number(),
18603
+ viewsMaterialized: number(),
18604
+ viewsSkipped: number(),
18605
+ workerToRunnerBytes: number(),
18606
+ runnerToPoolRawBytes: number(),
18607
+ runnerToPoolJpegBytes: number(),
18608
+ onDemandFullFrameRequests: number(),
18609
+ onDemandCropRequests: number(),
18610
+ nativeHits: number(),
18611
+ nativeMisses: number(),
18612
+ tileHits: number(),
18613
+ tileMisses: number(),
18614
+ fallbackHits: number(),
18615
+ fallbackMisses: number(),
18616
+ retainedWritesAvoided: number(),
18617
+ residentRefs: number(),
18618
+ residentBytes: number(),
18619
+ releases: number(),
18620
+ evictions: number(),
18621
+ staleMisses: number()
18622
+ });
18623
+ var FrameLazyMetricsSchema = object({
18624
+ node: FrameLazyCountersSchema,
18625
+ cameras: array(FrameLazyCountersSchema.extend({ deviceId: number() }))
18626
+ });
18547
18627
  var RunnerLocalMetricsSchema = object({
18548
18628
  nodeId: string(),
18549
18629
  activeCameras: number(),
18550
18630
  throttledCameras: number(),
18551
18631
  avgInferenceTimeMs: number(),
18552
- queueDepth: number()
18632
+ queueDepth: number(),
18633
+ frameLazy: FrameLazyMetricsSchema.optional()
18553
18634
  });
18554
18635
  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({
18555
18636
  handle: FrameHandleSchema,
@@ -19953,6 +20034,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
19953
20034
  location: StorageLocationSchema,
19954
20035
  relativePath: string()
19955
20036
  }), _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" });
20037
+ /** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
20038
+ var ProfileSettingsSchemaBridge = unknown().nullable();
20039
+ var ProfileSettingsBagSchema = record(string(), unknown());
19956
20040
  /**
19957
20041
  * A live terminal session hosted by the provider addon. Output and input do
19958
20042
  * NOT flow through the capability — they use the addon data plane
@@ -19982,7 +20066,14 @@ var TerminalSessionInfoSchema = object({
19982
20066
  var TerminalProfileInfoSchema = object({
19983
20067
  profileId: string(),
19984
20068
  label: string(),
19985
- description: string().optional()
20069
+ description: string().optional(),
20070
+ /** Spawn defaults the instance form copies on create. */
20071
+ executable: string().optional(),
20072
+ args: array(string()).readonly().optional(),
20073
+ cwd: string().optional(),
20074
+ environment: array(string()).readonly().optional(),
20075
+ /** ConfigUISchema for instance knobs, or null when the profile has none. */
20076
+ settingsSchema: ProfileSettingsSchemaBridge.optional()
19986
20077
  });
19987
20078
  /**
19988
20079
  * A durable operator-created Terminal instance. Profiles are templates; only
@@ -19995,7 +20086,12 @@ var TerminalInstanceInfoSchema = object({
19995
20086
  profileId: string(),
19996
20087
  profileLabel: string(),
19997
20088
  name: string(),
19998
- enabled: boolean()
20089
+ enabled: boolean(),
20090
+ executable: string(),
20091
+ args: array(string()).readonly(),
20092
+ cwd: string(),
20093
+ environment: array(string()).readonly(),
20094
+ profileSettings: ProfileSettingsBagSchema
19999
20095
  });
20000
20096
  var TerminalLegacyCameraSchema = object({
20001
20097
  stableId: string(),
@@ -20025,7 +20121,23 @@ var TerminalOutputBatchSchema = object({
20025
20121
  method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }), method(_void(), array(TerminalInstanceInfoSchema).readonly(), { auth: "admin" }), method(object({
20026
20122
  targetNodeId: string().min(1),
20027
20123
  profileId: string().min(1),
20028
- name: string().trim().min(1).max(160).optional()
20124
+ name: string().trim().min(1).max(160).optional(),
20125
+ executable: string().max(1024).optional(),
20126
+ args: array(string().max(2048)).max(64).optional(),
20127
+ cwd: string().max(1024).optional(),
20128
+ environment: array(string().max(4096)).max(64).optional(),
20129
+ profileSettings: ProfileSettingsBagSchema.optional()
20130
+ }), TerminalInstanceInfoSchema, {
20131
+ kind: "mutation",
20132
+ auth: "admin"
20133
+ }), method(object({
20134
+ instanceId: string().min(1),
20135
+ name: string().trim().min(1).max(160).optional(),
20136
+ executable: string().max(1024).optional(),
20137
+ args: array(string().max(2048)).max(64).optional(),
20138
+ cwd: string().max(1024).optional(),
20139
+ environment: array(string().max(4096)).max(64).optional(),
20140
+ profileSettings: ProfileSettingsBagSchema.optional()
20029
20141
  }), TerminalInstanceInfoSchema, {
20030
20142
  kind: "mutation",
20031
20143
  auth: "admin"
@@ -20047,7 +20159,11 @@ method(_void(), array(TerminalProfileInfoSchema).readonly(), { auth: "admin" }),
20047
20159
  }), method(_void(), array(TerminalSessionInfoSchema).readonly(), { auth: "admin" }), method(object({
20048
20160
  profileId: string(),
20049
20161
  cols: number().int().positive(),
20050
- rows: number().int().positive()
20162
+ rows: number().int().positive(),
20163
+ executable: string().max(1024).optional(),
20164
+ args: array(string().max(2048)).max(64).optional(),
20165
+ cwd: string().max(1024).optional(),
20166
+ environment: array(string().max(4096)).max(64).optional()
20051
20167
  }), TerminalSessionInfoSchema, {
20052
20168
  kind: "mutation",
20053
20169
  auth: "admin"
@@ -23922,10 +24038,10 @@ var lawnMowerControlCapability = {
23922
24038
  *
23923
24039
  * • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
23924
24040
  * to receive an ordered list of candidate base URLs it should race
23925
- * on connect — LAN IPv4 first (lowest latency when on same network),
23926
- * then public hostname (if a tunnel is up), then IPv6. The SDK can
23927
- * race them with short timeouts and stick with the winner for the
23928
- * session.
24041
+ * on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
24042
+ * when on the same network), then public hostname (if a tunnel is
24043
+ * up). The SDK can race them with short timeouts and stick with the
24044
+ * winner for the session.
23929
24045
  *
23930
24046
  * Why hub-only: agents are not directly addressable by the operator's
23931
24047
  * clients — they reverse-connect to the hub. Exposing their interfaces
@@ -24080,6 +24196,17 @@ var NotificationEndpointSchema = object({
24080
24196
  /** What the ranking currently resolves to (null when nothing is reachable). */
24081
24197
  resolved: string().nullable()
24082
24198
  });
24199
+ /**
24200
+ * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
24201
+ * AUTO (every LAN IPv4 + the public tunnel). `resolved` is what that choice
24202
+ * currently expands to, so the UI can show the effective set either way.
24203
+ */
24204
+ var ViewerEndpointsSchema = object({
24205
+ /** The operator's explicit race set, or empty for AUTO. */
24206
+ baseUrls: array(string()).readonly(),
24207
+ /** What the ranking currently resolves to (may be empty if nothing is up). */
24208
+ resolved: array(string()).readonly()
24209
+ });
24083
24210
  var AllowedAddressesSchema = object({
24084
24211
  /**
24085
24212
  * Allowlist of interface addresses operators have explicitly opted
@@ -24088,6 +24215,20 @@ var AllowedAddressesSchema = object({
24088
24215
  * Network Addresses admin page and persisted by the addon.
24089
24216
  */
24090
24217
  addresses: array(string()).readonly() });
24218
+ var TlsStatusSchema = object({
24219
+ mode: _enum([
24220
+ "generated",
24221
+ "uploaded",
24222
+ "disabled"
24223
+ ]),
24224
+ leafFingerprintSha256: string().nullable(),
24225
+ caFingerprintSha256: string().nullable(),
24226
+ validTo: string().nullable(),
24227
+ sans: array(string()),
24228
+ caCertPem: string().nullable(),
24229
+ reissueError: string().nullable(),
24230
+ restartRequired: boolean()
24231
+ });
24091
24232
  method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
24092
24233
  /**
24093
24234
  * LEGACY HINT — do not send from new code. Kept optional so clients
@@ -24097,17 +24238,31 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
24097
24238
  */
24098
24239
  port: number().int().min(1).max(65535).optional(),
24099
24240
  /** Include `http(s)://127.0.0.1:<port>` as the lowest-priority
24100
- * candidate. Default `true`. */
24241
+ * candidate. Default `false` — loopback is not a client route. */
24101
24242
  includeLoopback: boolean().optional(),
24102
- /** Skip IPv6 entries. Some legacy clients can't parse them.
24103
- * Default `false`. */
24243
+ /** Skip IPv6 entries. Default `false` the palette includes stable
24244
+ * LAN IPv6 (ICE/WebRTC uses dual-stack regardless). Pass `true` to
24245
+ * hide them. The viewer HTTP/WS race is `getViewerEndpoints`. */
24104
24246
  ipv4Only: boolean().optional(),
24105
24247
  /** Scheme to emit for LAN/loopback URLs. Default `'http'`.
24106
24248
  * Pass `'https'` when the caller is itself loaded over HTTPS
24107
24249
  * to avoid mixed-content blocks in the browser. The public
24108
24250
  * tunnel always emits `https://` regardless. */
24109
24251
  scheme: _enum(["http", "https"]).optional()
24110
- }), 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" });
24252
+ }), 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, {
24253
+ kind: "mutation",
24254
+ auth: "admin"
24255
+ }), method(object({
24256
+ certPem: string().min(1),
24257
+ keyPem: string().min(1),
24258
+ caPem: string().optional()
24259
+ }), TlsStatusSchema, {
24260
+ kind: "mutation",
24261
+ auth: "admin"
24262
+ }), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
24263
+ kind: "mutation",
24264
+ auth: "admin"
24265
+ });
24111
24266
  var LockControlStatusSchema = object({
24112
24267
  /** Lifecycle state of the lock. `jammed` means the motor reported
24113
24268
  * failure to reach the target — operator intervention required. */
@@ -32626,6 +32781,12 @@ Object.freeze({
32626
32781
  addonId: null,
32627
32782
  access: "create"
32628
32783
  },
32784
+ "localNetwork.downloadCa": {
32785
+ capName: "local-network",
32786
+ capScope: "system",
32787
+ addonId: null,
32788
+ access: "view"
32789
+ },
32629
32790
  "localNetwork.getAllowedAddresses": {
32630
32791
  capName: "local-network",
32631
32792
  capScope: "system",
@@ -32650,18 +32811,42 @@ Object.freeze({
32650
32811
  addonId: null,
32651
32812
  access: "view"
32652
32813
  },
32814
+ "localNetwork.getTlsStatus": {
32815
+ capName: "local-network",
32816
+ capScope: "system",
32817
+ addonId: null,
32818
+ access: "view"
32819
+ },
32820
+ "localNetwork.getViewerEndpoints": {
32821
+ capName: "local-network",
32822
+ capScope: "system",
32823
+ addonId: null,
32824
+ access: "view"
32825
+ },
32653
32826
  "localNetwork.list": {
32654
32827
  capName: "local-network",
32655
32828
  capScope: "system",
32656
32829
  addonId: null,
32657
32830
  access: "view"
32658
32831
  },
32832
+ "localNetwork.regenerateCertificate": {
32833
+ capName: "local-network",
32834
+ capScope: "system",
32835
+ addonId: null,
32836
+ access: "create"
32837
+ },
32659
32838
  "localNetwork.resetAllowlistToBestMatch": {
32660
32839
  capName: "local-network",
32661
32840
  capScope: "system",
32662
32841
  addonId: null,
32663
32842
  access: "delete"
32664
32843
  },
32844
+ "localNetwork.revertToGeneratedCertificate": {
32845
+ capName: "local-network",
32846
+ capScope: "system",
32847
+ addonId: null,
32848
+ access: "create"
32849
+ },
32665
32850
  "localNetwork.setAllowedAddresses": {
32666
32851
  capName: "local-network",
32667
32852
  capScope: "system",
@@ -32674,6 +32859,18 @@ Object.freeze({
32674
32859
  addonId: null,
32675
32860
  access: "create"
32676
32861
  },
32862
+ "localNetwork.setViewerEndpoints": {
32863
+ capName: "local-network",
32864
+ capScope: "system",
32865
+ addonId: null,
32866
+ access: "create"
32867
+ },
32868
+ "localNetwork.uploadCertificate": {
32869
+ capName: "local-network",
32870
+ capScope: "system",
32871
+ addonId: null,
32872
+ access: "create"
32873
+ },
32677
32874
  "lockControl.lock": {
32678
32875
  capName: "lock-control",
32679
32876
  capScope: "device",
@@ -35554,6 +35751,12 @@ Object.freeze({
35554
35751
  addonId: null,
35555
35752
  access: "create"
35556
35753
  },
35754
+ "terminalSession.updateInstance": {
35755
+ capName: "terminal-session",
35756
+ capScope: "system",
35757
+ addonId: null,
35758
+ access: "create"
35759
+ },
35557
35760
  "terminalSession.writeInput": {
35558
35761
  capName: "terminal-session",
35559
35762
  capScope: "system",
@@ -38041,6 +38244,35 @@ Object.freeze(Object.fromEntries([{
38041
38244
  }]
38042
38245
  }].map((s) => [s.stepId, s.defaultModelId])));
38043
38246
  string().min(1);
38247
+ var CLUSTER_STEP_SETTING_FIELDS = [{
38248
+ stepId: "face-embedding",
38249
+ key: "minLandmarkFaceSize",
38250
+ label: "Min face size for recognition (detection px)",
38251
+ 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.",
38252
+ type: "slider",
38253
+ min: 0,
38254
+ max: 64,
38255
+ step: 2,
38256
+ default: 24
38257
+ }];
38258
+ function clusterStepSettingKey(stepId, fieldKey) {
38259
+ return `clusterStepSetting:${stepId}:${fieldKey}`;
38260
+ }
38261
+ var ClusterSettingNumberSchema = number().finite();
38262
+ function readClusterStepSettings(config) {
38263
+ const out = {};
38264
+ for (const field of CLUSTER_STEP_SETTING_FIELDS) {
38265
+ const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
38266
+ const value = parsed.success ? parsed.data : field.default;
38267
+ const existing = out[field.stepId] ?? {};
38268
+ out[field.stepId] = {
38269
+ ...existing,
38270
+ [field.key]: value
38271
+ };
38272
+ }
38273
+ return out;
38274
+ }
38275
+ readClusterStepSettings({});
38044
38276
  object({
38045
38277
  /**
38046
38278
  * 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-amcrest",
3
- "version": "0.2.27",
3
+ "version": "0.2.28",
4
4
  "description": "Amcrest/Dahua camera device provider addon for CamStack — Dahua CGI over HTTP(S) with digest auth (snapshot, RTSP catalog, PTZ, image/day-night config)",
5
5
  "keywords": [
6
6
  "camstack",