@camstack/addon-pipeline 1.2.78 → 1.2.80
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.
- package/dist/{addon-utils-C-XbUkiG.js → addon-utils-C4Cge0S0.js} +1 -1
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +2 -2
- package/dist/{dist-CsP_DikG.mjs → dist-Bf1SE1Ew.mjs} +184 -5
- package/dist/{dist-BdVCXl5n.js → dist-ZSiUDGzf.js} +184 -5
- package/dist/{event-loop-stall-monitor-C3cvE_Xk.mjs → event-loop-stall-monitor-CjWfos2b.mjs} +1 -1
- package/dist/{event-loop-stall-monitor-BOu8lGee.js → event-loop-stall-monitor-VcDGoua3.js} +1 -1
- package/dist/{lazy-sharp-1LkmyWqV.js → lazy-sharp-CC4WNiKY.js} +1 -1
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +4 -4
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/recorder/index.js +62 -5
- package/dist/recorder/index.mjs +61 -4
- package/dist/session-decode/decode-worker-child.js +2 -2
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DUi-lR4R.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B1oVjQLS.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BjDv7QMq.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DEps-9qh.mjs +26 -0
- package/dist/stream-broker/{hostInit-DEtsjgBO.mjs → hostInit-D_m-NYyr.mjs} +2 -2
- package/dist/stream-broker/index.js +252 -30
- package/dist/stream-broker/index.mjs +252 -30
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-B4fPjmXk.js → worker-protocol-KDfFzKgT.js} +1 -1
- package/dist/{worker-protocol-BRwzX3f_.mjs → worker-protocol-p66oO1xL.mjs} +1 -1
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-1QMyGZMB.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Dg08SxUW.mjs +0 -26
|
@@ -2,9 +2,9 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-ZSiUDGzf.js");
|
|
6
6
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
7
|
-
const require_addon_utils = require("../addon-utils-
|
|
7
|
+
const require_addon_utils = require("../addon-utils-C4Cge0S0.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_dist.__toESM(node_path);
|
|
10
10
|
let node_fs = require("node:fs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { B as mapAudioLabelToMacro, E as audioAnalyzerCapability, T as audioAnalysisCapability, ft as hydrateSchema, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, st as BaseAddon, tt as errMsg } from "../dist-
|
|
2
|
+
import { B as mapAudioLabelToMacro, E as audioAnalyzerCapability, T as audioAnalysisCapability, ft as hydrateSchema, m as HF_BASE_URL, n as AUDIO_BACKEND_CHOICES, o as DEFAULT_AUDIO_ANALYZER_CONFIG, st as BaseAddon, tt as errMsg } from "../dist-Bf1SE1Ew.mjs";
|
|
3
3
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
4
4
|
import { i as downloadFile } from "../addon-utils-A2S9D7pu.mjs";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
@@ -2,11 +2,11 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-
|
|
7
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
5
|
+
const require_dist = require("../dist-ZSiUDGzf.js");
|
|
6
|
+
const require_event_loop_stall_monitor = require("../event-loop-stall-monitor-VcDGoua3.js");
|
|
7
|
+
const require_lazy_sharp = require("../lazy-sharp-CC4WNiKY.js");
|
|
8
8
|
const require_node_topology_platform = require("../node-topology-platform-CFZ7F4xW.js");
|
|
9
|
-
const require_addon_utils = require("../addon-utils-
|
|
9
|
+
const require_addon_utils = require("../addon-utils-C4Cge0S0.js");
|
|
10
10
|
let sharp = require("sharp");
|
|
11
11
|
sharp = require_dist.__toESM(sharp);
|
|
12
12
|
let node_child_process = require("node:child_process");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { $ as supportedRuntimes$1, A as defaultDeviceFor$1, At as string, C as YAMNET_TO_MACRO, G as pipelineExecutorCapability, L as enumerateInferenceDevices, Mt as EventCategory, Ot as object, P as detectionPipelineCapability, R as evaluateZoneRules, St as array, X as runtimeDevices$1, _t as parseJsonUnknown, bt as sleep, dt as createEvent, ft as hydrateSchema, gt as nodePin, jt as union, st as BaseAddon, t as APPLE_SA_TO_MACRO, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT } from "../dist-
|
|
3
|
-
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-
|
|
2
|
+
import { $ as supportedRuntimes$1, A as defaultDeviceFor$1, At as string, C as YAMNET_TO_MACRO, G as pipelineExecutorCapability, L as enumerateInferenceDevices, Mt as EventCategory, Ot as object, P as detectionPipelineCapability, R as evaluateZoneRules, St as array, X as runtimeDevices$1, _t as parseJsonUnknown, bt as sleep, dt as createEvent, ft as hydrateSchema, gt as nodePin, jt as union, st as BaseAddon, t as APPLE_SA_TO_MACRO, tt as errMsg, u as DEVICE_BACKEND_TO_FORMAT } from "../dist-Bf1SE1Ew.mjs";
|
|
3
|
+
import { a as getDefaultModelForFormat, c as getStepDefinition, i as ALL_STEPS, l as resolveModelForFormat, n as startEventLoopStallMonitor, o as getDefaultModelForFormatFromDef, r as ALL_PIPELINE_STEPS, s as getStep } from "../event-loop-stall-monitor-CjWfos2b.mjs";
|
|
4
4
|
import { t as getSharp } from "../lazy-sharp-6oymT_yf.mjs";
|
|
5
5
|
import { t as pickNodePlatformArch } from "../node-topology-platform-BkR_k6WT.mjs";
|
|
6
6
|
import { a as ensureModel, o as isModelDownloaded, r as deleteModelFromDisk } from "../addon-utils-A2S9D7pu.mjs";
|
|
@@ -13704,6 +13704,18 @@ var LlmGenerateBaseInputSchema = object({
|
|
|
13704
13704
|
* Resource ceiling = llama-server flags + idleStopMinutes ONLY (no RSS
|
|
13705
13705
|
* watchdog — operator decision #3).
|
|
13706
13706
|
*/
|
|
13707
|
+
/**
|
|
13708
|
+
* A companion artifact that MUST land beside the main GGUF: the `mmproj`
|
|
13709
|
+
* projector of a vision model, or shards 2..N of a split GGUF. Carried on the
|
|
13710
|
+
* REF rather than looked up at install time, so what the operator approved in
|
|
13711
|
+
* the preview is exactly what the node downloads.
|
|
13712
|
+
*/
|
|
13713
|
+
var ManagedModelExtraFileSchema = object({
|
|
13714
|
+
url: string(),
|
|
13715
|
+
filename: string(),
|
|
13716
|
+
sizeBytes: number(),
|
|
13717
|
+
sha256: string().optional()
|
|
13718
|
+
});
|
|
13707
13719
|
var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
13708
13720
|
object({
|
|
13709
13721
|
kind: literal("catalog"),
|
|
@@ -13712,7 +13724,11 @@ var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
|
13712
13724
|
object({
|
|
13713
13725
|
kind: literal("url"),
|
|
13714
13726
|
url: string(),
|
|
13715
|
-
sha256: string().optional()
|
|
13727
|
+
sha256: string().optional(),
|
|
13728
|
+
/** Picker/status label; the file basename when absent. */
|
|
13729
|
+
label: string().optional(),
|
|
13730
|
+
sizeBytes: number().optional(),
|
|
13731
|
+
extraFiles: array(ManagedModelExtraFileSchema).optional()
|
|
13716
13732
|
}),
|
|
13717
13733
|
object({
|
|
13718
13734
|
kind: literal("path"),
|
|
@@ -13773,11 +13789,39 @@ var ManagedRuntimeConfigSchema = object({
|
|
|
13773
13789
|
"q4_1",
|
|
13774
13790
|
"q4_0"
|
|
13775
13791
|
]).optional(),
|
|
13792
|
+
/**
|
|
13793
|
+
* Escape hatch for llama-server flags this schema does NOT model — `--jinja`
|
|
13794
|
+
* (which most vision chat templates need and some language-only models
|
|
13795
|
+
* dislike), `--cont-batching`, `--rope-scaling`, …
|
|
13796
|
+
*
|
|
13797
|
+
* It is NOT a second place to set the flags above. A token that collides
|
|
13798
|
+
* with a typed field is REJECTED at start, naming the field that owns it
|
|
13799
|
+
* (`assertNoOwnedFlags`), because two knobs writing the same argv is exactly
|
|
13800
|
+
* the "two switches that disagree" failure this repo has already shipped
|
|
13801
|
+
* twice (D62).
|
|
13802
|
+
*/
|
|
13803
|
+
extraArgs: array(string()).default([]),
|
|
13776
13804
|
/** Else lazy: first generate boots it. */
|
|
13777
13805
|
autoStart: boolean().default(false),
|
|
13778
13806
|
/** 0 = never; frees RAM after quiet periods. */
|
|
13779
13807
|
idleStopMinutes: number().int().default(30)
|
|
13780
13808
|
});
|
|
13809
|
+
/**
|
|
13810
|
+
* Where a multi-GB install currently is. A single 0..1 fraction cannot answer
|
|
13811
|
+
* "is it stuck?" for an install that is three files (shards + mmproj) followed
|
|
13812
|
+
* by a sha256 pass over 22 GB — during which the fraction sat at 1.0 and the
|
|
13813
|
+
* node looked hung. Phase + file + bytes is the smallest shape that does.
|
|
13814
|
+
*/
|
|
13815
|
+
var LlmDownloadProgressSchema = object({
|
|
13816
|
+
phase: _enum(["downloading", "verifying"]),
|
|
13817
|
+
/** The artifact currently moving, e.g. `mmproj-F16.gguf`. */
|
|
13818
|
+
file: string(),
|
|
13819
|
+
fileIndex: number().int(),
|
|
13820
|
+
fileCount: number().int(),
|
|
13821
|
+
/** Across the WHOLE install, not the current file. */
|
|
13822
|
+
downloadedBytes: number(),
|
|
13823
|
+
totalBytes: number().optional()
|
|
13824
|
+
});
|
|
13781
13825
|
var LlmRuntimeStatusSchema = object({
|
|
13782
13826
|
/** Status is ALWAYS node-qualified. */
|
|
13783
13827
|
nodeId: string(),
|
|
@@ -13794,6 +13838,8 @@ var LlmRuntimeStatusSchema = object({
|
|
|
13794
13838
|
modelPath: string().optional(),
|
|
13795
13839
|
modelId: string().optional(),
|
|
13796
13840
|
downloadProgress: number().min(0).max(1).optional(),
|
|
13841
|
+
/** Detail behind `downloadProgress`; present for the same lifetime. */
|
|
13842
|
+
download: LlmDownloadProgressSchema.optional(),
|
|
13797
13843
|
lastError: string().optional(),
|
|
13798
13844
|
crashesInWindow: number(),
|
|
13799
13845
|
/** Child RSS (sampled best-effort). */
|
|
@@ -13804,7 +13850,14 @@ var LlmNodeModelSchema = object({
|
|
|
13804
13850
|
file: string(),
|
|
13805
13851
|
sizeBytes: number(),
|
|
13806
13852
|
catalogId: string().optional(),
|
|
13807
|
-
installedAt: number().optional()
|
|
13853
|
+
installedAt: number().optional(),
|
|
13854
|
+
/**
|
|
13855
|
+
* Absolute path on the node. Present so a file that is on disk but matches
|
|
13856
|
+
* no catalog entry — a custom Hugging Face install, or a GGUF the operator
|
|
13857
|
+
* copied in by hand — is still SELECTABLE, as a `{kind:'path'}` ref. Without
|
|
13858
|
+
* it the picker could list such a file and do nothing with it.
|
|
13859
|
+
*/
|
|
13860
|
+
path: string().optional()
|
|
13808
13861
|
});
|
|
13809
13862
|
var LlmRuntimeDiskUsageSchema = object({
|
|
13810
13863
|
nodeId: string(),
|
|
@@ -13882,9 +13935,12 @@ var LlmProfileSchema = object({
|
|
|
13882
13935
|
systemPrompt: string().optional(),
|
|
13883
13936
|
/** Total generation bound — the only one a unary call has. */
|
|
13884
13937
|
timeoutMs: number().int().positive().default(6e4),
|
|
13885
|
-
/**
|
|
13938
|
+
/** The TCP handshake only — "is the port even open". NOT the wait for
|
|
13939
|
+
* response headers: on the LM Studio / llama-server wire those are written
|
|
13940
|
+
* once the model has finished loading, so they belong to the bound below. */
|
|
13886
13941
|
connectTimeoutMs: number().int().positive().default(1e4),
|
|
13887
|
-
/** Accepted, but no output yet —
|
|
13942
|
+
/** Accepted, but no output yet — response headers included, because a cold
|
|
13943
|
+
* GPU load is exactly what happens before them. */
|
|
13888
13944
|
firstTokenTimeoutMs: number().int().positive().default(12e4),
|
|
13889
13945
|
/** Output started then stopped. */
|
|
13890
13946
|
idleTimeoutMs: number().int().positive().default(6e4),
|
|
@@ -13947,6 +14003,36 @@ var ManagedModelCatalogEntrySchema = object({
|
|
|
13947
14003
|
/** Vision models: companion projector file. */
|
|
13948
14004
|
mmprojUrl: string().optional()
|
|
13949
14005
|
});
|
|
14006
|
+
/**
|
|
14007
|
+
* The outcome of turning one operator-typed Hugging Face reference into a
|
|
14008
|
+
* download plan. A RESULT, never a throw: "this repo has 24 quantizations and
|
|
14009
|
+
* I will not pick for you" is a normal answer the UI has to render, not an
|
|
14010
|
+
* exception.
|
|
14011
|
+
*
|
|
14012
|
+
* `candidates` is the whole reason the refusal is usable — every string in it
|
|
14013
|
+
* is a tag that resolves when pasted back as `<org>/<repo>:<TAG>`.
|
|
14014
|
+
*/
|
|
14015
|
+
var HfModelResolutionSchema = discriminatedUnion("ok", [object({
|
|
14016
|
+
ok: literal(true),
|
|
14017
|
+
/** Ready to hand to `installModel` unchanged. */
|
|
14018
|
+
model: ManagedModelRefSchema,
|
|
14019
|
+
label: string(),
|
|
14020
|
+
repo: string(),
|
|
14021
|
+
quantization: string(),
|
|
14022
|
+
purpose: _enum(["text", "vision"]),
|
|
14023
|
+
totalBytes: number(),
|
|
14024
|
+
/** mmproj + shards, for the preview: an operator approving 23 GB should
|
|
14025
|
+
* see that 0.9 GB of it is a projector they did not name. */
|
|
14026
|
+
extraFilenames: array(string())
|
|
14027
|
+
}), object({
|
|
14028
|
+
ok: literal(false),
|
|
14029
|
+
code: string(),
|
|
14030
|
+
message: string(),
|
|
14031
|
+
candidates: array(string()).optional(),
|
|
14032
|
+
/** Set when the refusal was only the ceiling: re-calling with
|
|
14033
|
+
* `maxBytes: requiredBytes` is the operator's explicit override. */
|
|
14034
|
+
requiredBytes: number().optional()
|
|
14035
|
+
})]);
|
|
13950
14036
|
var LlmRuntimeNodeSchema = object({
|
|
13951
14037
|
nodeId: string(),
|
|
13952
14038
|
reachable: boolean(),
|
|
@@ -13983,6 +14069,15 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }
|
|
|
13983
14069
|
consumer: string().optional(),
|
|
13984
14070
|
profileId: string().optional()
|
|
13985
14071
|
}), array(LlmUsageRollupSchema)), method(object({}), array(ManagedModelCatalogEntrySchema)), method(object({}), array(LlmRuntimeNodeSchema)), method(object({ nodeId: string() }), array(LlmNodeModelSchema)), method(object({
|
|
14072
|
+
/** `https://huggingface.co/<org>/<repo>/resolve/main/<f>.gguf`,
|
|
14073
|
+
* `<org>/<repo>/<f>.gguf`, `<org>/<repo>` or `<org>/<repo>:<QUANT>`. */
|
|
14074
|
+
ref: string(),
|
|
14075
|
+
/** Explicit ceiling override, in bytes. Absent = the built-in ceiling. */
|
|
14076
|
+
maxBytes: number().positive().optional()
|
|
14077
|
+
}), HfModelResolutionSchema, {
|
|
14078
|
+
kind: "mutation",
|
|
14079
|
+
auth: "admin"
|
|
14080
|
+
}), method(object({
|
|
13986
14081
|
nodeId: string(),
|
|
13987
14082
|
model: ManagedModelRefSchema
|
|
13988
14083
|
}), _void(), {
|
|
@@ -19610,6 +19705,17 @@ var maxSessionHoldMsField = {
|
|
|
19610
19705
|
default: 12e4,
|
|
19611
19706
|
step: 5e3
|
|
19612
19707
|
};
|
|
19708
|
+
/**
|
|
19709
|
+
* Quiet period that closes an `audioMode: 'on-motion'` audio window. Floor of
|
|
19710
|
+
* 5s so a rearm can never degenerate into per-event stream churn; default 90s
|
|
19711
|
+
* comfortably outlives the gap between two PIR wakes on a battery camera.
|
|
19712
|
+
*/
|
|
19713
|
+
var audioMotionWindowMsField = {
|
|
19714
|
+
min: 5e3,
|
|
19715
|
+
max: 6e5,
|
|
19716
|
+
default: 9e4,
|
|
19717
|
+
step: 5e3
|
|
19718
|
+
};
|
|
19613
19719
|
var motionFpsField = {
|
|
19614
19720
|
min: 1,
|
|
19615
19721
|
max: 30,
|
|
@@ -19786,6 +19892,27 @@ var RunnerCameraConfigSchema = object({
|
|
|
19786
19892
|
* resolved `CameraDetectionConfig`.
|
|
19787
19893
|
*/
|
|
19788
19894
|
maxSessionHoldMs: number().min(maxSessionHoldMsField.min).max(maxSessionHoldMsField.max).optional(),
|
|
19895
|
+
/**
|
|
19896
|
+
* Orchestrator-side quiet period (ms) that closes an `audioMode:
|
|
19897
|
+
* 'on-motion'` audio window, measured from the LAST motion event.
|
|
19898
|
+
*
|
|
19899
|
+
* This exists because the falling edge cannot be relied on. Camera-native
|
|
19900
|
+
* providers emit motion as a RISING EDGE ONLY (Reolink's Baichuan push and
|
|
19901
|
+
* its email-push SMTP path both emit `detected: true` and never the
|
|
19902
|
+
* counterpart); only the frame-diff analyzer emits falls. So on an
|
|
19903
|
+
* onboard-only camera a window that closed only on `detected: false` never
|
|
19904
|
+
* closed at all, and `on-motion` silently behaved as `always-on` — on a
|
|
19905
|
+
* battery camera, the one failure mode the mode exists to prevent.
|
|
19906
|
+
*
|
|
19907
|
+
* Every motion event rearms this timer WITHOUT restarting the stream, so a
|
|
19908
|
+
* burst of re-fires costs nothing. A falling edge, when one does arrive,
|
|
19909
|
+
* still closes earlier via `motionCooldownMs` — whichever comes first wins.
|
|
19910
|
+
*
|
|
19911
|
+
* Not consumed by the runner: carried here so it shares the per-camera
|
|
19912
|
+
* device-settings surface with `motionCooldownMs`, exactly like
|
|
19913
|
+
* `maxSessionHoldMs`.
|
|
19914
|
+
*/
|
|
19915
|
+
audioMotionWindowMs: number().min(audioMotionWindowMsField.min).max(audioMotionWindowMsField.max).optional(),
|
|
19789
19916
|
motionFps: number().min(motionFpsField.min).max(motionFpsField.max).default(motionFpsField.default),
|
|
19790
19917
|
detectionFps: number().min(detectionFpsField.min).max(detectionFpsField.max).default(detectionFpsField.default),
|
|
19791
19918
|
motionStreamId: string(),
|
|
@@ -19881,7 +20008,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
19881
20008
|
*/
|
|
19882
20009
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
19883
20010
|
});
|
|
19884
|
-
motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
20011
|
+
motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
19885
20012
|
/**
|
|
19886
20013
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
19887
20014
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -26676,6 +26803,33 @@ var recordingExportCapability = {
|
|
|
26676
26803
|
* as `unknown`, never guessed. A day reference scored against an IR frame
|
|
26677
26804
|
* collapses the cosine and would latch a false alarm every single night. */
|
|
26678
26805
|
var SceneConditionSchema = string();
|
|
26806
|
+
/**
|
|
26807
|
+
* What a scene does when the CURRENT light has no reference of its own.
|
|
26808
|
+
*
|
|
26809
|
+
* The lighting variants are not equally likely to exist. Almost every operator
|
|
26810
|
+
* captures daylight and then never stands outside at 22:00 to capture IR, and a
|
|
26811
|
+
* scene that is only ever going to be asked about a daytime question ("is the
|
|
26812
|
+
* bin still on the kerb at 08:00") does not need a night reference at all. The
|
|
26813
|
+
* night half must therefore be OPTIONAL, and optional means the scene keeps
|
|
26814
|
+
* working without it rather than degrading into a permanent complaint.
|
|
26815
|
+
*
|
|
26816
|
+
* - `skip` (default) — the check in that light is not made. Not a verdict, not
|
|
26817
|
+
* an alarm, not even an `unknown`: the live state simply stays whatever the
|
|
26818
|
+
* last covered light left it at, the latch is untouched, and the hysteresis
|
|
26819
|
+
* run is neither spent nor cleared. The scene resumes by itself at first
|
|
26820
|
+
* light. This is the only behaviour under which "I never captured IR" is a
|
|
26821
|
+
* configuration choice instead of a nightly fault.
|
|
26822
|
+
* - `judge-anyway` — score against the OTHER conditions' references. Available
|
|
26823
|
+
* for cameras whose IR frame is close enough to daylight (a floodlit
|
|
26824
|
+
* driveway, an always-white-light doorbell), and wrong for everything else:
|
|
26825
|
+
* cross-condition cosines are not comparable, so a day reference against a
|
|
26826
|
+
* true IR frame collapses and the scene reports a theft at 21:40.
|
|
26827
|
+
*
|
|
26828
|
+
* Never applies when the scene has NO comparable reference at all — that is
|
|
26829
|
+
* "not armed yet", it is reported as `no-reference-for-condition`, and silence
|
|
26830
|
+
* there would hide a scene the operator never finished setting up.
|
|
26831
|
+
*/
|
|
26832
|
+
var SceneUncoveredPolicySchema = _enum(["skip", "judge-anyway"]);
|
|
26679
26833
|
/** `matched` = the baseline is what we see; `diverged` = it demonstrably is not;
|
|
26680
26834
|
* `unknown` = we cannot judge (no reference for this condition, encoder model
|
|
26681
26835
|
* changed, view shifted, no snapshot). `unknown` is a real value, not a null,
|
|
@@ -26731,6 +26885,9 @@ var SceneCheckSchema = discriminatedUnion("mode", [object({
|
|
|
26731
26885
|
hysteresisCount: number().int().positive()
|
|
26732
26886
|
})]);
|
|
26733
26887
|
var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
|
|
26888
|
+
/** Night is OPTIONAL. A scene with only a daylight reference sits the IR hours
|
|
26889
|
+
* out in silence rather than reporting a fault every night. */
|
|
26890
|
+
var SCENE_DEFAULT_UNCOVERED_POLICY = "skip";
|
|
26734
26891
|
/**
|
|
26735
26892
|
* Vision-model adjudication of a candidate flip. Field names deliberately
|
|
26736
26893
|
* mirror `NcConfirmSchema` so an operator meets one vocabulary, not two.
|
|
@@ -26797,6 +26954,21 @@ var SceneMonitorSchema = object({
|
|
|
26797
26954
|
* automation can react to the bin coming back without the operator's own
|
|
26798
26955
|
* alarm silently clearing itself. */
|
|
26799
26956
|
autoRestore: boolean().default(false),
|
|
26957
|
+
/** What to do when the current light has no reference of its own. See
|
|
26958
|
+
* {@link SceneUncoveredPolicySchema} — the default makes night OPTIONAL. */
|
|
26959
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.default(SCENE_DEFAULT_UNCOVERED_POLICY),
|
|
26960
|
+
/**
|
|
26961
|
+
* The light whose checks are currently being SAT OUT under
|
|
26962
|
+
* `onUncoveredCondition: 'skip'` — `null` when the scene is checking normally.
|
|
26963
|
+
*
|
|
26964
|
+
* Engine-reported and advisory only: it moves no verdict, no latch and no
|
|
26965
|
+
* hysteresis. It exists so the card can say *"night (IR) — checks paused,
|
|
26966
|
+
* nothing captured in this light"* in the same calm voice as the coverage
|
|
26967
|
+
* line, because the alternative is a scene that silently stops answering
|
|
26968
|
+
* after sunset with nothing anywhere saying why. A skipped check must never
|
|
26969
|
+
* read as a broken one.
|
|
26970
|
+
*/
|
|
26971
|
+
suspendedCondition: SceneConditionSchema.nullable().default(null),
|
|
26800
26972
|
/** Named cause when `verdict === 'unknown'`. */
|
|
26801
26973
|
unavailable: SceneUnavailableSchema.nullable(),
|
|
26802
26974
|
/** Conditions that have at least one comparable reference — the coverage line
|
|
@@ -26840,6 +27012,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSche
|
|
|
26840
27012
|
minObservationSpacingSec: number().int().min(0).max(3600).optional(),
|
|
26841
27013
|
anchorThreshold: number().min(0).max(1).optional(),
|
|
26842
27014
|
autoRestore: boolean().optional(),
|
|
27015
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.optional(),
|
|
26843
27016
|
/** `null` clears the vision-model adjudicator. */
|
|
26844
27017
|
confirm: SceneConfirmSchema.nullable().optional()
|
|
26845
27018
|
})
|
|
@@ -30072,6 +30245,12 @@ Object.freeze({
|
|
|
30072
30245
|
addonId: null,
|
|
30073
30246
|
access: "view"
|
|
30074
30247
|
},
|
|
30248
|
+
"llm.resolveModelRef": {
|
|
30249
|
+
capName: "llm",
|
|
30250
|
+
capScope: "system",
|
|
30251
|
+
addonId: null,
|
|
30252
|
+
access: "create"
|
|
30253
|
+
},
|
|
30075
30254
|
"llm.setDefault": {
|
|
30076
30255
|
capName: "llm",
|
|
30077
30256
|
capScope: "system",
|
|
@@ -13727,6 +13727,18 @@ var LlmGenerateBaseInputSchema = object({
|
|
|
13727
13727
|
* Resource ceiling = llama-server flags + idleStopMinutes ONLY (no RSS
|
|
13728
13728
|
* watchdog — operator decision #3).
|
|
13729
13729
|
*/
|
|
13730
|
+
/**
|
|
13731
|
+
* A companion artifact that MUST land beside the main GGUF: the `mmproj`
|
|
13732
|
+
* projector of a vision model, or shards 2..N of a split GGUF. Carried on the
|
|
13733
|
+
* REF rather than looked up at install time, so what the operator approved in
|
|
13734
|
+
* the preview is exactly what the node downloads.
|
|
13735
|
+
*/
|
|
13736
|
+
var ManagedModelExtraFileSchema = object({
|
|
13737
|
+
url: string(),
|
|
13738
|
+
filename: string(),
|
|
13739
|
+
sizeBytes: number(),
|
|
13740
|
+
sha256: string().optional()
|
|
13741
|
+
});
|
|
13730
13742
|
var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
13731
13743
|
object({
|
|
13732
13744
|
kind: literal("catalog"),
|
|
@@ -13735,7 +13747,11 @@ var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
|
13735
13747
|
object({
|
|
13736
13748
|
kind: literal("url"),
|
|
13737
13749
|
url: string(),
|
|
13738
|
-
sha256: string().optional()
|
|
13750
|
+
sha256: string().optional(),
|
|
13751
|
+
/** Picker/status label; the file basename when absent. */
|
|
13752
|
+
label: string().optional(),
|
|
13753
|
+
sizeBytes: number().optional(),
|
|
13754
|
+
extraFiles: array(ManagedModelExtraFileSchema).optional()
|
|
13739
13755
|
}),
|
|
13740
13756
|
object({
|
|
13741
13757
|
kind: literal("path"),
|
|
@@ -13796,11 +13812,39 @@ var ManagedRuntimeConfigSchema = object({
|
|
|
13796
13812
|
"q4_1",
|
|
13797
13813
|
"q4_0"
|
|
13798
13814
|
]).optional(),
|
|
13815
|
+
/**
|
|
13816
|
+
* Escape hatch for llama-server flags this schema does NOT model — `--jinja`
|
|
13817
|
+
* (which most vision chat templates need and some language-only models
|
|
13818
|
+
* dislike), `--cont-batching`, `--rope-scaling`, …
|
|
13819
|
+
*
|
|
13820
|
+
* It is NOT a second place to set the flags above. A token that collides
|
|
13821
|
+
* with a typed field is REJECTED at start, naming the field that owns it
|
|
13822
|
+
* (`assertNoOwnedFlags`), because two knobs writing the same argv is exactly
|
|
13823
|
+
* the "two switches that disagree" failure this repo has already shipped
|
|
13824
|
+
* twice (D62).
|
|
13825
|
+
*/
|
|
13826
|
+
extraArgs: array(string()).default([]),
|
|
13799
13827
|
/** Else lazy: first generate boots it. */
|
|
13800
13828
|
autoStart: boolean().default(false),
|
|
13801
13829
|
/** 0 = never; frees RAM after quiet periods. */
|
|
13802
13830
|
idleStopMinutes: number().int().default(30)
|
|
13803
13831
|
});
|
|
13832
|
+
/**
|
|
13833
|
+
* Where a multi-GB install currently is. A single 0..1 fraction cannot answer
|
|
13834
|
+
* "is it stuck?" for an install that is three files (shards + mmproj) followed
|
|
13835
|
+
* by a sha256 pass over 22 GB — during which the fraction sat at 1.0 and the
|
|
13836
|
+
* node looked hung. Phase + file + bytes is the smallest shape that does.
|
|
13837
|
+
*/
|
|
13838
|
+
var LlmDownloadProgressSchema = object({
|
|
13839
|
+
phase: _enum(["downloading", "verifying"]),
|
|
13840
|
+
/** The artifact currently moving, e.g. `mmproj-F16.gguf`. */
|
|
13841
|
+
file: string(),
|
|
13842
|
+
fileIndex: number().int(),
|
|
13843
|
+
fileCount: number().int(),
|
|
13844
|
+
/** Across the WHOLE install, not the current file. */
|
|
13845
|
+
downloadedBytes: number(),
|
|
13846
|
+
totalBytes: number().optional()
|
|
13847
|
+
});
|
|
13804
13848
|
var LlmRuntimeStatusSchema = object({
|
|
13805
13849
|
/** Status is ALWAYS node-qualified. */
|
|
13806
13850
|
nodeId: string(),
|
|
@@ -13817,6 +13861,8 @@ var LlmRuntimeStatusSchema = object({
|
|
|
13817
13861
|
modelPath: string().optional(),
|
|
13818
13862
|
modelId: string().optional(),
|
|
13819
13863
|
downloadProgress: number().min(0).max(1).optional(),
|
|
13864
|
+
/** Detail behind `downloadProgress`; present for the same lifetime. */
|
|
13865
|
+
download: LlmDownloadProgressSchema.optional(),
|
|
13820
13866
|
lastError: string().optional(),
|
|
13821
13867
|
crashesInWindow: number(),
|
|
13822
13868
|
/** Child RSS (sampled best-effort). */
|
|
@@ -13827,7 +13873,14 @@ var LlmNodeModelSchema = object({
|
|
|
13827
13873
|
file: string(),
|
|
13828
13874
|
sizeBytes: number(),
|
|
13829
13875
|
catalogId: string().optional(),
|
|
13830
|
-
installedAt: number().optional()
|
|
13876
|
+
installedAt: number().optional(),
|
|
13877
|
+
/**
|
|
13878
|
+
* Absolute path on the node. Present so a file that is on disk but matches
|
|
13879
|
+
* no catalog entry — a custom Hugging Face install, or a GGUF the operator
|
|
13880
|
+
* copied in by hand — is still SELECTABLE, as a `{kind:'path'}` ref. Without
|
|
13881
|
+
* it the picker could list such a file and do nothing with it.
|
|
13882
|
+
*/
|
|
13883
|
+
path: string().optional()
|
|
13831
13884
|
});
|
|
13832
13885
|
var LlmRuntimeDiskUsageSchema = object({
|
|
13833
13886
|
nodeId: string(),
|
|
@@ -13905,9 +13958,12 @@ var LlmProfileSchema = object({
|
|
|
13905
13958
|
systemPrompt: string().optional(),
|
|
13906
13959
|
/** Total generation bound — the only one a unary call has. */
|
|
13907
13960
|
timeoutMs: number().int().positive().default(6e4),
|
|
13908
|
-
/**
|
|
13961
|
+
/** The TCP handshake only — "is the port even open". NOT the wait for
|
|
13962
|
+
* response headers: on the LM Studio / llama-server wire those are written
|
|
13963
|
+
* once the model has finished loading, so they belong to the bound below. */
|
|
13909
13964
|
connectTimeoutMs: number().int().positive().default(1e4),
|
|
13910
|
-
/** Accepted, but no output yet —
|
|
13965
|
+
/** Accepted, but no output yet — response headers included, because a cold
|
|
13966
|
+
* GPU load is exactly what happens before them. */
|
|
13911
13967
|
firstTokenTimeoutMs: number().int().positive().default(12e4),
|
|
13912
13968
|
/** Output started then stopped. */
|
|
13913
13969
|
idleTimeoutMs: number().int().positive().default(6e4),
|
|
@@ -13970,6 +14026,36 @@ var ManagedModelCatalogEntrySchema = object({
|
|
|
13970
14026
|
/** Vision models: companion projector file. */
|
|
13971
14027
|
mmprojUrl: string().optional()
|
|
13972
14028
|
});
|
|
14029
|
+
/**
|
|
14030
|
+
* The outcome of turning one operator-typed Hugging Face reference into a
|
|
14031
|
+
* download plan. A RESULT, never a throw: "this repo has 24 quantizations and
|
|
14032
|
+
* I will not pick for you" is a normal answer the UI has to render, not an
|
|
14033
|
+
* exception.
|
|
14034
|
+
*
|
|
14035
|
+
* `candidates` is the whole reason the refusal is usable — every string in it
|
|
14036
|
+
* is a tag that resolves when pasted back as `<org>/<repo>:<TAG>`.
|
|
14037
|
+
*/
|
|
14038
|
+
var HfModelResolutionSchema = discriminatedUnion("ok", [object({
|
|
14039
|
+
ok: literal(true),
|
|
14040
|
+
/** Ready to hand to `installModel` unchanged. */
|
|
14041
|
+
model: ManagedModelRefSchema,
|
|
14042
|
+
label: string(),
|
|
14043
|
+
repo: string(),
|
|
14044
|
+
quantization: string(),
|
|
14045
|
+
purpose: _enum(["text", "vision"]),
|
|
14046
|
+
totalBytes: number(),
|
|
14047
|
+
/** mmproj + shards, for the preview: an operator approving 23 GB should
|
|
14048
|
+
* see that 0.9 GB of it is a projector they did not name. */
|
|
14049
|
+
extraFilenames: array(string())
|
|
14050
|
+
}), object({
|
|
14051
|
+
ok: literal(false),
|
|
14052
|
+
code: string(),
|
|
14053
|
+
message: string(),
|
|
14054
|
+
candidates: array(string()).optional(),
|
|
14055
|
+
/** Set when the refusal was only the ceiling: re-calling with
|
|
14056
|
+
* `maxBytes: requiredBytes` is the operator's explicit override. */
|
|
14057
|
+
requiredBytes: number().optional()
|
|
14058
|
+
})]);
|
|
13973
14059
|
var LlmRuntimeNodeSchema = object({
|
|
13974
14060
|
nodeId: string(),
|
|
13975
14061
|
reachable: boolean(),
|
|
@@ -14006,6 +14092,15 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }
|
|
|
14006
14092
|
consumer: string().optional(),
|
|
14007
14093
|
profileId: string().optional()
|
|
14008
14094
|
}), array(LlmUsageRollupSchema)), method(object({}), array(ManagedModelCatalogEntrySchema)), method(object({}), array(LlmRuntimeNodeSchema)), method(object({ nodeId: string() }), array(LlmNodeModelSchema)), method(object({
|
|
14095
|
+
/** `https://huggingface.co/<org>/<repo>/resolve/main/<f>.gguf`,
|
|
14096
|
+
* `<org>/<repo>/<f>.gguf`, `<org>/<repo>` or `<org>/<repo>:<QUANT>`. */
|
|
14097
|
+
ref: string(),
|
|
14098
|
+
/** Explicit ceiling override, in bytes. Absent = the built-in ceiling. */
|
|
14099
|
+
maxBytes: number().positive().optional()
|
|
14100
|
+
}), HfModelResolutionSchema, {
|
|
14101
|
+
kind: "mutation",
|
|
14102
|
+
auth: "admin"
|
|
14103
|
+
}), method(object({
|
|
14009
14104
|
nodeId: string(),
|
|
14010
14105
|
model: ManagedModelRefSchema
|
|
14011
14106
|
}), _void(), {
|
|
@@ -19633,6 +19728,17 @@ var maxSessionHoldMsField = {
|
|
|
19633
19728
|
default: 12e4,
|
|
19634
19729
|
step: 5e3
|
|
19635
19730
|
};
|
|
19731
|
+
/**
|
|
19732
|
+
* Quiet period that closes an `audioMode: 'on-motion'` audio window. Floor of
|
|
19733
|
+
* 5s so a rearm can never degenerate into per-event stream churn; default 90s
|
|
19734
|
+
* comfortably outlives the gap between two PIR wakes on a battery camera.
|
|
19735
|
+
*/
|
|
19736
|
+
var audioMotionWindowMsField = {
|
|
19737
|
+
min: 5e3,
|
|
19738
|
+
max: 6e5,
|
|
19739
|
+
default: 9e4,
|
|
19740
|
+
step: 5e3
|
|
19741
|
+
};
|
|
19636
19742
|
var motionFpsField = {
|
|
19637
19743
|
min: 1,
|
|
19638
19744
|
max: 30,
|
|
@@ -19809,6 +19915,27 @@ var RunnerCameraConfigSchema = object({
|
|
|
19809
19915
|
* resolved `CameraDetectionConfig`.
|
|
19810
19916
|
*/
|
|
19811
19917
|
maxSessionHoldMs: number().min(maxSessionHoldMsField.min).max(maxSessionHoldMsField.max).optional(),
|
|
19918
|
+
/**
|
|
19919
|
+
* Orchestrator-side quiet period (ms) that closes an `audioMode:
|
|
19920
|
+
* 'on-motion'` audio window, measured from the LAST motion event.
|
|
19921
|
+
*
|
|
19922
|
+
* This exists because the falling edge cannot be relied on. Camera-native
|
|
19923
|
+
* providers emit motion as a RISING EDGE ONLY (Reolink's Baichuan push and
|
|
19924
|
+
* its email-push SMTP path both emit `detected: true` and never the
|
|
19925
|
+
* counterpart); only the frame-diff analyzer emits falls. So on an
|
|
19926
|
+
* onboard-only camera a window that closed only on `detected: false` never
|
|
19927
|
+
* closed at all, and `on-motion` silently behaved as `always-on` — on a
|
|
19928
|
+
* battery camera, the one failure mode the mode exists to prevent.
|
|
19929
|
+
*
|
|
19930
|
+
* Every motion event rearms this timer WITHOUT restarting the stream, so a
|
|
19931
|
+
* burst of re-fires costs nothing. A falling edge, when one does arrive,
|
|
19932
|
+
* still closes earlier via `motionCooldownMs` — whichever comes first wins.
|
|
19933
|
+
*
|
|
19934
|
+
* Not consumed by the runner: carried here so it shares the per-camera
|
|
19935
|
+
* device-settings surface with `motionCooldownMs`, exactly like
|
|
19936
|
+
* `maxSessionHoldMs`.
|
|
19937
|
+
*/
|
|
19938
|
+
audioMotionWindowMs: number().min(audioMotionWindowMsField.min).max(audioMotionWindowMsField.max).optional(),
|
|
19812
19939
|
motionFps: number().min(motionFpsField.min).max(motionFpsField.max).default(motionFpsField.default),
|
|
19813
19940
|
detectionFps: number().min(detectionFpsField.min).max(detectionFpsField.max).default(detectionFpsField.default),
|
|
19814
19941
|
motionStreamId: string(),
|
|
@@ -19904,7 +20031,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
19904
20031
|
*/
|
|
19905
20032
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
19906
20033
|
});
|
|
19907
|
-
motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
20034
|
+
motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
19908
20035
|
/**
|
|
19909
20036
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
19910
20037
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -26699,6 +26826,33 @@ var recordingExportCapability = {
|
|
|
26699
26826
|
* as `unknown`, never guessed. A day reference scored against an IR frame
|
|
26700
26827
|
* collapses the cosine and would latch a false alarm every single night. */
|
|
26701
26828
|
var SceneConditionSchema = string();
|
|
26829
|
+
/**
|
|
26830
|
+
* What a scene does when the CURRENT light has no reference of its own.
|
|
26831
|
+
*
|
|
26832
|
+
* The lighting variants are not equally likely to exist. Almost every operator
|
|
26833
|
+
* captures daylight and then never stands outside at 22:00 to capture IR, and a
|
|
26834
|
+
* scene that is only ever going to be asked about a daytime question ("is the
|
|
26835
|
+
* bin still on the kerb at 08:00") does not need a night reference at all. The
|
|
26836
|
+
* night half must therefore be OPTIONAL, and optional means the scene keeps
|
|
26837
|
+
* working without it rather than degrading into a permanent complaint.
|
|
26838
|
+
*
|
|
26839
|
+
* - `skip` (default) — the check in that light is not made. Not a verdict, not
|
|
26840
|
+
* an alarm, not even an `unknown`: the live state simply stays whatever the
|
|
26841
|
+
* last covered light left it at, the latch is untouched, and the hysteresis
|
|
26842
|
+
* run is neither spent nor cleared. The scene resumes by itself at first
|
|
26843
|
+
* light. This is the only behaviour under which "I never captured IR" is a
|
|
26844
|
+
* configuration choice instead of a nightly fault.
|
|
26845
|
+
* - `judge-anyway` — score against the OTHER conditions' references. Available
|
|
26846
|
+
* for cameras whose IR frame is close enough to daylight (a floodlit
|
|
26847
|
+
* driveway, an always-white-light doorbell), and wrong for everything else:
|
|
26848
|
+
* cross-condition cosines are not comparable, so a day reference against a
|
|
26849
|
+
* true IR frame collapses and the scene reports a theft at 21:40.
|
|
26850
|
+
*
|
|
26851
|
+
* Never applies when the scene has NO comparable reference at all — that is
|
|
26852
|
+
* "not armed yet", it is reported as `no-reference-for-condition`, and silence
|
|
26853
|
+
* there would hide a scene the operator never finished setting up.
|
|
26854
|
+
*/
|
|
26855
|
+
var SceneUncoveredPolicySchema = _enum(["skip", "judge-anyway"]);
|
|
26702
26856
|
/** `matched` = the baseline is what we see; `diverged` = it demonstrably is not;
|
|
26703
26857
|
* `unknown` = we cannot judge (no reference for this condition, encoder model
|
|
26704
26858
|
* changed, view shifted, no snapshot). `unknown` is a real value, not a null,
|
|
@@ -26754,6 +26908,9 @@ var SceneCheckSchema = discriminatedUnion("mode", [object({
|
|
|
26754
26908
|
hysteresisCount: number().int().positive()
|
|
26755
26909
|
})]);
|
|
26756
26910
|
var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
|
|
26911
|
+
/** Night is OPTIONAL. A scene with only a daylight reference sits the IR hours
|
|
26912
|
+
* out in silence rather than reporting a fault every night. */
|
|
26913
|
+
var SCENE_DEFAULT_UNCOVERED_POLICY = "skip";
|
|
26757
26914
|
/**
|
|
26758
26915
|
* Vision-model adjudication of a candidate flip. Field names deliberately
|
|
26759
26916
|
* mirror `NcConfirmSchema` so an operator meets one vocabulary, not two.
|
|
@@ -26820,6 +26977,21 @@ var SceneMonitorSchema = object({
|
|
|
26820
26977
|
* automation can react to the bin coming back without the operator's own
|
|
26821
26978
|
* alarm silently clearing itself. */
|
|
26822
26979
|
autoRestore: boolean().default(false),
|
|
26980
|
+
/** What to do when the current light has no reference of its own. See
|
|
26981
|
+
* {@link SceneUncoveredPolicySchema} — the default makes night OPTIONAL. */
|
|
26982
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.default(SCENE_DEFAULT_UNCOVERED_POLICY),
|
|
26983
|
+
/**
|
|
26984
|
+
* The light whose checks are currently being SAT OUT under
|
|
26985
|
+
* `onUncoveredCondition: 'skip'` — `null` when the scene is checking normally.
|
|
26986
|
+
*
|
|
26987
|
+
* Engine-reported and advisory only: it moves no verdict, no latch and no
|
|
26988
|
+
* hysteresis. It exists so the card can say *"night (IR) — checks paused,
|
|
26989
|
+
* nothing captured in this light"* in the same calm voice as the coverage
|
|
26990
|
+
* line, because the alternative is a scene that silently stops answering
|
|
26991
|
+
* after sunset with nothing anywhere saying why. A skipped check must never
|
|
26992
|
+
* read as a broken one.
|
|
26993
|
+
*/
|
|
26994
|
+
suspendedCondition: SceneConditionSchema.nullable().default(null),
|
|
26823
26995
|
/** Named cause when `verdict === 'unknown'`. */
|
|
26824
26996
|
unavailable: SceneUnavailableSchema.nullable(),
|
|
26825
26997
|
/** Conditions that have at least one comparable reference — the coverage line
|
|
@@ -26863,6 +27035,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSche
|
|
|
26863
27035
|
minObservationSpacingSec: number().int().min(0).max(3600).optional(),
|
|
26864
27036
|
anchorThreshold: number().min(0).max(1).optional(),
|
|
26865
27037
|
autoRestore: boolean().optional(),
|
|
27038
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.optional(),
|
|
26866
27039
|
/** `null` clears the vision-model adjudicator. */
|
|
26867
27040
|
confirm: SceneConfirmSchema.nullable().optional()
|
|
26868
27041
|
})
|
|
@@ -30095,6 +30268,12 @@ Object.freeze({
|
|
|
30095
30268
|
addonId: null,
|
|
30096
30269
|
access: "view"
|
|
30097
30270
|
},
|
|
30271
|
+
"llm.resolveModelRef": {
|
|
30272
|
+
capName: "llm",
|
|
30273
|
+
capScope: "system",
|
|
30274
|
+
addonId: null,
|
|
30275
|
+
access: "create"
|
|
30276
|
+
},
|
|
30098
30277
|
"llm.setDefault": {
|
|
30099
30278
|
capName: "llm",
|
|
30100
30279
|
capScope: "system",
|