@camstack/addon-pipeline 1.2.76 → 1.2.78
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-CTpQfjSR.js → addon-utils-C-XbUkiG.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-CZLjObZZ.js → dist-BdVCXl5n.js} +429 -44
- package/dist/{dist-zksfWnEA.mjs → dist-CsP_DikG.mjs} +429 -44
- package/dist/{event-loop-stall-monitor-CcBQAI28.js → event-loop-stall-monitor-BOu8lGee.js} +1 -1
- package/dist/{event-loop-stall-monitor-BuZA3loB.mjs → event-loop-stall-monitor-C3cvE_Xk.mjs} +1 -1
- package/dist/{lazy-sharp-SWR_D1Um.js → lazy-sharp-1LkmyWqV.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 +655 -46
- package/dist/recorder/index.mjs +654 -45
- 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-Dd6XOtVn.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DUi-lR4R.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-1QMyGZMB.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-Dg08SxUW.mjs +26 -0
- package/dist/stream-broker/{hostInit-COc_Q_xX.mjs → hostInit-DEtsjgBO.mjs} +3 -3
- package/dist/stream-broker/index.js +411 -93
- package/dist/stream-broker/index.mjs +411 -93
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-DAQ1iZFK.js → worker-protocol-B4fPjmXk.js} +1 -1
- package/dist/{worker-protocol-DyX_HbaJ.mjs → worker-protocol-BRwzX3f_.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-RYTOS6B-.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-DfsLsn2e.mjs +0 -26
|
@@ -13645,6 +13645,17 @@ var LlmImageSchema = object({
|
|
|
13645
13645
|
bytes: _instanceof(Uint8Array),
|
|
13646
13646
|
mimeType: string()
|
|
13647
13647
|
});
|
|
13648
|
+
/**
|
|
13649
|
+
* Retry policy. `enabled: false` is NOT the same as `maxAttempts: 1` in intent —
|
|
13650
|
+
* the flag is what a consumer table flips, the count is what the operator tunes.
|
|
13651
|
+
* A retry doubles the wall time of a call, so the two gates that run inside a
|
|
13652
|
+
* notification's budget keep it off (see `CONSUMER_RETRY_POLICY` in addon-ai).
|
|
13653
|
+
*/
|
|
13654
|
+
var LlmRetryPolicySchema = object({
|
|
13655
|
+
enabled: boolean().default(false),
|
|
13656
|
+
/** Total attempts INCLUDING the first. 1 = no retry. */
|
|
13657
|
+
maxAttempts: number().int().min(1).max(5).default(1)
|
|
13658
|
+
});
|
|
13648
13659
|
var LlmGenerateBaseInputSchema = object({
|
|
13649
13660
|
/** Collection routing (the notification-output posture). */
|
|
13650
13661
|
addonId: string().optional(),
|
|
@@ -13659,7 +13670,28 @@ var LlmGenerateBaseInputSchema = object({
|
|
|
13659
13670
|
jsonSchema: record(string(), unknown()).optional(),
|
|
13660
13671
|
/** Per-call override of the profile default. */
|
|
13661
13672
|
maxTokens: number().int().positive().optional(),
|
|
13662
|
-
temperature: number().optional()
|
|
13673
|
+
temperature: number().optional(),
|
|
13674
|
+
/** Per-call override of the profile default (nucleus sampling). */
|
|
13675
|
+
topP: number().min(0).max(1).optional(),
|
|
13676
|
+
/** Per-call override of the profile default (top-k sampling). */
|
|
13677
|
+
topK: number().int().positive().optional(),
|
|
13678
|
+
/** Per-call override of `profile.timeoutMs` — the total generation bound. */
|
|
13679
|
+
timeoutMs: number().int().positive().optional(),
|
|
13680
|
+
/** Per-call override; beats both the consumer table and the profile. */
|
|
13681
|
+
retry: LlmRetryPolicySchema.optional(),
|
|
13682
|
+
/**
|
|
13683
|
+
* Caller-minted id that makes this generation CANCELLABLE.
|
|
13684
|
+
*
|
|
13685
|
+
* Without it a caller that stops waiting cannot stop the work: the gates race
|
|
13686
|
+
* the call against 8 s and free their own slot when the timer wins, while the
|
|
13687
|
+
* generation upstream keeps running to `profile.timeoutMs` — 60 s by default,
|
|
13688
|
+
* on a single-threaded local model. The per-camera bound then counts WAITS,
|
|
13689
|
+
* not generations, and the real load is unbounded.
|
|
13690
|
+
*
|
|
13691
|
+
* `AbortSignal` cannot cross a process boundary; an id can. Pass one here and
|
|
13692
|
+
* `llm.cancel({ requestId })` tears the socket down.
|
|
13693
|
+
*/
|
|
13694
|
+
requestId: string().optional()
|
|
13663
13695
|
});
|
|
13664
13696
|
/**
|
|
13665
13697
|
* `llm-runtime` — node-side managed llama.cpp executor (spec §4). Registered
|
|
@@ -13698,8 +13730,49 @@ var ManagedRuntimeConfigSchema = object({
|
|
|
13698
13730
|
gpuLayers: number().int().default(0),
|
|
13699
13731
|
/** Default: cpus-2, clamped ≥1 (resolved node-side). */
|
|
13700
13732
|
threads: number().int().optional(),
|
|
13701
|
-
/** Concurrent slots. */
|
|
13733
|
+
/** Concurrent slots (`--parallel`). */
|
|
13702
13734
|
parallel: number().int().default(1),
|
|
13735
|
+
/** Logical batch size (`-b`). Larger = faster prompt ingest, more RAM. */
|
|
13736
|
+
batchSize: number().int().positive().optional(),
|
|
13737
|
+
/** Physical batch / micro-batch (`-ub`). */
|
|
13738
|
+
ubatchSize: number().int().positive().optional(),
|
|
13739
|
+
/**
|
|
13740
|
+
* `--flash-attn`. Cuts KV-cache memory on the backends that implement it and
|
|
13741
|
+
* is a no-op elsewhere, so it is offered rather than assumed.
|
|
13742
|
+
*/
|
|
13743
|
+
flashAttention: boolean().default(false),
|
|
13744
|
+
/**
|
|
13745
|
+
* `--mlock`. Pins the weights in RAM so the OS cannot page them out mid
|
|
13746
|
+
* inference. Costs the full model size in resident memory — which is exactly
|
|
13747
|
+
* what the RAM budget is counting.
|
|
13748
|
+
*/
|
|
13749
|
+
mlock: boolean().default(false),
|
|
13750
|
+
/**
|
|
13751
|
+
* `--no-mmap`. Reads the whole GGUF up front instead of mapping it. Slower to
|
|
13752
|
+
* start, but avoids the page-fault stalls a network or spinning-disk model
|
|
13753
|
+
* store produces on every first token.
|
|
13754
|
+
*/
|
|
13755
|
+
noMmap: boolean().default(false),
|
|
13756
|
+
/** `--cache-type-k` / `--cache-type-v` — quantising the KV cache is the
|
|
13757
|
+
* cheapest way to fit a longer context in the same RAM. */
|
|
13758
|
+
cacheTypeK: _enum([
|
|
13759
|
+
"f32",
|
|
13760
|
+
"f16",
|
|
13761
|
+
"q8_0",
|
|
13762
|
+
"q5_1",
|
|
13763
|
+
"q5_0",
|
|
13764
|
+
"q4_1",
|
|
13765
|
+
"q4_0"
|
|
13766
|
+
]).optional(),
|
|
13767
|
+
cacheTypeV: _enum([
|
|
13768
|
+
"f32",
|
|
13769
|
+
"f16",
|
|
13770
|
+
"q8_0",
|
|
13771
|
+
"q5_1",
|
|
13772
|
+
"q5_0",
|
|
13773
|
+
"q4_1",
|
|
13774
|
+
"q4_0"
|
|
13775
|
+
]).optional(),
|
|
13703
13776
|
/** Else lazy: first generate boots it. */
|
|
13704
13777
|
autoStart: boolean().default(false),
|
|
13705
13778
|
/** 0 = never; frees RAM after quiet periods. */
|
|
@@ -13787,10 +13860,44 @@ var LlmProfileSchema = object({
|
|
|
13787
13860
|
baseUrl: string().optional(),
|
|
13788
13861
|
/** ConfigUISchema type:'password' — never round-trips (spec §5). */
|
|
13789
13862
|
apiKey: string().optional(),
|
|
13863
|
+
/** Vision on/off. A vision call against a `false` profile is REFUSED, never
|
|
13864
|
+
* degraded to text — that shipped once and produced a confident answer to a
|
|
13865
|
+
* question about a picture nobody sent. */
|
|
13790
13866
|
supportsVision: boolean(),
|
|
13791
13867
|
temperature: number().min(0).max(2).optional(),
|
|
13868
|
+
/** Nucleus sampling. Every wire we speak has it. */
|
|
13869
|
+
topP: number().min(0).max(1).optional(),
|
|
13870
|
+
/** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
|
|
13871
|
+
* wire does, and the client drops it there (measured: the request body gets
|
|
13872
|
+
* `top_p` and no `top_k`). The profile editor hides the field wherever it
|
|
13873
|
+
* would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
|
|
13874
|
+
topK: number().int().positive().optional(),
|
|
13792
13875
|
maxTokens: number().int().positive().optional(),
|
|
13876
|
+
/** Prompt context window. Advisory for cloud kinds (they enforce their own);
|
|
13877
|
+
* for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
|
|
13878
|
+
* the model with, so it is the one field that changes a PROCESS. */
|
|
13879
|
+
contextLength: number().int().positive().optional(),
|
|
13880
|
+
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
13881
|
+
* two system prompts fighting is worse than either alone). */
|
|
13882
|
+
systemPrompt: string().optional(),
|
|
13883
|
+
/** Total generation bound — the only one a unary call has. */
|
|
13793
13884
|
timeoutMs: number().int().positive().default(6e4),
|
|
13885
|
+
/** Wait for response headers only. */
|
|
13886
|
+
connectTimeoutMs: number().int().positive().default(1e4),
|
|
13887
|
+
/** Accepted, but no output yet — a cold GPU load lives here. */
|
|
13888
|
+
firstTokenTimeoutMs: number().int().positive().default(12e4),
|
|
13889
|
+
/** Output started then stopped. */
|
|
13890
|
+
idleTimeoutMs: number().int().positive().default(6e4),
|
|
13891
|
+
/** Profile-level default. The per-consumer table and a per-call override
|
|
13892
|
+
* both beat it — see `resolveRetryPolicy`. */
|
|
13893
|
+
retry: LlmRetryPolicySchema.default({
|
|
13894
|
+
enabled: false,
|
|
13895
|
+
maxAttempts: 1
|
|
13896
|
+
}),
|
|
13897
|
+
/** Whether this profile may use tools. The tool-call plumbing rides the
|
|
13898
|
+
* library; the REGISTRY of callable tools is ours and is empty in v1, so a
|
|
13899
|
+
* `true` here buys the wiring, not behaviour, until tools are registered. */
|
|
13900
|
+
toolsEnabled: boolean().default(false),
|
|
13794
13901
|
extraHeaders: record(string(), string()).optional(),
|
|
13795
13902
|
/** kind === 'managed-local' only (spec §4). */
|
|
13796
13903
|
runtime: ManagedRuntimeConfigSchema.optional()
|
|
@@ -13852,7 +13959,10 @@ var ProfileRefInputSchema = object({
|
|
|
13852
13959
|
addonId: string(),
|
|
13853
13960
|
profileId: string()
|
|
13854
13961
|
});
|
|
13855
|
-
method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
|
|
13962
|
+
method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(GenerateVisionInputSchema, LlmGenerateResultSchema, { kind: "mutation" }), method(object({
|
|
13963
|
+
addonId: string().optional(),
|
|
13964
|
+
requestId: string()
|
|
13965
|
+
}), _void(), { kind: "mutation" }), method(object({}), array(LlmProfileKindDescriptorSchema)), method(object({}), array(LlmProfileSchema)), method(object({ profile: LlmProfileSchema }), LlmProfileSchema, {
|
|
13856
13966
|
kind: "mutation",
|
|
13857
13967
|
auth: "admin"
|
|
13858
13968
|
}), method(ProfileRefInputSchema, _void(), {
|
|
@@ -15931,28 +16041,36 @@ var NcOccupancyConditionSchema = object({
|
|
|
15931
16041
|
/**
|
|
15932
16042
|
* Audio condition (IMMEDIATE trigger) — a rule on SOUND, not on a picture.
|
|
15933
16043
|
*
|
|
15934
|
-
*
|
|
15935
|
-
*
|
|
15936
|
-
*
|
|
15937
|
-
*
|
|
15938
|
-
*
|
|
15939
|
-
*
|
|
15940
|
-
*
|
|
15941
|
-
*
|
|
15942
|
-
*
|
|
15943
|
-
*
|
|
15944
|
-
*
|
|
15945
|
-
*
|
|
15946
|
-
*
|
|
15947
|
-
*
|
|
15948
|
-
*
|
|
15949
|
-
*
|
|
15950
|
-
*
|
|
15951
|
-
*
|
|
15952
|
-
*
|
|
15953
|
-
*
|
|
15954
|
-
*
|
|
15955
|
-
* `
|
|
16044
|
+
* **TWO EXCLUSIVE MODES** (operator decision 2026-08-14, D157). Which one a
|
|
16045
|
+
* rule is in is not a stored field — it is WHICH FILTER the rule carries, so
|
|
16046
|
+
* there is no second switch that can disagree with the first and every rule
|
|
16047
|
+
* authored before the decision migrates for free (`audioModeOf`):
|
|
16048
|
+
*
|
|
16049
|
+
* - **LABEL mode — `labels` present.** The rule fires on the FIRST frame the
|
|
16050
|
+
* classifier labels with one of them. No window, no percentage:
|
|
16051
|
+
* `hitPercent` and `samplingSeconds` are ignored, and the rule's own
|
|
16052
|
+
* `throttle` cooldown is the only brake. The per-label confidence floor is
|
|
16053
|
+
* the analyzer's (`classificationMinScore`, per device) — a label only
|
|
16054
|
+
* reaches this condition if the classifier was already confident enough.
|
|
16055
|
+
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
16056
|
+
* the condition: at least `hitPercent`% of the samples over
|
|
16057
|
+
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
16058
|
+
* {@link NC_AUDIO_DBFS_FLOOR}: negative-going, `0` = full scale). The window
|
|
16059
|
+
* must be FULL before it can match — a window open for two of its ten
|
|
16060
|
+
* seconds is 100% of nothing.
|
|
16061
|
+
*
|
|
16062
|
+
* **Why label mode has no window.** It had one, and it never fired: the
|
|
16063
|
+
* analyzer emits ~1 audio frame per second but YAMNet only LABELS one to three
|
|
16064
|
+
* of them per episode, even through continuous crying. The measured maximum
|
|
16065
|
+
* `hitPercent` over the whole live history was 40 — under the shipped default
|
|
16066
|
+
* of 60, so a label rule could not fire at all, ever. A percentage of frames is
|
|
16067
|
+
* the wrong question to ask of a sparse classifier.
|
|
16068
|
+
*
|
|
16069
|
+
* **Fail-closed when NEITHER is given** — every sample would be a trivial hit
|
|
16070
|
+
* and the rule would fire on silence. The schema cannot express "exactly one
|
|
16071
|
+
* of" without becoming a ZodEffects the cap path would have to special-case, so
|
|
16072
|
+
* the exclusivity is enforced where every editor writes (`patchAudio`) and a
|
|
16073
|
+
* legacy rule carrying both resolves to LABEL (the mode that fires).
|
|
15956
16074
|
*
|
|
15957
16075
|
* Labels are the audio macro classes (`AUDIO_MACRO_LABELS` / the NC taxonomy's
|
|
15958
16076
|
* `audio-*` ids). Both spellings are accepted — the matcher normalizes the
|
|
@@ -15960,13 +16078,13 @@ var NcOccupancyConditionSchema = object({
|
|
|
15960
16078
|
* an operator who typed `dog` mean the same thing.
|
|
15961
16079
|
*/
|
|
15962
16080
|
var NcAudioConditionSchema = object({
|
|
15963
|
-
/**
|
|
16081
|
+
/** LABEL MODE: audio macro labels. Present ⇒ fires on the first labelled frame. */
|
|
15964
16082
|
labels: array(string().min(1)).min(1).optional(),
|
|
15965
|
-
/**
|
|
16083
|
+
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
15966
16084
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
15967
|
-
/**
|
|
16085
|
+
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
15968
16086
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
15969
|
-
/**
|
|
16087
|
+
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
15970
16088
|
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
15971
16089
|
});
|
|
15972
16090
|
/**
|
|
@@ -16104,13 +16222,81 @@ var NcRuleActionsSchema = object({
|
|
|
16104
16222
|
*/
|
|
16105
16223
|
buttons: array(NcRuleNotificationButtonSchema).max(8).optional()
|
|
16106
16224
|
});
|
|
16225
|
+
/**
|
|
16226
|
+
* "This rule applies only while `deviceId` is in one of `states`."
|
|
16227
|
+
*
|
|
16228
|
+
* The states are the DEVICE's own vocabulary — `AlarmState` for a panel,
|
|
16229
|
+
* `on`/`off` for a switch — not a normalised set, because normalising would
|
|
16230
|
+
* make the condition lie about devices whose states have no equivalent.
|
|
16231
|
+
*
|
|
16232
|
+
* An unreadable state does NOT match: see the engine's fail-closed gate. A
|
|
16233
|
+
* condition that fired on "I could not read it" would be worse than no gate.
|
|
16234
|
+
*/
|
|
16235
|
+
var NcDeviceStateConditionSchema = object({
|
|
16236
|
+
deviceId: number().int(),
|
|
16237
|
+
/** Any of these matches. */
|
|
16238
|
+
states: array(string().min(1)).min(1)
|
|
16239
|
+
});
|
|
16240
|
+
/**
|
|
16241
|
+
* "This rule applies only while scene `sceneId` is `matched` / `diverged`."
|
|
16242
|
+
*
|
|
16243
|
+
* A GATE, not a trigger. `occupancy` and `audio` each DISCRIMINATE their rule —
|
|
16244
|
+
* carrying one makes the rule fire on that subject and nothing else. Scene is
|
|
16245
|
+
* the other shape entirely, the `deviceState` shape: it narrows a rule that
|
|
16246
|
+
* already has a trigger ("tell me about a person at the front door, but only
|
|
16247
|
+
* while the bin is still out"). That is why it composes with every delivery
|
|
16248
|
+
* instead of owning one, and why no new `NcDelivery` member and no new subject
|
|
16249
|
+
* kind exist for it — see D159.
|
|
16250
|
+
*
|
|
16251
|
+
* ── Identity ───────────────────────────────────────────────────────────────
|
|
16252
|
+
* `sceneId` is `SceneMonitor.id`, a `randomUUID()` minted by `createScene` —
|
|
16253
|
+
* globally unique, so it needs no device to disambiguate it. `deviceId` is
|
|
16254
|
+
* carried as a HINT for the editor and for the log line, never as part of the
|
|
16255
|
+
* lookup key: a rule whose hint drifted must still gate correctly.
|
|
16256
|
+
*
|
|
16257
|
+
* ── Which boolean ──────────────────────────────────────────────────────────
|
|
16258
|
+
* `latched` ABSENT means "whatever the scene itself says" — `SceneMonitor.emit`
|
|
16259
|
+
* already declares which boolean drives notification rules, and a second knob
|
|
16260
|
+
* that could disagree with it is exactly the D62 failure. Set it only to
|
|
16261
|
+
* override one rule against the scene's own default.
|
|
16262
|
+
*
|
|
16263
|
+
* - LIVE reading (`emit`/`latched` resolve to live): passes iff
|
|
16264
|
+
* `verdict === requiredState`. `unknown` — no reference for this light, view
|
|
16265
|
+
* shifted, no snapshot — passes NEITHER. A scene that cannot judge is not
|
|
16266
|
+
* evidence, in either direction.
|
|
16267
|
+
* - LATCHED reading: passes iff `latched === (requiredState === 'diverged')`.
|
|
16268
|
+
* The latch is a durable fact about the past ("it has diverged since I armed
|
|
16269
|
+
* it"), so a camera that has gone dark does not clear it — that is the whole
|
|
16270
|
+
* reason the operator asked for a latch.
|
|
16271
|
+
*
|
|
16272
|
+
* The gate reads an in-memory mirror (`NcSceneStateCache`) refreshed OFF the
|
|
16273
|
+
* event path, never the cap: D49. A mirror that has never loaded, or a scene it
|
|
16274
|
+
* does not carry, reads absent and the rule does NOT fire — fail closed, and
|
|
16275
|
+
* said out loud in the log rather than dropped in silence.
|
|
16276
|
+
*/
|
|
16277
|
+
var NcSceneConditionSchema = object({
|
|
16278
|
+
/** `SceneMonitor.id` — the uuid the cap mints. The whole lookup key. */
|
|
16279
|
+
sceneId: string().min(1),
|
|
16280
|
+
/** The camera the scene lives on. A hint for the editor and the log line. */
|
|
16281
|
+
deviceId: number().int().optional(),
|
|
16282
|
+
/** The state the scene must be in for the rule to fire. */
|
|
16283
|
+
requiredState: _enum(["matched", "diverged"]),
|
|
16284
|
+
/**
|
|
16285
|
+
* Read the LATCH (`true`) or the LIVE verdict (`false`). Absent = follow the
|
|
16286
|
+
* scene's own `emit` field, which is the only place that decision belongs.
|
|
16287
|
+
*/
|
|
16288
|
+
latched: boolean().optional()
|
|
16289
|
+
});
|
|
16107
16290
|
var NcConditionsSchema = object({
|
|
16108
16291
|
/** Gate on ANOTHER device's current state (the alarm armed, a switch on). */
|
|
16109
|
-
deviceState:
|
|
16110
|
-
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16292
|
+
deviceState: NcDeviceStateConditionSchema.optional(),
|
|
16293
|
+
/**
|
|
16294
|
+
* Gate on a SCENE's state — "only while the bin is still out". Composes with
|
|
16295
|
+
* every trigger (detection, occupancy, audio, sensor, package, track-end);
|
|
16296
|
+
* unlike `occupancy`/`audio` it discriminates nothing. See
|
|
16297
|
+
* {@link NcSceneCondition} and D159.
|
|
16298
|
+
*/
|
|
16299
|
+
scene: NcSceneConditionSchema.optional(),
|
|
16114
16300
|
/** Device scope — absent = all devices. */
|
|
16115
16301
|
devices: array(number()).optional(),
|
|
16116
16302
|
/** Detector class names (any overlap with the record's class set). */
|
|
@@ -16748,6 +16934,7 @@ var NcConditionDescriptorSchema = object({
|
|
|
16748
16934
|
"occupancy",
|
|
16749
16935
|
"audio",
|
|
16750
16936
|
"deviceState",
|
|
16937
|
+
"scene",
|
|
16751
16938
|
"systemEvent"
|
|
16752
16939
|
]),
|
|
16753
16940
|
operator: _enum([
|
|
@@ -26463,14 +26650,50 @@ var recordingExportCapability = {
|
|
|
26463
26650
|
* thing except the comparator: `similarity` (CLIP cosine at the same ROI coords
|
|
26464
26651
|
* vs condition-tagged references) and `llm` (vision-LLM judgment over the crop).
|
|
26465
26652
|
*
|
|
26466
|
-
*
|
|
26467
|
-
*
|
|
26468
|
-
*
|
|
26469
|
-
*
|
|
26470
|
-
|
|
26471
|
-
|
|
26472
|
-
*
|
|
26653
|
+
* **No `deviceConfig`, deliberately.** This shipped as the D14 widget archetype,
|
|
26654
|
+
* which put a "Scenes" tab on one camera's detail page. That is the wrong shape
|
|
26655
|
+
* for the thing: a scene is a standing question about the property ("is the bin
|
|
26656
|
+
* still out"), and the operator's question is "which of my scenes have tripped",
|
|
26657
|
+
* across every camera at once — not "what does camera 617 think". Buried one
|
|
26658
|
+
* camera deep it also could not be found. The surface is now a top-level admin
|
|
26659
|
+
* page (`/scenes`, `pages/Scenes.tsx`) that lists every scene on every camera and
|
|
26660
|
+
* picks the camera inside the create flow, the same shape Events and Faces have.
|
|
26661
|
+
*
|
|
26662
|
+
* The consequence to keep in mind: `host/scene-monitor-editor` is gone from
|
|
26663
|
+
* `HOST_WIDGETS` too. `scripts/check-host-widget-resolves.ts` asserts BOTH
|
|
26664
|
+
* directions, so a registration nobody declares fails exactly as loudly as a
|
|
26665
|
+
* declaration nobody registers. The editor is imported directly by the page.
|
|
26666
|
+
*
|
|
26667
|
+
* `status.kind:'push'` — the engine pushes on every hysteresis flip /
|
|
26668
|
+
* availability change; consumers never poll.
|
|
26669
|
+
*/
|
|
26670
|
+
/** Extensible condition tag. Seeded 'day' | 'ir' (the two variants the operator
|
|
26671
|
+
* captures) plus 'night' | 'dawn' | 'dusk' from the resolver's sun-times band.
|
|
26672
|
+
* Open by design so more can be added without a wire break.
|
|
26673
|
+
*
|
|
26674
|
+
* Matching does NOT fall back across conditions: cross-condition cosines are
|
|
26675
|
+
* not comparable, so "I have never seen this scene in this light" is reported
|
|
26676
|
+
* as `unknown`, never guessed. A day reference scored against an IR frame
|
|
26677
|
+
* collapses the cosine and would latch a false alarm every single night. */
|
|
26473
26678
|
var SceneConditionSchema = string();
|
|
26679
|
+
/** `matched` = the baseline is what we see; `diverged` = it demonstrably is not;
|
|
26680
|
+
* `unknown` = we cannot judge (no reference for this condition, encoder model
|
|
26681
|
+
* changed, view shifted, no snapshot). `unknown` is a real value, not a null,
|
|
26682
|
+
* and never counts toward hysteresis in either direction. */
|
|
26683
|
+
var SceneVerdictSchema = _enum([
|
|
26684
|
+
"matched",
|
|
26685
|
+
"diverged",
|
|
26686
|
+
"unknown"
|
|
26687
|
+
]);
|
|
26688
|
+
/** Why a scene cannot judge. Named, because this feature's failure mode is
|
|
26689
|
+
* silence that reads as "nothing has happened". */
|
|
26690
|
+
var SceneUnavailableSchema = _enum([
|
|
26691
|
+
"no-reference-for-condition",
|
|
26692
|
+
"view-shifted",
|
|
26693
|
+
"no-vision-profile",
|
|
26694
|
+
"encoder-model-changed",
|
|
26695
|
+
"no-snapshot"
|
|
26696
|
+
]);
|
|
26474
26697
|
/** One captured reference — condition-tagged, model-version-gated. `embedding`
|
|
26475
26698
|
* is `number[]` (Float32Array does NOT survive MsgPack/UDS). */
|
|
26476
26699
|
var SceneReferenceSchema = object({
|
|
@@ -26478,7 +26701,14 @@ var SceneReferenceSchema = object({
|
|
|
26478
26701
|
modelId: string(),
|
|
26479
26702
|
condition: SceneConditionSchema,
|
|
26480
26703
|
capturedAt: number(),
|
|
26481
|
-
thumbnailMediaId: string().optional()
|
|
26704
|
+
thumbnailMediaId: string().optional(),
|
|
26705
|
+
/** Whole-frame (downscaled) embedding captured alongside the ROI crop. The
|
|
26706
|
+
* anti-view-shift anchor: a bumped camera, a PTZ preset or a re-aim makes the
|
|
26707
|
+
* normalized rect frame a different piece of world, and the scene would
|
|
26708
|
+
* diverge forever with a perfectly plausible cosine. Checked LAZILY, only
|
|
26709
|
+
* when hysteresis is about to flip — one extra encode per candidate
|
|
26710
|
+
* transition, not per poll. */
|
|
26711
|
+
anchorEmbedding: array(number()).optional()
|
|
26482
26712
|
});
|
|
26483
26713
|
var SceneMonitorStateSchema = object({
|
|
26484
26714
|
id: string(),
|
|
@@ -26500,6 +26730,25 @@ var SceneCheckSchema = discriminatedUnion("mode", [object({
|
|
|
26500
26730
|
profileId: string().optional(),
|
|
26501
26731
|
hysteresisCount: number().int().positive()
|
|
26502
26732
|
})]);
|
|
26733
|
+
var SCENE_DEFAULT_ANCHOR_THRESHOLD = .85;
|
|
26734
|
+
/**
|
|
26735
|
+
* Vision-model adjudication of a candidate flip. Field names deliberately
|
|
26736
|
+
* mirror `NcConfirmSchema` so an operator meets one vocabulary, not two.
|
|
26737
|
+
*
|
|
26738
|
+
* `onTimeout` defaults to **'hold'**, the OPPOSITE of `NcConfirmGate`'s
|
|
26739
|
+
* fail-open: a notification suppressed is the worse error there, but a vision
|
|
26740
|
+
* model that timed out has not told us the bin is gone, and a latch is a
|
|
26741
|
+
* stateful claim that costs the operator a trip to reset.
|
|
26742
|
+
*/
|
|
26743
|
+
var SceneConfirmSchema = object({
|
|
26744
|
+
enabled: boolean().default(false),
|
|
26745
|
+
prompt: string().min(1).max(1e3),
|
|
26746
|
+
profileId: string().optional(),
|
|
26747
|
+
timeoutMs: number().int().min(1e3).max(2e4).default(8e3),
|
|
26748
|
+
maxImagePx: number().int().min(64).max(2048).default(448),
|
|
26749
|
+
/** What a timeout / unavailable model means for the PENDING flip. */
|
|
26750
|
+
onTimeout: _enum(["flip", "hold"]).default("hold")
|
|
26751
|
+
});
|
|
26503
26752
|
var SceneMonitorSchema = object({
|
|
26504
26753
|
id: string(),
|
|
26505
26754
|
label: string(),
|
|
@@ -26518,7 +26767,41 @@ var SceneMonitorSchema = object({
|
|
|
26518
26767
|
lastConfidence: number().nullable(),
|
|
26519
26768
|
currentCondition: SceneConditionSchema.nullable(),
|
|
26520
26769
|
availability: _enum(["ok", "unavailable"]),
|
|
26521
|
-
unavailableReason: string().nullable()
|
|
26770
|
+
unavailableReason: string().nullable(),
|
|
26771
|
+
/** Which state is "the initial screen". `null` until the first capture. */
|
|
26772
|
+
baselineStateId: string().nullable(),
|
|
26773
|
+
/** Which boolean drives notification rules and any export. */
|
|
26774
|
+
emit: _enum(["latched", "live"]).default("latched"),
|
|
26775
|
+
/** Live: does the region match the baseline RIGHT NOW. */
|
|
26776
|
+
verdict: SceneVerdictSchema,
|
|
26777
|
+
/** Has it been `diverged` at least once since `armedAt` — the operator's boolean. */
|
|
26778
|
+
latched: boolean(),
|
|
26779
|
+
/** Last reset (or creation). */
|
|
26780
|
+
armedAt: number(),
|
|
26781
|
+
divergedAt: number().nullable(),
|
|
26782
|
+
restoredAt: number().nullable(),
|
|
26783
|
+
/** A check is only COUNTED when the device has been quiet this long. Motion
|
|
26784
|
+
* during the window DISCARDS the observation — a car pulling up in front of
|
|
26785
|
+
* the bin must not be able to spend hysteresis credit. */
|
|
26786
|
+
quietSeconds: number().int().min(0).max(3600).default(60),
|
|
26787
|
+
/** An observation only advances the pending count when it is at least this
|
|
26788
|
+
* far from the previously counted one, so N agreeing checks span real time
|
|
26789
|
+
* rather than N adjacent polls inside one occlusion. */
|
|
26790
|
+
minObservationSpacingSec: number().int().min(0).max(3600).default(120),
|
|
26791
|
+
/** Vision-model adjudication of a candidate flip. Similarity primary only. */
|
|
26792
|
+
confirm: SceneConfirmSchema.optional(),
|
|
26793
|
+
/** Whole-frame anchor cosine below which a flip is REFUSED as `view-shifted`. */
|
|
26794
|
+
anchorThreshold: number().min(0).max(1).default(SCENE_DEFAULT_ANCHOR_THRESHOLD),
|
|
26795
|
+
/** Clear the latch on its own when the scene matches again? Default false —
|
|
26796
|
+
* `restoredAt` and the `scene-restored` edge are recorded regardless, so an
|
|
26797
|
+
* automation can react to the bin coming back without the operator's own
|
|
26798
|
+
* alarm silently clearing itself. */
|
|
26799
|
+
autoRestore: boolean().default(false),
|
|
26800
|
+
/** Named cause when `verdict === 'unknown'`. */
|
|
26801
|
+
unavailable: SceneUnavailableSchema.nullable(),
|
|
26802
|
+
/** Conditions that have at least one comparable reference — the coverage line
|
|
26803
|
+
* ("day ✓ · ir ✓ · dusk ✗") that turns a silent fallback into a visible fact. */
|
|
26804
|
+
coveredConditions: array(SceneConditionSchema)
|
|
26522
26805
|
});
|
|
26523
26806
|
var SceneMonitorStatusSchema = object({
|
|
26524
26807
|
monitors: array(SceneMonitorSchema),
|
|
@@ -26551,7 +26834,14 @@ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSche
|
|
|
26551
26834
|
"both"
|
|
26552
26835
|
]).optional(),
|
|
26553
26836
|
checkIntervalSec: number().optional(),
|
|
26554
|
-
check: SceneCheckSchema.optional()
|
|
26837
|
+
check: SceneCheckSchema.optional(),
|
|
26838
|
+
emit: _enum(["latched", "live"]).optional(),
|
|
26839
|
+
quietSeconds: number().int().min(0).max(3600).optional(),
|
|
26840
|
+
minObservationSpacingSec: number().int().min(0).max(3600).optional(),
|
|
26841
|
+
anchorThreshold: number().min(0).max(1).optional(),
|
|
26842
|
+
autoRestore: boolean().optional(),
|
|
26843
|
+
/** `null` clears the vision-model adjudicator. */
|
|
26844
|
+
confirm: SceneConfirmSchema.nullable().optional()
|
|
26555
26845
|
})
|
|
26556
26846
|
}), _void(), {
|
|
26557
26847
|
kind: "mutation",
|
|
@@ -26588,6 +26878,14 @@ DeviceType.Camera, method(object({ deviceId: number() }), SceneMonitorStatusSche
|
|
|
26588
26878
|
}), _void(), {
|
|
26589
26879
|
kind: "mutation",
|
|
26590
26880
|
auth: "admin"
|
|
26881
|
+
}), method(object({
|
|
26882
|
+
deviceId: number(),
|
|
26883
|
+
monitorId: string(),
|
|
26884
|
+
/** Defaults to TRUE at the provider seam — see `SCENE_RESET_RECAPTURES`. */
|
|
26885
|
+
recapture: boolean().optional()
|
|
26886
|
+
}), _void(), {
|
|
26887
|
+
kind: "mutation",
|
|
26888
|
+
auth: "admin"
|
|
26591
26889
|
});
|
|
26592
26890
|
/**
|
|
26593
26891
|
* Per-stage gating mode applied to the zones a rule references.
|
|
@@ -26896,12 +27194,64 @@ var NetworkAddressSchema = object({
|
|
|
26896
27194
|
family: string(),
|
|
26897
27195
|
internal: boolean()
|
|
26898
27196
|
});
|
|
27197
|
+
/**
|
|
27198
|
+
* Provenance of the site coordinates, and the whole reason this is not just two
|
|
27199
|
+
* numbers.
|
|
27200
|
+
*
|
|
27201
|
+
* - `operator-set` — a human typed it, or accepted a detection. Authoritative;
|
|
27202
|
+
* nothing overwrites it.
|
|
27203
|
+
* - `derived-from-ip` — the hub geolocated its own public IP once, because a
|
|
27204
|
+
* default that is right to a few kilometres beats the coarse UTC clock split
|
|
27205
|
+
* the sun-times consumers otherwise fall back to.
|
|
27206
|
+
*
|
|
27207
|
+
* The UI shows which one it is. An operator who cannot tell a guess from their
|
|
27208
|
+
* own input will eventually trust the guess.
|
|
27209
|
+
*/
|
|
27210
|
+
var SiteLocationSourceSchema = _enum(["operator-set", "derived-from-ip"]);
|
|
27211
|
+
/**
|
|
27212
|
+
* The read shape: the location plus the honest state of the one-shot derivation.
|
|
27213
|
+
*
|
|
27214
|
+
* `derivationAttemptedAt` is what makes the "one call, ever" contract
|
|
27215
|
+
* inspectable. When it is set and `location` is null, the geo-IP lookup ran and
|
|
27216
|
+
* failed; the hub will NOT try again on its own — the fallback is declared
|
|
27217
|
+
* (consumers degrade to their own last resort) and the operator either types the
|
|
27218
|
+
* coordinates or presses detect.
|
|
27219
|
+
*/
|
|
27220
|
+
var SiteLocationStatusSchema = object({
|
|
27221
|
+
location: object({
|
|
27222
|
+
/** WGS84 decimal degrees. */
|
|
27223
|
+
latitude: number().min(-90).max(90),
|
|
27224
|
+
longitude: number().min(-180).max(180),
|
|
27225
|
+
source: SiteLocationSourceSchema,
|
|
27226
|
+
/** Epoch ms the value was last written. */
|
|
27227
|
+
updatedAt: number(),
|
|
27228
|
+
/**
|
|
27229
|
+
* Human-readable place the geo-IP service reported ("Napoli, IT"). Display
|
|
27230
|
+
* only — never parsed, never matched on. Absent for an operator-typed value.
|
|
27231
|
+
*/
|
|
27232
|
+
label: string().optional()
|
|
27233
|
+
}).nullable(),
|
|
27234
|
+
derivationAttemptedAt: number().nullable(),
|
|
27235
|
+
/** Why the last derivation failed, for the UI to show instead of a shrug. */
|
|
27236
|
+
derivationError: string().nullable()
|
|
27237
|
+
});
|
|
27238
|
+
/** `null` clears the location and re-arms nothing — the derivation stays spent. */
|
|
27239
|
+
var SetSiteLocationInputSchema = object({
|
|
27240
|
+
latitude: number().min(-90).max(90),
|
|
27241
|
+
longitude: number().min(-180).max(180)
|
|
27242
|
+
}).nullable();
|
|
26899
27243
|
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(), {
|
|
26900
27244
|
kind: "mutation",
|
|
26901
27245
|
auth: "admin"
|
|
26902
27246
|
}), method(_void(), _void(), {
|
|
26903
27247
|
kind: "mutation",
|
|
26904
27248
|
auth: "admin"
|
|
27249
|
+
}), method(_void(), SiteLocationStatusSchema), method(SetSiteLocationInputSchema, SiteLocationStatusSchema, {
|
|
27250
|
+
kind: "mutation",
|
|
27251
|
+
auth: "admin"
|
|
27252
|
+
}), method(_void(), SiteLocationStatusSchema, {
|
|
27253
|
+
kind: "mutation",
|
|
27254
|
+
auth: "admin"
|
|
26905
27255
|
});
|
|
26906
27256
|
object({
|
|
26907
27257
|
/** True when the device's tamper switch / case-open contact is
|
|
@@ -29632,6 +29982,12 @@ Object.freeze({
|
|
|
29632
29982
|
addonId: null,
|
|
29633
29983
|
access: "create"
|
|
29634
29984
|
},
|
|
29985
|
+
"llm.cancel": {
|
|
29986
|
+
capName: "llm",
|
|
29987
|
+
capScope: "system",
|
|
29988
|
+
addonId: null,
|
|
29989
|
+
access: "create"
|
|
29990
|
+
},
|
|
29635
29991
|
"llm.deleteModel": {
|
|
29636
29992
|
capName: "llm",
|
|
29637
29993
|
capScope: "system",
|
|
@@ -31882,6 +32238,12 @@ Object.freeze({
|
|
|
31882
32238
|
addonId: null,
|
|
31883
32239
|
access: "create"
|
|
31884
32240
|
},
|
|
32241
|
+
"sceneMonitor.resetScene": {
|
|
32242
|
+
capName: "scene-monitor",
|
|
32243
|
+
capScope: "device",
|
|
32244
|
+
addonId: null,
|
|
32245
|
+
access: "delete"
|
|
32246
|
+
},
|
|
31885
32247
|
"sceneMonitor.updateScene": {
|
|
31886
32248
|
capName: "scene-monitor",
|
|
31887
32249
|
capScope: "device",
|
|
@@ -32560,6 +32922,12 @@ Object.freeze({
|
|
|
32560
32922
|
addonId: null,
|
|
32561
32923
|
access: "create"
|
|
32562
32924
|
},
|
|
32925
|
+
"system.detectSiteLocation": {
|
|
32926
|
+
capName: "system",
|
|
32927
|
+
capScope: "system",
|
|
32928
|
+
addonId: null,
|
|
32929
|
+
access: "create"
|
|
32930
|
+
},
|
|
32563
32931
|
"system.featureFlags": {
|
|
32564
32932
|
capName: "system",
|
|
32565
32933
|
capScope: "system",
|
|
@@ -32578,6 +32946,12 @@ Object.freeze({
|
|
|
32578
32946
|
addonId: null,
|
|
32579
32947
|
access: "view"
|
|
32580
32948
|
},
|
|
32949
|
+
"system.getSiteLocation": {
|
|
32950
|
+
capName: "system",
|
|
32951
|
+
capScope: "system",
|
|
32952
|
+
addonId: null,
|
|
32953
|
+
access: "view"
|
|
32954
|
+
},
|
|
32581
32955
|
"system.health": {
|
|
32582
32956
|
capName: "system",
|
|
32583
32957
|
capScope: "system",
|
|
@@ -32602,6 +32976,12 @@ Object.freeze({
|
|
|
32602
32976
|
addonId: null,
|
|
32603
32977
|
access: "create"
|
|
32604
32978
|
},
|
|
32979
|
+
"system.setSiteLocation": {
|
|
32980
|
+
capName: "system",
|
|
32981
|
+
capScope: "system",
|
|
32982
|
+
addonId: null,
|
|
32983
|
+
access: "create"
|
|
32984
|
+
},
|
|
32605
32985
|
"terminalSession.adoptLegacyMonitor": {
|
|
32606
32986
|
capName: "terminal-session",
|
|
32607
32987
|
capScope: "system",
|
|
@@ -34564,6 +34944,11 @@ Object.freeze({
|
|
|
34564
34944
|
form: "single",
|
|
34565
34945
|
optional: false
|
|
34566
34946
|
}],
|
|
34947
|
+
"sceneMonitor.resetScene": [{
|
|
34948
|
+
name: "deviceId",
|
|
34949
|
+
form: "single",
|
|
34950
|
+
optional: false
|
|
34951
|
+
}],
|
|
34567
34952
|
"sceneMonitor.updateScene": [{
|
|
34568
34953
|
name: "deviceId",
|
|
34569
34954
|
form: "single",
|
package/dist/{event-loop-stall-monitor-BuZA3loB.mjs → event-loop-stall-monitor-C3cvE_Xk.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS, z as hfModelUrl } from "./dist-
|
|
1
|
+
import { a as COCO_TO_MACRO, i as COCO_80_LABELS, r as AUDIO_MACRO_LABELS, z as hfModelUrl } from "./dist-CsP_DikG.mjs";
|
|
2
2
|
import { PerformanceObserver } from "node:perf_hooks";
|
|
3
3
|
//#region src/detection-pipeline/registry/model-catalogs.ts
|
|
4
4
|
var HF_REPO = "camstack/camstack-models";
|