@camstack/addon-post-analysis 1.2.75 → 1.2.77
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-DseTbokb.js → dist-Bs6oboqZ.js} +354 -50
- package/dist/{dist-BA7ThdEJ.mjs → dist-CxeFHSSV.mjs} +349 -51
- 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-YItCXmVN.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-BP6Na43Q.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-DFckpC3K.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-DRCS32f_.mjs → hostInit-DTI0jC8p.mjs} +2 -2
- package/dist/pipeline-analytics/index.js +2697 -1090
- package/dist/pipeline-analytics/index.mjs +2660 -1090
- 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-BgpX7t50.mjs +0 -26
|
@@ -5396,12 +5396,6 @@ Object.fromEntries([
|
|
|
5396
5396
|
icon: "shapes",
|
|
5397
5397
|
order: 38
|
|
5398
5398
|
},
|
|
5399
|
-
{
|
|
5400
|
-
id: "scenes",
|
|
5401
|
-
label: "Scenes",
|
|
5402
|
-
icon: "scan-eye",
|
|
5403
|
-
order: 36
|
|
5404
|
-
},
|
|
5405
5399
|
{
|
|
5406
5400
|
id: "analytics",
|
|
5407
5401
|
label: "Analytics",
|
|
@@ -12675,6 +12669,17 @@ var LlmImageSchema = object({
|
|
|
12675
12669
|
bytes: _instanceof(Uint8Array),
|
|
12676
12670
|
mimeType: string()
|
|
12677
12671
|
});
|
|
12672
|
+
/**
|
|
12673
|
+
* Retry policy. `enabled: false` is NOT the same as `maxAttempts: 1` in intent —
|
|
12674
|
+
* the flag is what a consumer table flips, the count is what the operator tunes.
|
|
12675
|
+
* A retry doubles the wall time of a call, so the two gates that run inside a
|
|
12676
|
+
* notification's budget keep it off (see `CONSUMER_RETRY_POLICY` in addon-ai).
|
|
12677
|
+
*/
|
|
12678
|
+
var LlmRetryPolicySchema = object({
|
|
12679
|
+
enabled: boolean().default(false),
|
|
12680
|
+
/** Total attempts INCLUDING the first. 1 = no retry. */
|
|
12681
|
+
maxAttempts: number().int().min(1).max(5).default(1)
|
|
12682
|
+
});
|
|
12678
12683
|
var LlmGenerateBaseInputSchema = object({
|
|
12679
12684
|
/** Collection routing (the notification-output posture). */
|
|
12680
12685
|
addonId: string().optional(),
|
|
@@ -12689,7 +12694,28 @@ var LlmGenerateBaseInputSchema = object({
|
|
|
12689
12694
|
jsonSchema: record(string(), unknown()).optional(),
|
|
12690
12695
|
/** Per-call override of the profile default. */
|
|
12691
12696
|
maxTokens: number().int().positive().optional(),
|
|
12692
|
-
temperature: number().optional()
|
|
12697
|
+
temperature: number().optional(),
|
|
12698
|
+
/** Per-call override of the profile default (nucleus sampling). */
|
|
12699
|
+
topP: number().min(0).max(1).optional(),
|
|
12700
|
+
/** Per-call override of the profile default (top-k sampling). */
|
|
12701
|
+
topK: number().int().positive().optional(),
|
|
12702
|
+
/** Per-call override of `profile.timeoutMs` — the total generation bound. */
|
|
12703
|
+
timeoutMs: number().int().positive().optional(),
|
|
12704
|
+
/** Per-call override; beats both the consumer table and the profile. */
|
|
12705
|
+
retry: LlmRetryPolicySchema.optional(),
|
|
12706
|
+
/**
|
|
12707
|
+
* Caller-minted id that makes this generation CANCELLABLE.
|
|
12708
|
+
*
|
|
12709
|
+
* Without it a caller that stops waiting cannot stop the work: the gates race
|
|
12710
|
+
* the call against 8 s and free their own slot when the timer wins, while the
|
|
12711
|
+
* generation upstream keeps running to `profile.timeoutMs` — 60 s by default,
|
|
12712
|
+
* on a single-threaded local model. The per-camera bound then counts WAITS,
|
|
12713
|
+
* not generations, and the real load is unbounded.
|
|
12714
|
+
*
|
|
12715
|
+
* `AbortSignal` cannot cross a process boundary; an id can. Pass one here and
|
|
12716
|
+
* `llm.cancel({ requestId })` tears the socket down.
|
|
12717
|
+
*/
|
|
12718
|
+
requestId: string().optional()
|
|
12693
12719
|
});
|
|
12694
12720
|
/**
|
|
12695
12721
|
* `llm-runtime` — node-side managed llama.cpp executor (spec §4). Registered
|
|
@@ -12728,8 +12754,49 @@ var ManagedRuntimeConfigSchema = object({
|
|
|
12728
12754
|
gpuLayers: number().int().default(0),
|
|
12729
12755
|
/** Default: cpus-2, clamped ≥1 (resolved node-side). */
|
|
12730
12756
|
threads: number().int().optional(),
|
|
12731
|
-
/** Concurrent slots. */
|
|
12757
|
+
/** Concurrent slots (`--parallel`). */
|
|
12732
12758
|
parallel: number().int().default(1),
|
|
12759
|
+
/** Logical batch size (`-b`). Larger = faster prompt ingest, more RAM. */
|
|
12760
|
+
batchSize: number().int().positive().optional(),
|
|
12761
|
+
/** Physical batch / micro-batch (`-ub`). */
|
|
12762
|
+
ubatchSize: number().int().positive().optional(),
|
|
12763
|
+
/**
|
|
12764
|
+
* `--flash-attn`. Cuts KV-cache memory on the backends that implement it and
|
|
12765
|
+
* is a no-op elsewhere, so it is offered rather than assumed.
|
|
12766
|
+
*/
|
|
12767
|
+
flashAttention: boolean().default(false),
|
|
12768
|
+
/**
|
|
12769
|
+
* `--mlock`. Pins the weights in RAM so the OS cannot page them out mid
|
|
12770
|
+
* inference. Costs the full model size in resident memory — which is exactly
|
|
12771
|
+
* what the RAM budget is counting.
|
|
12772
|
+
*/
|
|
12773
|
+
mlock: boolean().default(false),
|
|
12774
|
+
/**
|
|
12775
|
+
* `--no-mmap`. Reads the whole GGUF up front instead of mapping it. Slower to
|
|
12776
|
+
* start, but avoids the page-fault stalls a network or spinning-disk model
|
|
12777
|
+
* store produces on every first token.
|
|
12778
|
+
*/
|
|
12779
|
+
noMmap: boolean().default(false),
|
|
12780
|
+
/** `--cache-type-k` / `--cache-type-v` — quantising the KV cache is the
|
|
12781
|
+
* cheapest way to fit a longer context in the same RAM. */
|
|
12782
|
+
cacheTypeK: _enum([
|
|
12783
|
+
"f32",
|
|
12784
|
+
"f16",
|
|
12785
|
+
"q8_0",
|
|
12786
|
+
"q5_1",
|
|
12787
|
+
"q5_0",
|
|
12788
|
+
"q4_1",
|
|
12789
|
+
"q4_0"
|
|
12790
|
+
]).optional(),
|
|
12791
|
+
cacheTypeV: _enum([
|
|
12792
|
+
"f32",
|
|
12793
|
+
"f16",
|
|
12794
|
+
"q8_0",
|
|
12795
|
+
"q5_1",
|
|
12796
|
+
"q5_0",
|
|
12797
|
+
"q4_1",
|
|
12798
|
+
"q4_0"
|
|
12799
|
+
]).optional(),
|
|
12733
12800
|
/** Else lazy: first generate boots it. */
|
|
12734
12801
|
autoStart: boolean().default(false),
|
|
12735
12802
|
/** 0 = never; frees RAM after quiet periods. */
|
|
@@ -12817,10 +12884,44 @@ var LlmProfileSchema = object({
|
|
|
12817
12884
|
baseUrl: string().optional(),
|
|
12818
12885
|
/** ConfigUISchema type:'password' — never round-trips (spec §5). */
|
|
12819
12886
|
apiKey: string().optional(),
|
|
12887
|
+
/** Vision on/off. A vision call against a `false` profile is REFUSED, never
|
|
12888
|
+
* degraded to text — that shipped once and produced a confident answer to a
|
|
12889
|
+
* question about a picture nobody sent. */
|
|
12820
12890
|
supportsVision: boolean(),
|
|
12821
12891
|
temperature: number().min(0).max(2).optional(),
|
|
12892
|
+
/** Nucleus sampling. Every wire we speak has it. */
|
|
12893
|
+
topP: number().min(0).max(1).optional(),
|
|
12894
|
+
/** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
|
|
12895
|
+
* wire does, and the client drops it there (measured: the request body gets
|
|
12896
|
+
* `top_p` and no `top_k`). The profile editor hides the field wherever it
|
|
12897
|
+
* would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
|
|
12898
|
+
topK: number().int().positive().optional(),
|
|
12822
12899
|
maxTokens: number().int().positive().optional(),
|
|
12900
|
+
/** Prompt context window. Advisory for cloud kinds (they enforce their own);
|
|
12901
|
+
* for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
|
|
12902
|
+
* the model with, so it is the one field that changes a PROCESS. */
|
|
12903
|
+
contextLength: number().int().positive().optional(),
|
|
12904
|
+
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
12905
|
+
* two system prompts fighting is worse than either alone). */
|
|
12906
|
+
systemPrompt: string().optional(),
|
|
12907
|
+
/** Total generation bound — the only one a unary call has. */
|
|
12823
12908
|
timeoutMs: number().int().positive().default(6e4),
|
|
12909
|
+
/** Wait for response headers only. */
|
|
12910
|
+
connectTimeoutMs: number().int().positive().default(1e4),
|
|
12911
|
+
/** Accepted, but no output yet — a cold GPU load lives here. */
|
|
12912
|
+
firstTokenTimeoutMs: number().int().positive().default(12e4),
|
|
12913
|
+
/** Output started then stopped. */
|
|
12914
|
+
idleTimeoutMs: number().int().positive().default(6e4),
|
|
12915
|
+
/** Profile-level default. The per-consumer table and a per-call override
|
|
12916
|
+
* both beat it — see `resolveRetryPolicy`. */
|
|
12917
|
+
retry: LlmRetryPolicySchema.default({
|
|
12918
|
+
enabled: false,
|
|
12919
|
+
maxAttempts: 1
|
|
12920
|
+
}),
|
|
12921
|
+
/** Whether this profile may use tools. The tool-call plumbing rides the
|
|
12922
|
+
* library; the REGISTRY of callable tools is ours and is empty in v1, so a
|
|
12923
|
+
* `true` here buys the wiring, not behaviour, until tools are registered. */
|
|
12924
|
+
toolsEnabled: boolean().default(false),
|
|
12824
12925
|
extraHeaders: record(string(), string()).optional(),
|
|
12825
12926
|
/** kind === 'managed-local' only (spec §4). */
|
|
12826
12927
|
runtime: ManagedRuntimeConfigSchema.optional()
|
|
@@ -12882,7 +12983,10 @@ var ProfileRefInputSchema = object({
|
|
|
12882
12983
|
addonId: string(),
|
|
12883
12984
|
profileId: string()
|
|
12884
12985
|
});
|
|
12885
|
-
method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
|
|
12986
|
+
method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
|
|
12987
|
+
addonId: string().optional(),
|
|
12988
|
+
requestId: string()
|
|
12989
|
+
}), _void(), { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
|
|
12886
12990
|
kind: "mutation",
|
|
12887
12991
|
auth: "admin"
|
|
12888
12992
|
}), method(ProfileRefInputSchema, _void(), {
|
|
@@ -14724,28 +14828,36 @@ var NcOccupancyConditionSchema = object({
|
|
|
14724
14828
|
/**
|
|
14725
14829
|
* Audio condition (IMMEDIATE trigger) — a rule on SOUND, not on a picture.
|
|
14726
14830
|
*
|
|
14727
|
-
*
|
|
14728
|
-
*
|
|
14729
|
-
*
|
|
14730
|
-
*
|
|
14731
|
-
*
|
|
14732
|
-
*
|
|
14733
|
-
*
|
|
14734
|
-
*
|
|
14735
|
-
*
|
|
14736
|
-
*
|
|
14737
|
-
*
|
|
14738
|
-
*
|
|
14739
|
-
*
|
|
14740
|
-
*
|
|
14741
|
-
*
|
|
14742
|
-
*
|
|
14743
|
-
*
|
|
14744
|
-
*
|
|
14745
|
-
*
|
|
14746
|
-
*
|
|
14747
|
-
*
|
|
14748
|
-
* `
|
|
14831
|
+
* **TWO EXCLUSIVE MODES** (operator decision 2026-08-14, D157). Which one a
|
|
14832
|
+
* rule is in is not a stored field — it is WHICH FILTER the rule carries, so
|
|
14833
|
+
* there is no second switch that can disagree with the first and every rule
|
|
14834
|
+
* authored before the decision migrates for free (`audioModeOf`):
|
|
14835
|
+
*
|
|
14836
|
+
* - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
|
|
14837
|
+
* classifier labels with one of them. No window, no percentage:
|
|
14838
|
+
* `hitPercent` and `samplingSeconds` are ignored, and the rule's own
|
|
14839
|
+
* `throttle` cooldown is the only brake. The per-label confidence floor is
|
|
14840
|
+
* the analyzer's (`classificationMinScore`, per device) — a label only
|
|
14841
|
+
* reaches this condition if the classifier was already confident enough.
|
|
14842
|
+
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14843
|
+
* the condition: at least `hitPercent`% of the samples over
|
|
14844
|
+
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
14845
|
+
* {@link NC_AUDIO_DBFS_FLOOR}: negative-going, `0` = full scale). The window
|
|
14846
|
+
* must be FULL before it can match — a window open for two of its ten
|
|
14847
|
+
* seconds is 100% of nothing.
|
|
14848
|
+
*
|
|
14849
|
+
* **Why label mode has no window.** It had one, and it never fired: the
|
|
14850
|
+
* analyzer emits ~1 audio frame per second but YAMNet only LABELS one to three
|
|
14851
|
+
* of them per episode, even through continuous crying. The measured maximum
|
|
14852
|
+
* `hitPercent` over the whole live history was 40 — under the shipped default
|
|
14853
|
+
* of 60, so a label rule could not fire at all, ever. A percentage of frames is
|
|
14854
|
+
* the wrong question to ask of a sparse classifier.
|
|
14855
|
+
*
|
|
14856
|
+
* **Fail-closed when NEITHER is given** — every sample would be a trivial hit
|
|
14857
|
+
* and the rule would fire on silence. The schema cannot express "exactly one
|
|
14858
|
+
* of" without becoming a ZodEffects the cap path would have to special-case, so
|
|
14859
|
+
* the exclusivity is enforced where every editor writes (`patchAudio`) and a
|
|
14860
|
+
* legacy rule carrying both resolves to LABEL (the mode that fires).
|
|
14749
14861
|
*
|
|
14750
14862
|
* Labels are the audio macro classes (`AUDIO_MACRO_LABELS` / the NC taxonomy's
|
|
14751
14863
|
* `audio-*` ids). Both spellings are accepted — the matcher normalizes the
|
|
@@ -14753,13 +14865,13 @@ var NcOccupancyConditionSchema = object({
|
|
|
14753
14865
|
* an operator who typed `dog` mean the same thing.
|
|
14754
14866
|
*/
|
|
14755
14867
|
var NcAudioConditionSchema = object({
|
|
14756
|
-
/**
|
|
14868
|
+
/** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
|
|
14757
14869
|
labels: array(string().min(1)).min(1).optional(),
|
|
14758
|
-
/**
|
|
14870
|
+
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14759
14871
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14760
|
-
/**
|
|
14872
|
+
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14761
14873
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14762
|
-
/**
|
|
14874
|
+
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14763
14875
|
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14764
14876
|
});
|
|
14765
14877
|
/**
|
|
@@ -14897,13 +15009,81 @@ var NcRuleActionsSchema = object({
|
|
|
14897
15009
|
*/
|
|
14898
15010
|
buttons: array(NcRuleNotificationButtonSchema).max(8).optional()
|
|
14899
15011
|
});
|
|
15012
|
+
/**
|
|
15013
|
+
* "This rule applies only while `deviceId` is in one of `states`."
|
|
15014
|
+
*
|
|
15015
|
+
* The states are the DEVICE's own vocabulary — `AlarmState` for a panel,
|
|
15016
|
+
* `on`/`off` for a switch — not a normalised set, because normalising would
|
|
15017
|
+
* make the condition lie about devices whose states have no equivalent.
|
|
15018
|
+
*
|
|
15019
|
+
* An unreadable state does NOT match: see the engine's fail-closed gate. A
|
|
15020
|
+
* condition that fired on "I could not read it" would be worse than no gate.
|
|
15021
|
+
*/
|
|
15022
|
+
var NcDeviceStateConditionSchema = object({
|
|
15023
|
+
deviceId: number().int(),
|
|
15024
|
+
/** Any of these matches. */
|
|
15025
|
+
states: array(string().min(1)).min(1)
|
|
15026
|
+
});
|
|
15027
|
+
/**
|
|
15028
|
+
* "This rule applies only while scene `sceneId` is `matched` / `diverged`."
|
|
15029
|
+
*
|
|
15030
|
+
* A GATE, not a trigger. `occupancy` and `audio` each DISCRIMINATE their rule —
|
|
15031
|
+
* carrying one makes the rule fire on that subject and nothing else. Scene is
|
|
15032
|
+
* the other shape entirely, the `deviceState` shape: it narrows a rule that
|
|
15033
|
+
* already has a trigger ("tell me about a person at the front door, but only
|
|
15034
|
+
* while the bin is still out"). That is why it composes with every delivery
|
|
15035
|
+
* instead of owning one, and why no new `NcDelivery` member and no new subject
|
|
15036
|
+
* kind exist for it — see D159.
|
|
15037
|
+
*
|
|
15038
|
+
* ── Identity ───────────────────────────────────────────────────────────────
|
|
15039
|
+
* `sceneId` is `SceneMonitor.id`, a `randomUUID()` minted by `createScene` —
|
|
15040
|
+
* globally unique, so it needs no device to disambiguate it. `deviceId` is
|
|
15041
|
+
* carried as a HINT for the editor and for the log line, never as part of the
|
|
15042
|
+
* lookup key: a rule whose hint drifted must still gate correctly.
|
|
15043
|
+
*
|
|
15044
|
+
* ── Which boolean ──────────────────────────────────────────────────────────
|
|
15045
|
+
* `latched` ABSENT means "whatever the scene itself says" — `SceneMonitor.emit`
|
|
15046
|
+
* already declares which boolean drives notification rules, and a second knob
|
|
15047
|
+
* that could disagree with it is exactly the D62 failure. Set it only to
|
|
15048
|
+
* override one rule against the scene's own default.
|
|
15049
|
+
*
|
|
15050
|
+
* - LIVE reading (`emit`/`latched` resolve to live): passes iff
|
|
15051
|
+
* `verdict === requiredState`. `unknown` — no reference for this light, view
|
|
15052
|
+
* shifted, no snapshot — passes NEITHER. A scene that cannot judge is not
|
|
15053
|
+
* evidence, in either direction.
|
|
15054
|
+
* - LATCHED reading: passes iff `latched === (requiredState === 'diverged')`.
|
|
15055
|
+
* The latch is a durable fact about the past ("it has diverged since I armed
|
|
15056
|
+
* it"), so a camera that has gone dark does not clear it — that is the whole
|
|
15057
|
+
* reason the operator asked for a latch.
|
|
15058
|
+
*
|
|
15059
|
+
* The gate reads an in-memory mirror (`NcSceneStateCache`) refreshed OFF the
|
|
15060
|
+
* event path, never the cap: D49. A mirror that has never loaded, or a scene it
|
|
15061
|
+
* does not carry, reads absent and the rule does NOT fire — fail closed, and
|
|
15062
|
+
* said out loud in the log rather than dropped in silence.
|
|
15063
|
+
*/
|
|
15064
|
+
var NcSceneConditionSchema = object({
|
|
15065
|
+
/** `SceneMonitor.id` — the uuid the cap mints. The whole lookup key. */
|
|
15066
|
+
sceneId: string().min(1),
|
|
15067
|
+
/** The camera the scene lives on. A hint for the editor and the log line. */
|
|
15068
|
+
deviceId: number().int().optional(),
|
|
15069
|
+
/** The state the scene must be in for the rule to fire. */
|
|
15070
|
+
requiredState: _enum(["matched", "diverged"]),
|
|
15071
|
+
/**
|
|
15072
|
+
* Read the LATCH (`true`) or the LIVE verdict (`false`). Absent = follow the
|
|
15073
|
+
* scene's own `emit` field, which is the only place that decision belongs.
|
|
15074
|
+
*/
|
|
15075
|
+
latched: boolean().optional()
|
|
15076
|
+
});
|
|
14900
15077
|
var NcConditionsSchema = object({
|
|
14901
15078
|
/** Gate on ANOTHER device's current state (the alarm armed, a switch on). */
|
|
14902
|
-
deviceState:
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
15079
|
+
deviceState: NcDeviceStateConditionSchema.optional(),
|
|
15080
|
+
/**
|
|
15081
|
+
* Gate on a SCENE's state — "only while the bin is still out". Composes with
|
|
15082
|
+
* every trigger (detection, occupancy, audio, sensor, package, track-end);
|
|
15083
|
+
* unlike `occupancy`/`audio` it discriminates nothing. See
|
|
15084
|
+
* {@link NcSceneCondition} and D159.
|
|
15085
|
+
*/
|
|
15086
|
+
scene: NcSceneConditionSchema.optional(),
|
|
14907
15087
|
/** Device scope — absent = all devices. */
|
|
14908
15088
|
devices: array(number()).optional(),
|
|
14909
15089
|
/** Detector class names (any overlap with the record's class set). */
|
|
@@ -15541,6 +15721,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
15541
15721
|
"occupancy",
|
|
15542
15722
|
"audio",
|
|
15543
15723
|
"deviceState",
|
|
15724
|
+
"scene",
|
|
15544
15725
|
"systemEvent"
|
|
15545
15726
|
]),
|
|
15546
15727
|
operator: _enum([
|
|
@@ -15895,6 +16076,21 @@ var NC_CONDITION_CATALOG = [
|
|
|
15895
16076
|
phase: "P2",
|
|
15896
16077
|
description: "Only fire while another device is in one of the chosen states — the alarm armed, a switch on, a contact closed. A state that cannot be read does NOT fire."
|
|
15897
16078
|
},
|
|
16079
|
+
{
|
|
16080
|
+
id: "scene",
|
|
16081
|
+
group: "scope",
|
|
16082
|
+
label: "Scene state",
|
|
16083
|
+
valueType: "scene",
|
|
16084
|
+
operator: "in",
|
|
16085
|
+
appliesTo: [
|
|
16086
|
+
"immediate",
|
|
16087
|
+
"track-end",
|
|
16088
|
+
"device-event",
|
|
16089
|
+
"package-event"
|
|
16090
|
+
],
|
|
16091
|
+
phase: "P3",
|
|
16092
|
+
description: "Only fire while a scene is matched (the baseline is what we see) or diverged (it demonstrably is not) — “tell me about a person at the door, but only while the bin is still out”. A scene that cannot judge, or one this hub has not read yet, does NOT fire."
|
|
16093
|
+
},
|
|
15898
16094
|
{
|
|
15899
16095
|
id: "sensorKinds",
|
|
15900
16096
|
group: "device",
|
|
@@ -27474,10 +27670,22 @@ method(object({
|
|
|
27474
27670
|
* thing except the comparator: `similarity` (CLIP cosine at the same ROI coords
|
|
27475
27671
|
* vs condition-tagged references) and `llm` (vision-LLM judgment over the crop).
|
|
27476
27672
|
*
|
|
27477
|
-
*
|
|
27478
|
-
*
|
|
27479
|
-
*
|
|
27480
|
-
*
|
|
27673
|
+
* **No `deviceConfig`, deliberately.** This shipped as the D14 widget archetype,
|
|
27674
|
+
* which put a "Scenes" tab on one camera's detail page. That is the wrong shape
|
|
27675
|
+
* for the thing: a scene is a standing question about the property ("is the bin
|
|
27676
|
+
* still out"), and the operator's question is "which of my scenes have tripped",
|
|
27677
|
+
* across every camera at once — not "what does camera 617 think". Buried one
|
|
27678
|
+
* camera deep it also could not be found. The surface is now a top-level admin
|
|
27679
|
+
* page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
|
|
27680
|
+
* picks the camera inside the create flow, the same shape Events and Faces have.
|
|
27681
|
+
*
|
|
27682
|
+
* The consequence to keep in mind: `host/scene-monitor-editor` is gone from
|
|
27683
|
+
* `HOST_WIDGETS` too. `scripts/check-host-widget-resolves.ts` asserts BOTH
|
|
27684
|
+
* directions, so a registration nobody declares fails exactly as loudly as a
|
|
27685
|
+
* declaration nobody registers. The editor is imported directly by the page.
|
|
27686
|
+
*
|
|
27687
|
+
* `status.kind:'push'` — the engine pushes on every hysteresis flip /
|
|
27688
|
+
* availability change; consumers never poll.
|
|
27481
27689
|
*/
|
|
27482
27690
|
/** Extensible condition tag. Seeded 'day' | 'ir' (the two variants the operator
|
|
27483
27691
|
* captures) plus 'night' | 'dawn' | 'dusk' from the resolver's sun-times band.
|
|
@@ -27632,12 +27840,6 @@ var sceneMonitorCapability = {
|
|
|
27632
27840
|
kind: "wrapper",
|
|
27633
27841
|
defaultActive: true,
|
|
27634
27842
|
deviceTypes: [DeviceType.Camera],
|
|
27635
|
-
deviceConfig: { ui: {
|
|
27636
|
-
kind: "widget",
|
|
27637
|
-
widgetId: "host/scene-monitor-editor",
|
|
27638
|
-
tab: "scenes",
|
|
27639
|
-
label: "Scenes"
|
|
27640
|
-
} },
|
|
27641
27843
|
methods: {
|
|
27642
27844
|
listScenes: method(object({ deviceId: number() }), SceneMonitorStatusSchema),
|
|
27643
27845
|
createScene: method(object({
|
|
@@ -28226,12 +28428,64 @@ var NetworkAddressSchema = object({
|
|
|
28226
28428
|
family: string(),
|
|
28227
28429
|
internal: boolean()
|
|
28228
28430
|
});
|
|
28431
|
+
/**
|
|
28432
|
+
* Provenance of the site coordinates, and the whole reason this is not just two
|
|
28433
|
+
* numbers.
|
|
28434
|
+
*
|
|
28435
|
+
* - `operator-set` — a human typed it, or accepted a detection. Authoritative;
|
|
28436
|
+
* nothing overwrites it.
|
|
28437
|
+
* - `derived-from-ip` — the hub geolocated its own public IP once, because a
|
|
28438
|
+
* default that is right to a few kilometres beats the coarse UTC clock split
|
|
28439
|
+
* the sun-times consumers otherwise fall back to.
|
|
28440
|
+
*
|
|
28441
|
+
* The UI shows which one it is. An operator who cannot tell a guess from their
|
|
28442
|
+
* own input will eventually trust the guess.
|
|
28443
|
+
*/
|
|
28444
|
+
var SiteLocationSourceSchema = _enum(["operator-set", "derived-from-ip"]);
|
|
28445
|
+
/**
|
|
28446
|
+
* The read shape: the location plus the honest state of the one-shot derivation.
|
|
28447
|
+
*
|
|
28448
|
+
* `derivationAttemptedAt` is what makes the "one call, ever" contract
|
|
28449
|
+
* inspectable. When it is set and `location` is null, the geo-IP lookup ran and
|
|
28450
|
+
* failed; the hub will NOT try again on its own — the fallback is declared
|
|
28451
|
+
* (consumers degrade to their own last resort) and the operator either types the
|
|
28452
|
+
* coordinates or presses detect.
|
|
28453
|
+
*/
|
|
28454
|
+
var SiteLocationStatusSchema = object({
|
|
28455
|
+
location: object({
|
|
28456
|
+
/** WGS84 decimal degrees. */
|
|
28457
|
+
latitude: number().min(-90).max(90),
|
|
28458
|
+
longitude: number().min(-180).max(180),
|
|
28459
|
+
source: SiteLocationSourceSchema,
|
|
28460
|
+
/** Epoch ms the value was last written. */
|
|
28461
|
+
updatedAt: number(),
|
|
28462
|
+
/**
|
|
28463
|
+
* Human-readable place the geo-IP service reported ("Napoli, IT"). Display
|
|
28464
|
+
* only — never parsed, never matched on. Absent for an operator-typed value.
|
|
28465
|
+
*/
|
|
28466
|
+
label: string().optional()
|
|
28467
|
+
}).nullable(),
|
|
28468
|
+
derivationAttemptedAt: number().nullable(),
|
|
28469
|
+
/** Why the last derivation failed, for the UI to show instead of a shrug. */
|
|
28470
|
+
derivationError: string().nullable()
|
|
28471
|
+
});
|
|
28472
|
+
/** `null` clears the location and re-arms nothing — the derivation stays spent. */
|
|
28473
|
+
var SetSiteLocationInputSchema = object({
|
|
28474
|
+
latitude: number().min(-90).max(90),
|
|
28475
|
+
longitude: number().min(-180).max(180)
|
|
28476
|
+
}).nullable();
|
|
28229
28477
|
method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), method(_void(), FeatureManifestSchema), method(_void(), array(NetworkAddressSchema).readonly()), method(_void(), unknown().nullable(), { auth: "admin" }), method(record(string(), unknown()), _null(), {
|
|
28230
28478
|
kind: "mutation",
|
|
28231
28479
|
auth: "admin"
|
|
28232
28480
|
}), method(_void(), _void(), {
|
|
28233
28481
|
kind: "mutation",
|
|
28234
28482
|
auth: "admin"
|
|
28483
|
+
}), method(_void(), SiteLocationStatusSchema), method(SetSiteLocationInputSchema, SiteLocationStatusSchema, {
|
|
28484
|
+
kind: "mutation",
|
|
28485
|
+
auth: "admin"
|
|
28486
|
+
}), method(_void(), SiteLocationStatusSchema, {
|
|
28487
|
+
kind: "mutation",
|
|
28488
|
+
auth: "admin"
|
|
28235
28489
|
});
|
|
28236
28490
|
/**
|
|
28237
28491
|
* Tamper / case-open detection sensor. Drives Home Assistant
|
|
@@ -32420,6 +32674,12 @@ Object.freeze({
|
|
|
32420
32674
|
addonId: null,
|
|
32421
32675
|
access: "create"
|
|
32422
32676
|
},
|
|
32677
|
+
"llm.cancel": {
|
|
32678
|
+
capName: "llm",
|
|
32679
|
+
capScope: "system",
|
|
32680
|
+
addonId: null,
|
|
32681
|
+
access: "create"
|
|
32682
|
+
},
|
|
32423
32683
|
"llm.deleteModel": {
|
|
32424
32684
|
capName: "llm",
|
|
32425
32685
|
capScope: "system",
|
|
@@ -35354,6 +35614,12 @@ Object.freeze({
|
|
|
35354
35614
|
addonId: null,
|
|
35355
35615
|
access: "create"
|
|
35356
35616
|
},
|
|
35617
|
+
"system.detectSiteLocation": {
|
|
35618
|
+
capName: "system",
|
|
35619
|
+
capScope: "system",
|
|
35620
|
+
addonId: null,
|
|
35621
|
+
access: "create"
|
|
35622
|
+
},
|
|
35357
35623
|
"system.featureFlags": {
|
|
35358
35624
|
capName: "system",
|
|
35359
35625
|
capScope: "system",
|
|
@@ -35372,6 +35638,12 @@ Object.freeze({
|
|
|
35372
35638
|
addonId: null,
|
|
35373
35639
|
access: "view"
|
|
35374
35640
|
},
|
|
35641
|
+
"system.getSiteLocation": {
|
|
35642
|
+
capName: "system",
|
|
35643
|
+
capScope: "system",
|
|
35644
|
+
addonId: null,
|
|
35645
|
+
access: "view"
|
|
35646
|
+
},
|
|
35375
35647
|
"system.health": {
|
|
35376
35648
|
capName: "system",
|
|
35377
35649
|
capScope: "system",
|
|
@@ -35396,6 +35668,12 @@ Object.freeze({
|
|
|
35396
35668
|
addonId: null,
|
|
35397
35669
|
access: "create"
|
|
35398
35670
|
},
|
|
35671
|
+
"system.setSiteLocation": {
|
|
35672
|
+
capName: "system",
|
|
35673
|
+
capScope: "system",
|
|
35674
|
+
addonId: null,
|
|
35675
|
+
access: "create"
|
|
35676
|
+
},
|
|
35399
35677
|
"terminalSession.adoptLegacyMonitor": {
|
|
35400
35678
|
capName: "terminal-session",
|
|
35401
35679
|
capScope: "system",
|
|
@@ -37653,6 +37931,26 @@ Object.freeze({
|
|
|
37653
37931
|
"network-access": "ingress",
|
|
37654
37932
|
"smtp-provider": "email"
|
|
37655
37933
|
});
|
|
37934
|
+
/**
|
|
37935
|
+
* Which mode this condition is in — the ONE place that question is answered.
|
|
37936
|
+
*
|
|
37937
|
+
* The mode is NOT a stored field, deliberately. It is which filter the rule
|
|
37938
|
+
* carries, so every rule authored before the modes existed migrates for free
|
|
37939
|
+
* and there is no second switch that can disagree with the first (the failure
|
|
37940
|
+
* this repo has shipped twice). `null` = neither filter, which the engine
|
|
37941
|
+
* refuses (see {@link audioIsFailClosed}).
|
|
37942
|
+
*
|
|
37943
|
+
* A LEGACY rule carrying BOTH resolves to `label`: it is the mode that fires,
|
|
37944
|
+
* and the alternative is silently keeping a window the operator can no longer
|
|
37945
|
+
* see in the editor. Nothing new can reach this branch — {@link patchAudio}
|
|
37946
|
+
* clears the other filter on every write.
|
|
37947
|
+
*/
|
|
37948
|
+
function audioModeOf(value) {
|
|
37949
|
+
if (value === void 0) return null;
|
|
37950
|
+
if (value.labels !== void 0 && value.labels.length > 0) return "label";
|
|
37951
|
+
if (value.dbThreshold !== void 0) return "level";
|
|
37952
|
+
return null;
|
|
37953
|
+
}
|
|
37656
37954
|
new Map(AUDIO_MACRO_LABELS.flatMap((macro) => macro.icon === void 0 ? [] : [[macro.id, macro.icon]]));
|
|
37657
37955
|
new Set(["devices", "classes"]);
|
|
37658
37956
|
var WEEKDAY_TO_DAY = {
|
|
@@ -38197,4 +38495,4 @@ function vectorDimFromBase64(encoded) {
|
|
|
38197
38495
|
return Math.floor(Buffer.from(encoded, "base64").byteLength / 4);
|
|
38198
38496
|
}
|
|
38199
38497
|
//#endregion
|
|
38200
|
-
export {
|
|
38498
|
+
export { isDetectionMacroClass as $, SCENE_CONFIRM_DEFAULT_TIMEOUT_MS as A, unknown as At, alarmPanelCapability as B, NcSnoozeSchema as C, discriminatedUnion as Ct, OpsLogEntrySchema as D, partialRecord as Dt, NcTaxonomySchema as E, object as Et, TimelapseRuleInputSchema as F, cosineSimilarity as G, audioMetricsCapability as H, TimelapseRulePatchSchema as I, deriveRecordingMode as J, customAction as K, TimelapseRuleSchema as L, SCENE_DIVERGED as M, SceneMonitorSchema as N, RECORDING_EXPORT_MAX_READ_BYTES as O, record as Ot, TIMELAPSE_DENSE_FLOOR_SEC as P, hfModelUrl as Q, TrackSourceSchema as R, NcSnoozeInputSchema as S, boolean as St, NcSystemEventKindSchema as T, number as Tt, audioModeOf as U, assertTimelapseCadences as V, buildEventKindDescriptor as W, encodeVectorBase64 as X, embeddingEncoderCapability as Y, faceGalleryCapability as Z, NcRuleInputSchema as _, isDeviceScopedCap as _t, DETECTION_PIPELINE_CAP_NAME as a, readDeviceStateFrom as at, NcRuleTargetSchema as b, _enum as bt, EVENT_PAD_MS as c, subKindsOf as ct, NC_ALARM_SYSTEM_EVENT_KINDS as d, zoneAnalyticsCapability as dt, isScheduleActive as et, NC_CONDITION_CATALOG as f, errMsg as ft, NcConditionDescriptorSchema as g, hydrateSchema as gt, NC_TAXONOMY as h, createEvent as ht, DETECTION_MACRO_CLASSES as i, plateGalleryCapability as it, SCENE_DEFAULT_ANCHOR_THRESHOLD as j, EventCategory as jt, RetrainStatusSchema as k, string as kt, LabelAttributionSchema as l, vectorDimFromBase64 as lt, NC_SNOOZE_MAX_MINUTES as m, DeviceType as mt, DEFAULT_EVENT_COLOR as n, notificationRulesCapability as nt, DeclaredDevices as o, readTimelapseGeneratedAt as ot, NC_DEFAULT_SNOOZE_MINUTES as p, BaseAddon as pt, defineCustomActions as q, DEFAULT_TIMELAPSE_PREVIEW_TEXT as r, pipelineAnalyticsCapability as rt, EVENT_KIND_BY_CAP as s, sceneMonitorCapability as st, BaseDevice as t, kebabToCamel as tt, MACRO_LABELS as u, videoclipsCapability as ut, NcRulePatchSchema as v, nodePin as vt, NcSnoozeSuppressedSchema as w, literal as wt, NcScheduleSchema as x, array as xt, NcRuleSchema as y, sleep as yt, addonWidgetsSourceCapability as z };
|
|
@@ -2,7 +2,7 @@ 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-Bs6oboqZ.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_fs$1 = require_dist.__toESM(node_fs, 1);
|
|
8
8
|
node_fs = require_dist.__toESM(node_fs);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Q as hfModelUrl, Y as embeddingEncoderCapability, pt as BaseAddon } from "../dist-CxeFHSSV.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import "node:fs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e, i as t, n, o as r, r as i, t as a } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.js-C0AuF9av.mjs";
|
|
2
2
|
import { t as o } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-B3Wx5J80.mjs";
|
|
3
|
-
import { a as s, i as c, n as l, o as u, r as d, s as f, t as p } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-
|
|
3
|
+
import { a as s, i as c, n as l, o as u, r as d, s as f, t as p } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DFckpC3K.mjs";
|
|
4
4
|
import { n as m, r as h, t as g } from "./_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-Bm-iyjmq.mjs";
|
|
5
5
|
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
|
|
6
6
|
var _ = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), v = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), y = (e) => {
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.74",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.51",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_pipeline_analytics_widgets",
|