@camstack/addon-post-analysis 1.2.77 → 1.2.79
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/{dist-Bs6oboqZ.js → dist-CWoaZE47.js} +274 -6
- package/dist/{dist-CxeFHSSV.mjs → dist-D6_m_zg1.mjs} +269 -7
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BP6Na43Q.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DhzYNXUk.mjs} +2 -2
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BeCNd7Q3.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-DTI0jC8p.mjs → hostInit-CcziTvBY.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +1180 -473
- package/dist/pipeline-analytics/index.mjs +1143 -436
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DFckpC3K.mjs +0 -26
|
@@ -12759,6 +12759,18 @@ var LlmGenerateBaseInputSchema = object({
|
|
|
12759
12759
|
* Resource ceiling = llama-server flags + idleStopMinutes ONLY (no RSS
|
|
12760
12760
|
* watchdog — operator decision #3).
|
|
12761
12761
|
*/
|
|
12762
|
+
/**
|
|
12763
|
+
* A companion artifact that MUST land beside the main GGUF: the `mmproj`
|
|
12764
|
+
* projector of a vision model, or shards 2..N of a split GGUF. Carried on the
|
|
12765
|
+
* REF rather than looked up at install time, so what the operator approved in
|
|
12766
|
+
* the preview is exactly what the node downloads.
|
|
12767
|
+
*/
|
|
12768
|
+
var ManagedModelExtraFileSchema = object({
|
|
12769
|
+
url: string(),
|
|
12770
|
+
filename: string(),
|
|
12771
|
+
sizeBytes: number(),
|
|
12772
|
+
sha256: string().optional()
|
|
12773
|
+
});
|
|
12762
12774
|
var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
12763
12775
|
object({
|
|
12764
12776
|
kind: literal("catalog"),
|
|
@@ -12767,7 +12779,11 @@ var ManagedModelRefSchema = discriminatedUnion("kind", [
|
|
|
12767
12779
|
object({
|
|
12768
12780
|
kind: literal("url"),
|
|
12769
12781
|
url: string(),
|
|
12770
|
-
sha256: string().optional()
|
|
12782
|
+
sha256: string().optional(),
|
|
12783
|
+
/** Picker/status label; the file basename when absent. */
|
|
12784
|
+
label: string().optional(),
|
|
12785
|
+
sizeBytes: number().optional(),
|
|
12786
|
+
extraFiles: array(ManagedModelExtraFileSchema).optional()
|
|
12771
12787
|
}),
|
|
12772
12788
|
object({
|
|
12773
12789
|
kind: literal("path"),
|
|
@@ -12828,11 +12844,39 @@ var ManagedRuntimeConfigSchema = object({
|
|
|
12828
12844
|
"q4_1",
|
|
12829
12845
|
"q4_0"
|
|
12830
12846
|
]).optional(),
|
|
12847
|
+
/**
|
|
12848
|
+
* Escape hatch for llama-server flags this schema does NOT model — `--jinja`
|
|
12849
|
+
* (which most vision chat templates need and some language-only models
|
|
12850
|
+
* dislike), `--cont-batching`, `--rope-scaling`, …
|
|
12851
|
+
*
|
|
12852
|
+
* It is NOT a second place to set the flags above. A token that collides
|
|
12853
|
+
* with a typed field is REJECTED at start, naming the field that owns it
|
|
12854
|
+
* (`assertNoOwnedFlags`), because two knobs writing the same argv is exactly
|
|
12855
|
+
* the "two switches that disagree" failure this repo has already shipped
|
|
12856
|
+
* twice (D62).
|
|
12857
|
+
*/
|
|
12858
|
+
extraArgs: array(string()).default([]),
|
|
12831
12859
|
/** Else lazy: first generate boots it. */
|
|
12832
12860
|
autoStart: boolean().default(false),
|
|
12833
12861
|
/** 0 = never; frees RAM after quiet periods. */
|
|
12834
12862
|
idleStopMinutes: number().int().default(30)
|
|
12835
12863
|
});
|
|
12864
|
+
/**
|
|
12865
|
+
* Where a multi-GB install currently is. A single 0..1 fraction cannot answer
|
|
12866
|
+
* "is it stuck?" for an install that is three files (shards + mmproj) followed
|
|
12867
|
+
* by a sha256 pass over 22 GB — during which the fraction sat at 1.0 and the
|
|
12868
|
+
* node looked hung. Phase + file + bytes is the smallest shape that does.
|
|
12869
|
+
*/
|
|
12870
|
+
var LlmDownloadProgressSchema = object({
|
|
12871
|
+
phase: _enum(["downloading", "verifying"]),
|
|
12872
|
+
/** The artifact currently moving, e.g. `mmproj-F16.gguf`. */
|
|
12873
|
+
file: string(),
|
|
12874
|
+
fileIndex: number().int(),
|
|
12875
|
+
fileCount: number().int(),
|
|
12876
|
+
/** Across the WHOLE install, not the current file. */
|
|
12877
|
+
downloadedBytes: number(),
|
|
12878
|
+
totalBytes: number().optional()
|
|
12879
|
+
});
|
|
12836
12880
|
var LlmRuntimeStatusSchema = object({
|
|
12837
12881
|
/** Status is ALWAYS node-qualified. */
|
|
12838
12882
|
nodeId: string(),
|
|
@@ -12849,6 +12893,8 @@ var LlmRuntimeStatusSchema = object({
|
|
|
12849
12893
|
modelPath: string().optional(),
|
|
12850
12894
|
modelId: string().optional(),
|
|
12851
12895
|
downloadProgress: number().min(0).max(1).optional(),
|
|
12896
|
+
/** Detail behind `downloadProgress`; present for the same lifetime. */
|
|
12897
|
+
download: LlmDownloadProgressSchema.optional(),
|
|
12852
12898
|
lastError: string().optional(),
|
|
12853
12899
|
crashesInWindow: number(),
|
|
12854
12900
|
/** Child RSS (sampled best-effort). */
|
|
@@ -12859,7 +12905,14 @@ var LlmNodeModelSchema = object({
|
|
|
12859
12905
|
file: string(),
|
|
12860
12906
|
sizeBytes: number(),
|
|
12861
12907
|
catalogId: string().optional(),
|
|
12862
|
-
installedAt: number().optional()
|
|
12908
|
+
installedAt: number().optional(),
|
|
12909
|
+
/**
|
|
12910
|
+
* Absolute path on the node. Present so a file that is on disk but matches
|
|
12911
|
+
* no catalog entry — a custom Hugging Face install, or a GGUF the operator
|
|
12912
|
+
* copied in by hand — is still SELECTABLE, as a `{kind:'path'}` ref. Without
|
|
12913
|
+
* it the picker could list such a file and do nothing with it.
|
|
12914
|
+
*/
|
|
12915
|
+
path: string().optional()
|
|
12863
12916
|
});
|
|
12864
12917
|
var LlmRuntimeDiskUsageSchema = object({
|
|
12865
12918
|
nodeId: string(),
|
|
@@ -12937,9 +12990,12 @@ var LlmProfileSchema = object({
|
|
|
12937
12990
|
systemPrompt: string().optional(),
|
|
12938
12991
|
/** Total generation bound — the only one a unary call has. */
|
|
12939
12992
|
timeoutMs: number().int().positive().default(6e4),
|
|
12940
|
-
/**
|
|
12993
|
+
/** The TCP handshake only — "is the port even open". NOT the wait for
|
|
12994
|
+
* response headers: on the LM Studio / llama-server wire those are written
|
|
12995
|
+
* once the model has finished loading, so they belong to the bound below. */
|
|
12941
12996
|
connectTimeoutMs: number().int().positive().default(1e4),
|
|
12942
|
-
/** Accepted, but no output yet —
|
|
12997
|
+
/** Accepted, but no output yet — response headers included, because a cold
|
|
12998
|
+
* GPU load is exactly what happens before them. */
|
|
12943
12999
|
firstTokenTimeoutMs: number().int().positive().default(12e4),
|
|
12944
13000
|
/** Output started then stopped. */
|
|
12945
13001
|
idleTimeoutMs: number().int().positive().default(6e4),
|
|
@@ -13002,6 +13058,36 @@ var ManagedModelCatalogEntrySchema = object({
|
|
|
13002
13058
|
/** Vision models: companion projector file. */
|
|
13003
13059
|
mmprojUrl: string().optional()
|
|
13004
13060
|
});
|
|
13061
|
+
/**
|
|
13062
|
+
* The outcome of turning one operator-typed Hugging Face reference into a
|
|
13063
|
+
* download plan. A RESULT, never a throw: "this repo has 24 quantizations and
|
|
13064
|
+
* I will not pick for you" is a normal answer the UI has to render, not an
|
|
13065
|
+
* exception.
|
|
13066
|
+
*
|
|
13067
|
+
* `candidates` is the whole reason the refusal is usable — every string in it
|
|
13068
|
+
* is a tag that resolves when pasted back as `<org>/<repo>:<TAG>`.
|
|
13069
|
+
*/
|
|
13070
|
+
var HfModelResolutionSchema = discriminatedUnion("ok", [object({
|
|
13071
|
+
ok: literal(true),
|
|
13072
|
+
/** Ready to hand to `installModel` unchanged. */
|
|
13073
|
+
model: ManagedModelRefSchema,
|
|
13074
|
+
label: string(),
|
|
13075
|
+
repo: string(),
|
|
13076
|
+
quantization: string(),
|
|
13077
|
+
purpose: _enum(["text", "vision"]),
|
|
13078
|
+
totalBytes: number(),
|
|
13079
|
+
/** mmproj + shards, for the preview: an operator approving 23 GB should
|
|
13080
|
+
* see that 0.9 GB of it is a projector they did not name. */
|
|
13081
|
+
extraFilenames: array(string())
|
|
13082
|
+
}), object({
|
|
13083
|
+
ok: literal(false),
|
|
13084
|
+
code: string(),
|
|
13085
|
+
message: string(),
|
|
13086
|
+
candidates: array(string()).optional(),
|
|
13087
|
+
/** Set when the refusal was only the ceiling: re-calling with
|
|
13088
|
+
* `maxBytes: requiredBytes` is the operator's explicit override. */
|
|
13089
|
+
requiredBytes: number().optional()
|
|
13090
|
+
})]);
|
|
13005
13091
|
var LlmRuntimeNodeSchema = object({
|
|
13006
13092
|
nodeId: string(),
|
|
13007
13093
|
reachable: boolean(),
|
|
@@ -13038,6 +13124,15 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }
|
|
|
13038
13124
|
consumer: string().optional(),
|
|
13039
13125
|
profileId: string().optional()
|
|
13040
13126
|
}), array(LlmUsageRollupSchema)), method(object({}), array(ManagedModelCatalogEntrySchema)), method(object({}), array(LlmRuntimeNodeSchema)), method(object({ nodeId: string() }), array(LlmNodeModelSchema)), method(object({
|
|
13127
|
+
/** `https://huggingface.co/<org>/<repo>/resolve/main/<f>.gguf`,
|
|
13128
|
+
* `<org>/<repo>/<f>.gguf`, `<org>/<repo>` or `<org>/<repo>:<QUANT>`. */
|
|
13129
|
+
ref: string(),
|
|
13130
|
+
/** Explicit ceiling override, in bytes. Absent = the built-in ceiling. */
|
|
13131
|
+
maxBytes: number().positive().optional()
|
|
13132
|
+
}), HfModelResolutionSchema, {
|
|
13133
|
+
kind: "mutation",
|
|
13134
|
+
auth: "admin"
|
|
13135
|
+
}), method(object({
|
|
13041
13136
|
nodeId: string(),
|
|
13042
13137
|
model: ManagedModelRefSchema
|
|
13043
13138
|
}), _void(), {
|
|
@@ -19239,6 +19334,17 @@ var maxSessionHoldMsField = {
|
|
|
19239
19334
|
default: 12e4,
|
|
19240
19335
|
step: 5e3
|
|
19241
19336
|
};
|
|
19337
|
+
/**
|
|
19338
|
+
* Quiet period that closes an `audioMode: 'on-motion'` audio window. Floor of
|
|
19339
|
+
* 5s so a rearm can never degenerate into per-event stream churn; default 90s
|
|
19340
|
+
* comfortably outlives the gap between two PIR wakes on a battery camera.
|
|
19341
|
+
*/
|
|
19342
|
+
var audioMotionWindowMsField = {
|
|
19343
|
+
min: 5e3,
|
|
19344
|
+
max: 6e5,
|
|
19345
|
+
default: 9e4,
|
|
19346
|
+
step: 5e3
|
|
19347
|
+
};
|
|
19242
19348
|
var motionFpsField = {
|
|
19243
19349
|
min: 1,
|
|
19244
19350
|
max: 30,
|
|
@@ -19415,6 +19521,27 @@ var RunnerCameraConfigSchema = object({
|
|
|
19415
19521
|
* resolved `CameraDetectionConfig`.
|
|
19416
19522
|
*/
|
|
19417
19523
|
maxSessionHoldMs: number().min(maxSessionHoldMsField.min).max(maxSessionHoldMsField.max).optional(),
|
|
19524
|
+
/**
|
|
19525
|
+
* Orchestrator-side quiet period (ms) that closes an `audioMode:
|
|
19526
|
+
* 'on-motion'` audio window, measured from the LAST motion event.
|
|
19527
|
+
*
|
|
19528
|
+
* This exists because the falling edge cannot be relied on. Camera-native
|
|
19529
|
+
* providers emit motion as a RISING EDGE ONLY (Reolink's Baichuan push and
|
|
19530
|
+
* its email-push SMTP path both emit `detected: true` and never the
|
|
19531
|
+
* counterpart); only the frame-diff analyzer emits falls. So on an
|
|
19532
|
+
* onboard-only camera a window that closed only on `detected: false` never
|
|
19533
|
+
* closed at all, and `on-motion` silently behaved as `always-on` — on a
|
|
19534
|
+
* battery camera, the one failure mode the mode exists to prevent.
|
|
19535
|
+
*
|
|
19536
|
+
* Every motion event rearms this timer WITHOUT restarting the stream, so a
|
|
19537
|
+
* burst of re-fires costs nothing. A falling edge, when one does arrive,
|
|
19538
|
+
* still closes earlier via `motionCooldownMs` — whichever comes first wins.
|
|
19539
|
+
*
|
|
19540
|
+
* Not consumed by the runner: carried here so it shares the per-camera
|
|
19541
|
+
* device-settings surface with `motionCooldownMs`, exactly like
|
|
19542
|
+
* `maxSessionHoldMs`.
|
|
19543
|
+
*/
|
|
19544
|
+
audioMotionWindowMs: number().min(audioMotionWindowMsField.min).max(audioMotionWindowMsField.max).optional(),
|
|
19418
19545
|
motionFps: number().min(motionFpsField.min).max(motionFpsField.max).default(motionFpsField.default),
|
|
19419
19546
|
detectionFps: number().min(detectionFpsField.min).max(detectionFpsField.max).default(detectionFpsField.default),
|
|
19420
19547
|
motionStreamId: string(),
|
|
@@ -19510,7 +19637,7 @@ var RunnerCameraConfigSchema = object({
|
|
|
19510
19637
|
*/
|
|
19511
19638
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
19512
19639
|
});
|
|
19513
|
-
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;
|
|
19640
|
+
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;
|
|
19514
19641
|
/**
|
|
19515
19642
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
19516
19643
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -22224,6 +22351,25 @@ var BatteryStatusSchema = object({
|
|
|
22224
22351
|
/** Ms epoch of the last observation. Lets consumers reason about freshness. */
|
|
22225
22352
|
lastUpdated: number(),
|
|
22226
22353
|
/**
|
|
22354
|
+
* Ms epoch of the last time the device PROVED it was reachable — a
|
|
22355
|
+
* completed firmware round-trip, an observed wake, or an inbound push
|
|
22356
|
+
* (firmware event, email). `0`/absent = never since this slice was born.
|
|
22357
|
+
*
|
|
22358
|
+
* This is the ONLY input that separates "asleep" from "gone", and it is
|
|
22359
|
+
* fed exclusively by PASSIVE signals: nothing may write it by reaching
|
|
22360
|
+
* for the radio, because a poll that confirms reachability is the same
|
|
22361
|
+
* poll that drains the battery. See {@link deriveBatteryPresence} — the
|
|
22362
|
+
* single derivation every consumer must use; no surface computes its own.
|
|
22363
|
+
*
|
|
22364
|
+
* It is deliberately NOT a clock in the
|
|
22365
|
+
* `scripts/check-runtime-state-durability.ts` sense: it is the
|
|
22366
|
+
* observation itself, and it is the only thing a 30-hour silence is
|
|
22367
|
+
* visible in. Writers quantise it (see `CONTACT_WRITE_QUANTUM_MS` in the
|
|
22368
|
+
* Reolink provider) so a value that means "recently" cannot cost a
|
|
22369
|
+
* SQLite commit per round-trip.
|
|
22370
|
+
*/
|
|
22371
|
+
lastContactAt: number().optional(),
|
|
22372
|
+
/**
|
|
22227
22373
|
* True when the source is a BINARY low-battery indicator (HA
|
|
22228
22374
|
* `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
|
|
22229
22375
|
* charge level — `percentage` is then a coarse stand-in (100 = normal,
|
|
@@ -27727,6 +27873,33 @@ method(object({
|
|
|
27727
27873
|
* as `unknown`, never guessed. A day reference scored against an IR frame
|
|
27728
27874
|
* collapses the cosine and would latch a false alarm every single night. */
|
|
27729
27875
|
var SceneConditionSchema = string();
|
|
27876
|
+
/**
|
|
27877
|
+
* What a scene does when the CURRENT light has no reference of its own.
|
|
27878
|
+
*
|
|
27879
|
+
* The lighting variants are not equally likely to exist. Almost every operator
|
|
27880
|
+
* captures daylight and then never stands outside at 22:00 to capture IR, and a
|
|
27881
|
+
* scene that is only ever going to be asked about a daytime question ("is the
|
|
27882
|
+
* bin still on the kerb at 08:00") does not need a night reference at all. The
|
|
27883
|
+
* night half must therefore be OPTIONAL, and optional means the scene keeps
|
|
27884
|
+
* working without it rather than degrading into a permanent complaint.
|
|
27885
|
+
*
|
|
27886
|
+
* - `skip` (default) — the check in that light is not made. Not a verdict, not
|
|
27887
|
+
* an alarm, not even an `unknown`: the live state simply stays whatever the
|
|
27888
|
+
* last covered light left it at, the latch is untouched, and the hysteresis
|
|
27889
|
+
* run is neither spent nor cleared. The scene resumes by itself at first
|
|
27890
|
+
* light. This is the only behaviour under which "I never captured IR" is a
|
|
27891
|
+
* configuration choice instead of a nightly fault.
|
|
27892
|
+
* - `judge-anyway` — score against the OTHER conditions' references. Available
|
|
27893
|
+
* for cameras whose IR frame is close enough to daylight (a floodlit
|
|
27894
|
+
* driveway, an always-white-light doorbell), and wrong for everything else:
|
|
27895
|
+
* cross-condition cosines are not comparable, so a day reference against a
|
|
27896
|
+
* true IR frame collapses and the scene reports a theft at 21:40.
|
|
27897
|
+
*
|
|
27898
|
+
* Never applies when the scene has NO comparable reference at all — that is
|
|
27899
|
+
* "not armed yet", it is reported as `no-reference-for-condition`, and silence
|
|
27900
|
+
* there would hide a scene the operator never finished setting up.
|
|
27901
|
+
*/
|
|
27902
|
+
var SceneUncoveredPolicySchema = _enum(["skip", "judge-anyway"]);
|
|
27730
27903
|
/** Reserved, engine-owned state id standing for "the region no longer looks
|
|
27731
27904
|
* like ANY captured reference". Never authored by an operator, never stored in
|
|
27732
27905
|
* `states[]` — it is the synthetic candidate that makes divergence a
|
|
@@ -27787,6 +27960,9 @@ var SceneCheckSchema = discriminatedUnion("mode", [object({
|
|
|
27787
27960
|
hysteresisCount: number().int().positive()
|
|
27788
27961
|
})]);
|
|
27789
27962
|
var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
|
|
27963
|
+
/** Night is OPTIONAL. A scene with only a daylight reference sits the IR hours
|
|
27964
|
+
* out in silence rather than reporting a fault every night. */
|
|
27965
|
+
var SCENE_DEFAULT_UNCOVERED_POLICY = "skip";
|
|
27790
27966
|
var SCENE_CONFIRM_DEFAULT_TIMEOUT_MS = 8e3;
|
|
27791
27967
|
/**
|
|
27792
27968
|
* Vision-model adjudication of a candidate flip. Field names deliberately
|
|
@@ -27854,6 +28030,21 @@ var SceneMonitorSchema = object({
|
|
|
27854
28030
|
* automation can react to the bin coming back without the operator's own
|
|
27855
28031
|
* alarm silently clearing itself. */
|
|
27856
28032
|
autoRestore: boolean().default(false),
|
|
28033
|
+
/** What to do when the current light has no reference of its own. See
|
|
28034
|
+
* {@link SceneUncoveredPolicySchema} — the default makes night OPTIONAL. */
|
|
28035
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.default(SCENE_DEFAULT_UNCOVERED_POLICY),
|
|
28036
|
+
/**
|
|
28037
|
+
* The light whose checks are currently being SAT OUT under
|
|
28038
|
+
* `onUncoveredCondition: 'skip'` — `null` when the scene is checking normally.
|
|
28039
|
+
*
|
|
28040
|
+
* Engine-reported and advisory only: it moves no verdict, no latch and no
|
|
28041
|
+
* hysteresis. It exists so the card can say *"night (IR) — checks paused,
|
|
28042
|
+
* nothing captured in this light"* in the same calm voice as the coverage
|
|
28043
|
+
* line, because the alternative is a scene that silently stops answering
|
|
28044
|
+
* after sunset with nothing anywhere saying why. A skipped check must never
|
|
28045
|
+
* read as a broken one.
|
|
28046
|
+
*/
|
|
28047
|
+
suspendedCondition: SceneConditionSchema.nullable().default(null),
|
|
27857
28048
|
/** Named cause when `verdict === 'unknown'`. */
|
|
27858
28049
|
unavailable: SceneUnavailableSchema.nullable(),
|
|
27859
28050
|
/** Conditions that have at least one comparable reference — the coverage line
|
|
@@ -27907,6 +28098,7 @@ var sceneMonitorCapability = {
|
|
|
27907
28098
|
minObservationSpacingSec: number().int().min(0).max(3600).optional(),
|
|
27908
28099
|
anchorThreshold: number().min(0).max(1).optional(),
|
|
27909
28100
|
autoRestore: boolean().optional(),
|
|
28101
|
+
onUncoveredCondition: SceneUncoveredPolicySchema.optional(),
|
|
27910
28102
|
/** `null` clears the vision-model adjudicator. */
|
|
27911
28103
|
confirm: SceneConfirmSchema.nullable().optional()
|
|
27912
28104
|
})
|
|
@@ -28205,7 +28397,70 @@ var CamStreamDescriptorSchema = object({
|
|
|
28205
28397
|
/** Transport-specific opaque metadata (e.g. rfc4571 SDP). */
|
|
28206
28398
|
metadata: record(string(), unknown()).optional()
|
|
28207
28399
|
});
|
|
28208
|
-
|
|
28400
|
+
/**
|
|
28401
|
+
* `stream-catalog` — device-scoped, provider-implemented. The pull counterpart
|
|
28402
|
+
* of the removed `publishCameraStream` push: a camera provider returns the full
|
|
28403
|
+
* set of stream descriptors it can offer for the device, synchronously, so the
|
|
28404
|
+
* broker can reconcile its registry against the authoritative provider state.
|
|
28405
|
+
*/
|
|
28406
|
+
/**
|
|
28407
|
+
* The catalog as a DURABLE fact rather than a live answer.
|
|
28408
|
+
*
|
|
28409
|
+
* A battery camera's descriptors are profile-stable — they change when the
|
|
28410
|
+
* operator rewrites an encoder profile, not minute to minute — but building
|
|
28411
|
+
* them costs a Baichuan login, which on a sleeping Argus IS a wake. So the
|
|
28412
|
+
* provider is allowed to build them exactly once per profile and must serve
|
|
28413
|
+
* every later pull from a cache.
|
|
28414
|
+
*
|
|
28415
|
+
* Holding that cache only in RAM is what turned a restart into an outage. The
|
|
28416
|
+
* runner comes back with the camera asleep, `buildStreamCatalogUncached`
|
|
28417
|
+
* correctly refuses to wake it, the pull answers `[]`, the broker has no
|
|
28418
|
+
* cam-stream entry to build a broker from, and `webrtcSession.handleOffer`
|
|
28419
|
+
* fails with a flat "No broker for stream" — for as long as the camera sleeps,
|
|
28420
|
+
* which on a battery cam is most of the day. The camera was fine. The stream
|
|
28421
|
+
* was unreachable because the process had forgotten what the camera offers.
|
|
28422
|
+
*
|
|
28423
|
+
* Declaring it here puts it in `device-runtime-state`, the kernel's canonical
|
|
28424
|
+
* declared collection, with the same `restored` durability `battery` uses for
|
|
28425
|
+
* the same reason: the last known value is the only value there is while the
|
|
28426
|
+
* device is asleep. The broker's brokers are therefore always DEFINABLE — it
|
|
28427
|
+
* is the DIAL that wakes a camera, never the catalog (D173).
|
|
28428
|
+
*/
|
|
28429
|
+
var StreamCatalogStateSchema = object({
|
|
28430
|
+
/** The descriptors as last built from a real camera response. Never a guess:
|
|
28431
|
+
* a failed or refused build writes NOTHING, so a restored catalog is always
|
|
28432
|
+
* one the camera itself once produced. */
|
|
28433
|
+
descriptors: array(CamStreamDescriptorSchema),
|
|
28434
|
+
/** Ms epoch of the build that produced {@link descriptors}. Lets the wake
|
|
28435
|
+
* path decide whether the camera's own awake window is worth spending on a
|
|
28436
|
+
* re-read. */
|
|
28437
|
+
lastFetchedAt: number()
|
|
28438
|
+
});
|
|
28439
|
+
var streamCatalogCapability = {
|
|
28440
|
+
name: "stream-catalog",
|
|
28441
|
+
scope: "device",
|
|
28442
|
+
deviceNative: true,
|
|
28443
|
+
mode: "singleton",
|
|
28444
|
+
deviceTypes: [DeviceType.Camera],
|
|
28445
|
+
methods: { getCatalog: method(object({ deviceId: number().int().nonnegative() }), array(CamStreamDescriptorSchema).readonly()) },
|
|
28446
|
+
runtimeState: StreamCatalogStateSchema,
|
|
28447
|
+
/**
|
|
28448
|
+
* Runtime-state durability: **restored** — see the schema doc. A cold
|
|
28449
|
+
* catalog on a sleeping battery camera is not a slow first frame, it is a
|
|
28450
|
+
* camera that cannot be watched at all until it happens to wake.
|
|
28451
|
+
*
|
|
28452
|
+
* Churn is nil by construction: the slice is written only by a SUCCESSFUL
|
|
28453
|
+
* build, and a build only runs when there is no cached copy (or the copy is
|
|
28454
|
+
* a day old and the camera is awake anyway).
|
|
28455
|
+
*
|
|
28456
|
+
* See `RuntimeStateDurability`. Enforced by
|
|
28457
|
+
* `scripts/check-runtime-state-durability.ts`.
|
|
28458
|
+
*/
|
|
28459
|
+
durability: "restored",
|
|
28460
|
+
/** Clock field: written, but excluded from the compare that decides whether
|
|
28461
|
+
* persisting is worth a SQLite commit — the descriptors are the value. */
|
|
28462
|
+
volatileStateFields: ["lastFetchedAt"]
|
|
28463
|
+
};
|
|
28209
28464
|
/** One of the camera's stream profiles. */
|
|
28210
28465
|
var StreamProfileSchema = _enum([
|
|
28211
28466
|
"main",
|
|
@@ -29909,6 +30164,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
29909
30164
|
sceneMonitor: sceneMonitorCapability,
|
|
29910
30165
|
scriptRunner: scriptRunnerCapability,
|
|
29911
30166
|
smoke: smokeCapability,
|
|
30167
|
+
streamCatalog: streamCatalogCapability,
|
|
29912
30168
|
streamParams: streamParamsCapability,
|
|
29913
30169
|
switch: switchCapability,
|
|
29914
30170
|
tamper: tamperCapability,
|
|
@@ -32795,6 +33051,12 @@ Object.freeze({
|
|
|
32795
33051
|
addonId: null,
|
|
32796
33052
|
access: "view"
|
|
32797
33053
|
},
|
|
33054
|
+
"llm.resolveModelRef": {
|
|
33055
|
+
capName: "llm",
|
|
33056
|
+
capScope: "system",
|
|
33057
|
+
addonId: null,
|
|
33058
|
+
access: "create"
|
|
33059
|
+
},
|
|
32798
33060
|
"llm.setDefault": {
|
|
32799
33061
|
capName: "llm",
|
|
32800
33062
|
capScope: "system",
|
|
@@ -38730,6 +38992,12 @@ Object.defineProperty(exports, "SCENE_DEFAULT_ANCHOR_THRESHOLD", {
|
|
|
38730
38992
|
return SCENE_DEFAULT_ANCHOR_THRESHOLD;
|
|
38731
38993
|
}
|
|
38732
38994
|
});
|
|
38995
|
+
Object.defineProperty(exports, "SCENE_DEFAULT_UNCOVERED_POLICY", {
|
|
38996
|
+
enumerable: true,
|
|
38997
|
+
get: function() {
|
|
38998
|
+
return SCENE_DEFAULT_UNCOVERED_POLICY;
|
|
38999
|
+
}
|
|
39000
|
+
});
|
|
38733
39001
|
Object.defineProperty(exports, "SCENE_DIVERGED", {
|
|
38734
39002
|
enumerable: true,
|
|
38735
39003
|
get: function() {
|