@camstack/types 1.2.75 → 1.2.76

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 (40) hide show
  1. package/dist/addon.d.ts +19 -18
  2. package/dist/addon.js +59 -56
  3. package/dist/addon.mjs +59 -57
  4. package/dist/capabilities/alerts.cap.d.ts +5 -5
  5. package/dist/capabilities/battery.cap.d.ts +4 -4
  6. package/dist/capabilities/custom-model-registry.cap.d.ts +4 -4
  7. package/dist/capabilities/decoder.cap.d.ts +2 -2
  8. package/dist/capabilities/face-gallery.cap.d.ts +1 -1
  9. package/dist/capabilities/index.d.ts +2 -2
  10. package/dist/capabilities/lawn-mower-control.cap.d.ts +4 -4
  11. package/dist/capabilities/llm-runtime.cap.d.ts +121 -3
  12. package/dist/capabilities/llm.cap.d.ts +189 -4
  13. package/dist/capabilities/metrics-provider.cap.d.ts +2 -2
  14. package/dist/capabilities/model-convert.cap.d.ts +6 -6
  15. package/dist/capabilities/model-distributor.cap.d.ts +4 -4
  16. package/dist/capabilities/notification-output.cap.d.ts +9 -9
  17. package/dist/capabilities/notification-rules.cap.d.ts +11 -11
  18. package/dist/capabilities/osd-manager.cap.d.ts +6 -6
  19. package/dist/capabilities/pipeline-analytics.cap.d.ts +39 -39
  20. package/dist/capabilities/pipeline-executor.cap.d.ts +7 -7
  21. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +6 -6
  22. package/dist/capabilities/pipeline-runner.cap.d.ts +2 -0
  23. package/dist/capabilities/platform-probe.cap.d.ts +2 -2
  24. package/dist/capabilities/recording.cap.d.ts +3 -3
  25. package/dist/capabilities/stream-broker.cap.d.ts +6 -6
  26. package/dist/device/base-device-provider.d.ts +9 -0
  27. package/dist/encode-profile.d.ts +2 -2
  28. package/dist/generated/addon-api.d.ts +7 -0
  29. package/dist/generated/method-access-map.d.ts +1 -1
  30. package/dist/generated/system-proxy.d.ts +1 -1
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.js +188 -7
  33. package/dist/index.mjs +185 -8
  34. package/dist/interfaces/recording-config.d.ts +2 -2
  35. package/dist/interfaces/stream-broker.d.ts +9 -1
  36. package/dist/{sleep-CQayd2Su.mjs → sleep-BfRjZ3C3.mjs} +37 -1
  37. package/dist/{sleep-B-mRsuDp.js → sleep-DslGLq5_.js} +42 -0
  38. package/dist/types/models.d.ts +7 -7
  39. package/dist/util/boot-recovery-backoff.d.ts +26 -0
  40. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_event_category = require("./event-category-D3gG7oil.js");
3
- const require_sleep = require("./sleep-B-mRsuDp.js");
3
+ const require_sleep = require("./sleep-DslGLq5_.js");
4
4
  const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -9517,6 +9517,18 @@ var LlmGenerateBaseInputSchema = zod.z.object({
9517
9517
  * Resource ceiling = llama-server flags + idleStopMinutes ONLY (no RSS
9518
9518
  * watchdog — operator decision #3).
9519
9519
  */
9520
+ /**
9521
+ * A companion artifact that MUST land beside the main GGUF: the `mmproj`
9522
+ * projector of a vision model, or shards 2..N of a split GGUF. Carried on the
9523
+ * REF rather than looked up at install time, so what the operator approved in
9524
+ * the preview is exactly what the node downloads.
9525
+ */
9526
+ var ManagedModelExtraFileSchema = zod.z.object({
9527
+ url: zod.z.string(),
9528
+ filename: zod.z.string(),
9529
+ sizeBytes: zod.z.number(),
9530
+ sha256: zod.z.string().optional()
9531
+ });
9520
9532
  var ManagedModelRefSchema = zod.z.discriminatedUnion("kind", [
9521
9533
  zod.z.object({
9522
9534
  kind: zod.z.literal("catalog"),
@@ -9525,7 +9537,11 @@ var ManagedModelRefSchema = zod.z.discriminatedUnion("kind", [
9525
9537
  zod.z.object({
9526
9538
  kind: zod.z.literal("url"),
9527
9539
  url: zod.z.string(),
9528
- sha256: zod.z.string().optional()
9540
+ sha256: zod.z.string().optional(),
9541
+ /** Picker/status label; the file basename when absent. */
9542
+ label: zod.z.string().optional(),
9543
+ sizeBytes: zod.z.number().optional(),
9544
+ extraFiles: zod.z.array(ManagedModelExtraFileSchema).optional()
9529
9545
  }),
9530
9546
  zod.z.object({
9531
9547
  kind: zod.z.literal("path"),
@@ -9586,11 +9602,39 @@ var ManagedRuntimeConfigSchema = zod.z.object({
9586
9602
  "q4_1",
9587
9603
  "q4_0"
9588
9604
  ]).optional(),
9605
+ /**
9606
+ * Escape hatch for llama-server flags this schema does NOT model — `--jinja`
9607
+ * (which most vision chat templates need and some language-only models
9608
+ * dislike), `--cont-batching`, `--rope-scaling`, …
9609
+ *
9610
+ * It is NOT a second place to set the flags above. A token that collides
9611
+ * with a typed field is REJECTED at start, naming the field that owns it
9612
+ * (`assertNoOwnedFlags`), because two knobs writing the same argv is exactly
9613
+ * the "two switches that disagree" failure this repo has already shipped
9614
+ * twice (D62).
9615
+ */
9616
+ extraArgs: zod.z.array(zod.z.string()).default([]),
9589
9617
  /** Else lazy: first generate boots it. */
9590
9618
  autoStart: zod.z.boolean().default(false),
9591
9619
  /** 0 = never; frees RAM after quiet periods. */
9592
9620
  idleStopMinutes: zod.z.number().int().default(30)
9593
9621
  });
9622
+ /**
9623
+ * Where a multi-GB install currently is. A single 0..1 fraction cannot answer
9624
+ * "is it stuck?" for an install that is three files (shards + mmproj) followed
9625
+ * by a sha256 pass over 22 GB — during which the fraction sat at 1.0 and the
9626
+ * node looked hung. Phase + file + bytes is the smallest shape that does.
9627
+ */
9628
+ var LlmDownloadProgressSchema = zod.z.object({
9629
+ phase: zod.z.enum(["downloading", "verifying"]),
9630
+ /** The artifact currently moving, e.g. `mmproj-F16.gguf`. */
9631
+ file: zod.z.string(),
9632
+ fileIndex: zod.z.number().int(),
9633
+ fileCount: zod.z.number().int(),
9634
+ /** Across the WHOLE install, not the current file. */
9635
+ downloadedBytes: zod.z.number(),
9636
+ totalBytes: zod.z.number().optional()
9637
+ });
9594
9638
  var LlmRuntimeStatusSchema = zod.z.object({
9595
9639
  /** Status is ALWAYS node-qualified. */
9596
9640
  nodeId: zod.z.string(),
@@ -9607,6 +9651,8 @@ var LlmRuntimeStatusSchema = zod.z.object({
9607
9651
  modelPath: zod.z.string().optional(),
9608
9652
  modelId: zod.z.string().optional(),
9609
9653
  downloadProgress: zod.z.number().min(0).max(1).optional(),
9654
+ /** Detail behind `downloadProgress`; present for the same lifetime. */
9655
+ download: LlmDownloadProgressSchema.optional(),
9610
9656
  lastError: zod.z.string().optional(),
9611
9657
  crashesInWindow: zod.z.number(),
9612
9658
  /** Child RSS (sampled best-effort). */
@@ -9617,7 +9663,14 @@ var LlmNodeModelSchema = zod.z.object({
9617
9663
  file: zod.z.string(),
9618
9664
  sizeBytes: zod.z.number(),
9619
9665
  catalogId: zod.z.string().optional(),
9620
- installedAt: zod.z.number().optional()
9666
+ installedAt: zod.z.number().optional(),
9667
+ /**
9668
+ * Absolute path on the node. Present so a file that is on disk but matches
9669
+ * no catalog entry — a custom Hugging Face install, or a GGUF the operator
9670
+ * copied in by hand — is still SELECTABLE, as a `{kind:'path'}` ref. Without
9671
+ * it the picker could list such a file and do nothing with it.
9672
+ */
9673
+ path: zod.z.string().optional()
9621
9674
  });
9622
9675
  var LlmRuntimeDiskUsageSchema = zod.z.object({
9623
9676
  nodeId: zod.z.string(),
@@ -9781,6 +9834,36 @@ var ManagedModelCatalogEntrySchema = zod.z.object({
9781
9834
  /** Vision models: companion projector file. */
9782
9835
  mmprojUrl: zod.z.string().optional()
9783
9836
  });
9837
+ /**
9838
+ * The outcome of turning one operator-typed Hugging Face reference into a
9839
+ * download plan. A RESULT, never a throw: "this repo has 24 quantizations and
9840
+ * I will not pick for you" is a normal answer the UI has to render, not an
9841
+ * exception.
9842
+ *
9843
+ * `candidates` is the whole reason the refusal is usable — every string in it
9844
+ * is a tag that resolves when pasted back as `<org>/<repo>:<TAG>`.
9845
+ */
9846
+ var HfModelResolutionSchema = zod.z.discriminatedUnion("ok", [zod.z.object({
9847
+ ok: zod.z.literal(true),
9848
+ /** Ready to hand to `installModel` unchanged. */
9849
+ model: ManagedModelRefSchema,
9850
+ label: zod.z.string(),
9851
+ repo: zod.z.string(),
9852
+ quantization: zod.z.string(),
9853
+ purpose: zod.z.enum(["text", "vision"]),
9854
+ totalBytes: zod.z.number(),
9855
+ /** mmproj + shards, for the preview: an operator approving 23 GB should
9856
+ * see that 0.9 GB of it is a projector they did not name. */
9857
+ extraFilenames: zod.z.array(zod.z.string())
9858
+ }), zod.z.object({
9859
+ ok: zod.z.literal(false),
9860
+ code: zod.z.string(),
9861
+ message: zod.z.string(),
9862
+ candidates: zod.z.array(zod.z.string()).optional(),
9863
+ /** Set when the refusal was only the ceiling: re-calling with
9864
+ * `maxBytes: requiredBytes` is the operator's explicit override. */
9865
+ requiredBytes: zod.z.number().optional()
9866
+ })]);
9784
9867
  var LlmRuntimeNodeSchema = zod.z.object({
9785
9868
  nodeId: zod.z.string(),
9786
9869
  reachable: zod.z.boolean(),
@@ -9848,6 +9931,25 @@ var llmCapability = {
9848
9931
  listModelCatalog: require_sleep.method(zod.z.object({}), zod.z.array(ManagedModelCatalogEntrySchema)),
9849
9932
  listRuntimeNodes: require_sleep.method(zod.z.object({}), zod.z.array(LlmRuntimeNodeSchema)),
9850
9933
  listNodeModels: require_sleep.method(zod.z.object({ nodeId: zod.z.string() }), zod.z.array(LlmNodeModelSchema)),
9934
+ /**
9935
+ * One typed Hugging Face reference → a pinned, verified `ManagedModelRef`.
9936
+ *
9937
+ * Runs on the HUB, not on the target node: resolution needs egress to
9938
+ * huggingface.co, and an agent that cannot reach it still installs fine
9939
+ * through the model-distributor relay. Nothing is downloaded here — this is
9940
+ * a tree read plus a HEAD, so the operator sees the size, the quantization
9941
+ * and the mmproj BEFORE approving a multi-GB pull.
9942
+ */
9943
+ resolveModelRef: require_sleep.method(zod.z.object({
9944
+ /** `https://huggingface.co/<org>/<repo>/resolve/main/<f>.gguf`,
9945
+ * `<org>/<repo>/<f>.gguf`, `<org>/<repo>` or `<org>/<repo>:<QUANT>`. */
9946
+ ref: zod.z.string(),
9947
+ /** Explicit ceiling override, in bytes. Absent = the built-in ceiling. */
9948
+ maxBytes: zod.z.number().positive().optional()
9949
+ }), HfModelResolutionSchema, {
9950
+ kind: "mutation",
9951
+ auth: "admin"
9952
+ }),
9851
9953
  installModel: require_sleep.method(zod.z.object({
9852
9954
  nodeId: zod.z.string(),
9853
9955
  model: ManagedModelRefSchema
@@ -16846,6 +16948,17 @@ var maxSessionHoldMsField = {
16846
16948
  default: 12e4,
16847
16949
  step: 5e3
16848
16950
  };
16951
+ /**
16952
+ * Quiet period that closes an `audioMode: 'on-motion'` audio window. Floor of
16953
+ * 5s so a rearm can never degenerate into per-event stream churn; default 90s
16954
+ * comfortably outlives the gap between two PIR wakes on a battery camera.
16955
+ */
16956
+ var audioMotionWindowMsField = {
16957
+ min: 5e3,
16958
+ max: 6e5,
16959
+ default: 9e4,
16960
+ step: 5e3
16961
+ };
16849
16962
  var motionFpsField = {
16850
16963
  min: 1,
16851
16964
  max: 30,
@@ -17022,6 +17135,27 @@ var RunnerCameraConfigSchema = zod.z.object({
17022
17135
  * resolved `CameraDetectionConfig`.
17023
17136
  */
17024
17137
  maxSessionHoldMs: zod.z.number().min(maxSessionHoldMsField.min).max(maxSessionHoldMsField.max).optional(),
17138
+ /**
17139
+ * Orchestrator-side quiet period (ms) that closes an `audioMode:
17140
+ * 'on-motion'` audio window, measured from the LAST motion event.
17141
+ *
17142
+ * This exists because the falling edge cannot be relied on. Camera-native
17143
+ * providers emit motion as a RISING EDGE ONLY (Reolink's Baichuan push and
17144
+ * its email-push SMTP path both emit `detected: true` and never the
17145
+ * counterpart); only the frame-diff analyzer emits falls. So on an
17146
+ * onboard-only camera a window that closed only on `detected: false` never
17147
+ * closed at all, and `on-motion` silently behaved as `always-on` — on a
17148
+ * battery camera, the one failure mode the mode exists to prevent.
17149
+ *
17150
+ * Every motion event rearms this timer WITHOUT restarting the stream, so a
17151
+ * burst of re-fires costs nothing. A falling edge, when one does arrive,
17152
+ * still closes earlier via `motionCooldownMs` — whichever comes first wins.
17153
+ *
17154
+ * Not consumed by the runner: carried here so it shares the per-camera
17155
+ * device-settings surface with `motionCooldownMs`, exactly like
17156
+ * `maxSessionHoldMs`.
17157
+ */
17158
+ audioMotionWindowMs: zod.z.number().min(audioMotionWindowMsField.min).max(audioMotionWindowMsField.max).optional(),
17025
17159
  motionFps: zod.z.number().min(motionFpsField.min).max(motionFpsField.max).default(motionFpsField.default),
17026
17160
  detectionFps: zod.z.number().min(detectionFpsField.min).max(detectionFpsField.max).default(detectionFpsField.default),
17027
17161
  motionStreamId: zod.z.string(),
@@ -17206,6 +17340,25 @@ var RunnerCameraDeviceUIFields = [
17206
17340
  nullable: true,
17207
17341
  nullLabel: "Default"
17208
17342
  },
17343
+ {
17344
+ key: "audioMotionWindowMs",
17345
+ type: "slider",
17346
+ label: "Audio window after motion",
17347
+ description: "How long audio keeps being analysed after the last motion event. Each new motion event extends the window without restarting the audio stream.",
17348
+ min: audioMotionWindowMsField.min,
17349
+ max: audioMotionWindowMsField.max,
17350
+ step: audioMotionWindowMsField.step,
17351
+ default: audioMotionWindowMsField.default,
17352
+ showValue: true,
17353
+ unit: "s",
17354
+ displayScale: 1e3,
17355
+ nullable: true,
17356
+ nullLabel: "Default",
17357
+ showWhen: {
17358
+ field: "audioMode",
17359
+ equals: "on-motion"
17360
+ }
17361
+ },
17209
17362
  {
17210
17363
  key: "onboardMotionDrivesAnalyzer",
17211
17364
  type: "boolean",
@@ -31076,6 +31229,15 @@ var BaseDeviceProvider = class extends require_sleep.BaseAddon {
31076
31229
  labels: ["probe not implemented"]
31077
31230
  };
31078
31231
  }
31232
+ /**
31233
+ * Top-level devices restored at once in {@link onRestoreDevices}.
31234
+ *
31235
+ * Four covers the fleets this ships to without turning a boot into a burst a
31236
+ * camera NVR answers with a refusal. A provider whose upstream is a single
31237
+ * session with a serial command channel (a Baichuan hub, an NVR that
31238
+ * serialises ISAPI) should lower it; nothing needs to raise it.
31239
+ */
31240
+ restoreConcurrency = 4;
31079
31241
  async restoreDevices(savedDevices) {
31080
31242
  await this.onRestoreDevices(savedDevices);
31081
31243
  if (savedDevices.length > 0) this.ctx.logger.info(`Restored ${savedDevices.length} ${this.providerName} device(s)`);
@@ -31107,15 +31269,15 @@ var BaseDeviceProvider = class extends require_sleep.BaseAddon {
31107
31269
  */
31108
31270
  async onRestoreDevices(savedDevices) {
31109
31271
  const restored = /* @__PURE__ */ new Set();
31110
- for (const saved of savedDevices) {
31111
- if (saved.parentDeviceId !== null) continue;
31272
+ const topLevel = savedDevices.filter((saved) => saved.parentDeviceId === null);
31273
+ const restoreOne = async (saved) => {
31112
31274
  const Class = this.deviceClasses[saved.type];
31113
31275
  if (!Class) {
31114
31276
  this.ctx.logger.warn("No device class registered for restored type — skipping", {
31115
31277
  tags: { stableId: saved.stableId },
31116
31278
  meta: { type: saved.type }
31117
31279
  });
31118
- continue;
31280
+ return;
31119
31281
  }
31120
31282
  try {
31121
31283
  await this.ctx.kernel.devices.create(saved.stableId, Class, {});
@@ -31129,7 +31291,15 @@ var BaseDeviceProvider = class extends require_sleep.BaseAddon {
31129
31291
  }
31130
31292
  });
31131
31293
  }
31132
- }
31294
+ };
31295
+ let nextTopLevel = 0;
31296
+ await Promise.all(Array.from({ length: Math.min(Math.max(1, this.restoreConcurrency), topLevel.length) }, async () => {
31297
+ for (;;) {
31298
+ const saved = topLevel[nextTopLevel++];
31299
+ if (saved === void 0) return;
31300
+ await restoreOne(saved);
31301
+ }
31302
+ }));
31133
31303
  const childRows = savedDevices.filter((s) => s.parentDeviceId !== null);
31134
31304
  for (const saved of childRows) {
31135
31305
  const Class = this.deviceClasses[saved.type];
@@ -35809,6 +35979,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
35809
35979
  addonId: null,
35810
35980
  access: "view"
35811
35981
  },
35982
+ "llm.resolveModelRef": {
35983
+ capName: "llm",
35984
+ capScope: "system",
35985
+ addonId: null,
35986
+ access: "create"
35987
+ },
35812
35988
  "llm.setDefault": {
35813
35989
  capName: "llm",
35814
35990
  capScope: "system",
@@ -42052,6 +42228,7 @@ function createSystemProxy(api) {
42052
42228
  listModelCatalog: (input) => dispatch("llm", "listModelCatalog", "query", input),
42053
42229
  listRuntimeNodes: (input) => dispatch("llm", "listRuntimeNodes", "query", input),
42054
42230
  listNodeModels: (input) => dispatch("llm", "listNodeModels", "query", input),
42231
+ resolveModelRef: (input) => dispatch("llm", "resolveModelRef", "mutation", input),
42055
42232
  installModel: (input) => dispatch("llm", "installModel", "mutation", input),
42056
42233
  deleteModel: (input) => dispatch("llm", "deleteModel", "mutation", input),
42057
42234
  getRuntimeStatus: (input) => dispatch("llm", "getRuntimeStatus", "query", input),
@@ -45418,6 +45595,7 @@ exports.AvailableIntegrationTypeSchema = AvailableIntegrationTypeSchema;
45418
45595
  exports.BACKEND_TO_FORMAT = BACKEND_TO_FORMAT;
45419
45596
  exports.BASE_LIVE_EGRESS_PROFILE = BASE_LIVE_EGRESS_PROFILE;
45420
45597
  exports.BATTERY_DEVICE_PROFILE = BATTERY_DEVICE_PROFILE;
45598
+ exports.BOOT_RECOVERY_BACKOFF_MS = require_sleep.BOOT_RECOVERY_BACKOFF_MS;
45421
45599
  exports.BacklightModeSchema = BacklightModeSchema;
45422
45600
  exports.BackupDestinationInfoSchema = BackupDestinationInfoSchema;
45423
45601
  exports.BackupEntrySchema = BackupEntrySchema;
@@ -45679,6 +45857,7 @@ exports.HF_BASE_URL = HF_BASE_URL;
45679
45857
  exports.HF_REPO = HF_REPO;
45680
45858
  exports.HWACCEL_OPTIONS = HWACCEL_OPTIONS;
45681
45859
  exports.HealthStatusSchema = HealthStatusSchema;
45860
+ exports.HfModelResolutionSchema = HfModelResolutionSchema;
45682
45861
  exports.HistoryPointSchema = HistoryPointSchema;
45683
45862
  exports.HistoryResolutionEnum = HistoryResolutionEnum;
45684
45863
  exports.HumidifierStatusSchema = HumidifierStatusSchema;
@@ -45709,6 +45888,7 @@ exports.LinkedDeviceSchema = LinkedDeviceSchema;
45709
45888
  exports.LinkedDevicesModeSchema = LinkedDevicesModeSchema;
45710
45889
  exports.LlmDefaultSchema = LlmDefaultSchema;
45711
45890
  exports.LlmDefaultSelectorSchema = LlmDefaultSelectorSchema;
45891
+ exports.LlmDownloadProgressSchema = LlmDownloadProgressSchema;
45712
45892
  exports.LlmErrorCodeSchema = LlmErrorCodeSchema;
45713
45893
  exports.LlmGenerateBaseInputSchema = LlmGenerateBaseInputSchema;
45714
45894
  exports.LlmGenerateErrSchema = LlmGenerateErrSchema;
@@ -45749,6 +45929,7 @@ exports.METHOD_DEVICE_SELECTORS = METHOD_DEVICE_SELECTORS;
45749
45929
  exports.MODEL_FORMATS = MODEL_FORMATS;
45750
45930
  exports.MOTION_TRIGGER_FEATURE = MOTION_TRIGGER_FEATURE;
45751
45931
  exports.ManagedModelCatalogEntrySchema = ManagedModelCatalogEntrySchema;
45932
+ exports.ManagedModelExtraFileSchema = ManagedModelExtraFileSchema;
45752
45933
  exports.ManagedModelRefSchema = ManagedModelRefSchema;
45753
45934
  exports.ManagedRuntimeConfigSchema = ManagedRuntimeConfigSchema;
45754
45935
  exports.MaskGridDimsSchema = MaskGridDimsSchema;