@camstack/addon-post-analysis 1.2.610 → 1.2.612
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/{clip-model-registry-B1BMbjlk.js → clip-model-registry-C7WMvftu.js} +729 -141
- package/dist/{clip-model-registry-CHMOaqp1.mjs → clip-model-registry-JH4cTI06.mjs} +706 -142
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/_stub.js +2 -2
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Cv1RqnQj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DQE_Wu6_.mjs} +3 -3
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-7dLQKt_H.mjs +26 -0
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DbUPeg6m.mjs +26 -0
- package/dist/pipeline-analytics/{hostInit-vT2SQQV2.mjs → hostInit-Bl6Zvb1p.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +68007 -67085
- package/dist/pipeline-analytics/index.mjs +77067 -76144
- 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_types__loadShare__.js-DyXzqvY7.mjs +0 -26
- package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-Cm7pZeMH.mjs +0 -26
|
@@ -5643,7 +5643,7 @@ var ZodIssueCode = {
|
|
|
5643
5643
|
var ZodFirstPartyTypeKind;
|
|
5644
5644
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5645
5645
|
//#endregion
|
|
5646
|
-
//#region ../types/dist/sleep-
|
|
5646
|
+
//#region ../types/dist/sleep-BSuCCFjf.mjs
|
|
5647
5647
|
/**
|
|
5648
5648
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5649
5649
|
* window to float samples (D455).
|
|
@@ -8026,9 +8026,9 @@ function normalizeAddonInitResult(result) {
|
|
|
8026
8026
|
return result;
|
|
8027
8027
|
}
|
|
8028
8028
|
/**
|
|
8029
|
-
* The share-view scope kinds a
|
|
8030
|
-
* and validates them (`
|
|
8031
|
-
* list); a data plane names the kinds it ACCEPTS in `share`.
|
|
8029
|
+
* The share-view scope kinds a share-link token can carry. The hub mints
|
|
8030
|
+
* and validates them (`ShareViewGrantSchema` builds its
|
|
8031
|
+
* enum from this list); a data plane names the kinds it ACCEPTS in `share`.
|
|
8032
8032
|
*/
|
|
8033
8033
|
var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
|
|
8034
8034
|
/** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
|
|
@@ -14006,7 +14006,7 @@ var ConvertResultSchema = object({
|
|
|
14006
14006
|
* `super_admin` — collapsed onto the single boolean because every
|
|
14007
14007
|
* non-admin caller is governed by the same scope-check rules; the
|
|
14008
14008
|
* distinction was only ever used to route role-specific procedures
|
|
14009
|
-
* which we no longer have. CLI / webhook integrations are `
|
|
14009
|
+
* which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
|
|
14010
14010
|
* with `isAdmin: false` + an explicit scope list.
|
|
14011
14011
|
*/
|
|
14012
14012
|
/** Per-method access flavour. Materialised on every cap method via codegen. */
|
|
@@ -14195,10 +14195,12 @@ var AddonRoutesScopeSchema = object({
|
|
|
14195
14195
|
type: literal("addon-routes"),
|
|
14196
14196
|
access: array(MethodAccessSchema).min(1)
|
|
14197
14197
|
});
|
|
14198
|
+
var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
|
|
14198
14199
|
var CredentialScopeSchema = union([
|
|
14199
14200
|
literal("*"),
|
|
14200
14201
|
ShareViewScopeSchema,
|
|
14201
14202
|
AddonRoutesScopeSchema,
|
|
14203
|
+
PreferencesSelfScopeSchema,
|
|
14202
14204
|
TokenScopeSchema
|
|
14203
14205
|
]);
|
|
14204
14206
|
object({
|
|
@@ -14207,6 +14209,55 @@ object({
|
|
|
14207
14209
|
jti: string().min(16),
|
|
14208
14210
|
scopes: array(CredentialScopeSchema).min(1)
|
|
14209
14211
|
});
|
|
14212
|
+
var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
|
|
14213
|
+
/** A namespace's value: a JSON object, opaque to the hub. */
|
|
14214
|
+
var PreferenceValueSchema = record(string(), unknown());
|
|
14215
|
+
var PreferenceDeviceIdSchema = string().min(1).max(64);
|
|
14216
|
+
/** A stored row, as the owner reads it. */
|
|
14217
|
+
var PreferenceRowSchema = object({
|
|
14218
|
+
namespace: PreferenceNamespaceSchema,
|
|
14219
|
+
value: PreferenceValueSchema,
|
|
14220
|
+
/** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
|
|
14221
|
+
revision: number().int().positive(),
|
|
14222
|
+
updatedAt: number().int(),
|
|
14223
|
+
/** The client id the last writer sent; `null` when it sent none. */
|
|
14224
|
+
updatedByDevice: PreferenceDeviceIdSchema.nullable()
|
|
14225
|
+
});
|
|
14226
|
+
object({
|
|
14227
|
+
/** Absent: every namespace the caller holds. */
|
|
14228
|
+
namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
|
|
14229
|
+
object({ rows: array(PreferenceRowSchema) });
|
|
14230
|
+
object({
|
|
14231
|
+
namespace: PreferenceNamespaceSchema,
|
|
14232
|
+
value: PreferenceValueSchema,
|
|
14233
|
+
/**
|
|
14234
|
+
* The revision the edit was based on. Absent: last write wins. `0`: the
|
|
14235
|
+
* namespace must not exist yet. Any other value that is not the current
|
|
14236
|
+
* revision answers `conflict` and writes nothing.
|
|
14237
|
+
*/
|
|
14238
|
+
baseRevision: number().int().nonnegative().optional(),
|
|
14239
|
+
deviceId: PreferenceDeviceIdSchema.optional()
|
|
14240
|
+
});
|
|
14241
|
+
discriminatedUnion("status", [object({
|
|
14242
|
+
status: literal("saved"),
|
|
14243
|
+
row: PreferenceRowSchema
|
|
14244
|
+
}), object({
|
|
14245
|
+
status: literal("conflict"),
|
|
14246
|
+
current: PreferenceRowSchema.nullable()
|
|
14247
|
+
})]);
|
|
14248
|
+
object({ namespace: PreferenceNamespaceSchema });
|
|
14249
|
+
object({
|
|
14250
|
+
/** `false` when the namespace did not exist. */
|
|
14251
|
+
deleted: boolean() });
|
|
14252
|
+
object({
|
|
14253
|
+
/** The revision the client holds per namespace; a namespace it does not list is new to it. */
|
|
14254
|
+
revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
|
|
14255
|
+
object({
|
|
14256
|
+
/** Every row whose revision differs from the client's, and every row it did not list. */
|
|
14257
|
+
rows: array(PreferenceRowSchema),
|
|
14258
|
+
/** Namespaces the client listed that no longer exist. */
|
|
14259
|
+
deleted: array(PreferenceNamespaceSchema)
|
|
14260
|
+
});
|
|
14210
14261
|
_enum(["new-session", "step-up"]);
|
|
14211
14262
|
/** The languages the hub's app landing pages are written in (D858). */
|
|
14212
14263
|
var AppPageLangSchema = _enum(["en", "it"]);
|
|
@@ -18490,7 +18541,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
|
|
|
18490
18541
|
kind: literal("node"),
|
|
18491
18542
|
nodeId: string().min(1)
|
|
18492
18543
|
})]);
|
|
18544
|
+
/**
|
|
18545
|
+
* `enum` stores a STATE as the ordinal of its value in the series' value list
|
|
18546
|
+
* (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
|
|
18547
|
+
* meaning); a rollup keeps the time spent in each state (`states`).
|
|
18548
|
+
*/
|
|
18493
18549
|
var DeviceHistoryKindSchema = _enum([
|
|
18550
|
+
"gauge",
|
|
18551
|
+
"counter",
|
|
18552
|
+
"boolean",
|
|
18553
|
+
"enum"
|
|
18554
|
+
]);
|
|
18555
|
+
/** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
|
|
18556
|
+
var DeviceHistoryProducerKindSchema = _enum([
|
|
18494
18557
|
"gauge",
|
|
18495
18558
|
"counter",
|
|
18496
18559
|
"boolean"
|
|
@@ -18527,7 +18590,13 @@ var SeriesInfoSchema = object({
|
|
|
18527
18590
|
/** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
|
|
18528
18591
|
unit: string().nullable(),
|
|
18529
18592
|
displayName: string(),
|
|
18530
|
-
source: _enum([
|
|
18593
|
+
source: _enum([
|
|
18594
|
+
"cap",
|
|
18595
|
+
"addon",
|
|
18596
|
+
"derived"
|
|
18597
|
+
]),
|
|
18598
|
+
/** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
|
|
18599
|
+
values: array(string()).readonly().nullable(),
|
|
18531
18600
|
firstTs: number(),
|
|
18532
18601
|
lastTs: number()
|
|
18533
18602
|
});
|
|
@@ -18541,17 +18610,31 @@ var QueryPointSchema = object({
|
|
|
18541
18610
|
twMean: number().nullable(),
|
|
18542
18611
|
min: number(),
|
|
18543
18612
|
max: number(),
|
|
18544
|
-
/** `null` is unknown, never zero (D393). */
|
|
18545
|
-
last: number().nullable()
|
|
18613
|
+
/** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
|
|
18614
|
+
last: number().nullable(),
|
|
18615
|
+
/**
|
|
18616
|
+
* The increase over the point: a `counter`'s growth since the previous point
|
|
18617
|
+
* or bucket (a drop is a reset, counted from zero), and for
|
|
18618
|
+
* {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
|
|
18619
|
+
* every other kind, and when it cannot be known.
|
|
18620
|
+
*/
|
|
18621
|
+
delta: number().nullable(),
|
|
18622
|
+
/** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
|
|
18623
|
+
state: string().nullable(),
|
|
18624
|
+
/** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
|
|
18625
|
+
states: record(string(), number()).nullable()
|
|
18546
18626
|
});
|
|
18547
18627
|
var QuerySeriesSchema = object({
|
|
18548
18628
|
scope: string(),
|
|
18549
18629
|
/** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
|
|
18550
18630
|
before: object({
|
|
18551
18631
|
t: number(),
|
|
18552
|
-
value: number().nullable()
|
|
18632
|
+
value: number().nullable(),
|
|
18633
|
+
state: string().nullable()
|
|
18553
18634
|
}).nullable(),
|
|
18554
|
-
points: array(QueryPointSchema).readonly()
|
|
18635
|
+
points: array(QueryPointSchema).readonly(),
|
|
18636
|
+
/** A derived key: the stored key its points were computed from; `null` for a stored series. */
|
|
18637
|
+
derivedFrom: string().nullable()
|
|
18555
18638
|
});
|
|
18556
18639
|
/** The window part of a query, shared by the device and node forms. */
|
|
18557
18640
|
var QueryWindowShape = {
|
|
@@ -18567,6 +18650,23 @@ var QueryResultSchema = object({
|
|
|
18567
18650
|
series: array(QuerySeriesSchema).readonly(),
|
|
18568
18651
|
truncated: boolean()
|
|
18569
18652
|
});
|
|
18653
|
+
/** One read of a batch: a device's key or a node's key (exactly one subject). */
|
|
18654
|
+
var QueryManyItemSchema = union([object({
|
|
18655
|
+
deviceId: number().int(),
|
|
18656
|
+
key: string(),
|
|
18657
|
+
scope: string().optional()
|
|
18658
|
+
}), object({
|
|
18659
|
+
forNodeId: string().min(1),
|
|
18660
|
+
key: string(),
|
|
18661
|
+
scope: string().optional()
|
|
18662
|
+
})]);
|
|
18663
|
+
var QueryManyEntrySchema = discriminatedUnion("ok", [object({
|
|
18664
|
+
ok: literal(true),
|
|
18665
|
+
result: QueryResultSchema
|
|
18666
|
+
}), object({
|
|
18667
|
+
ok: literal(false),
|
|
18668
|
+
error: string()
|
|
18669
|
+
})]);
|
|
18570
18670
|
var TierStatusSchema = object({
|
|
18571
18671
|
tier: DeviceHistoryResolutionSchema,
|
|
18572
18672
|
/** `null` until the first background count answered. */
|
|
@@ -18622,16 +18722,22 @@ var DeviceHistoryStatusSchema = object({
|
|
|
18622
18722
|
lastRefreshAt: number().nullable()
|
|
18623
18723
|
})
|
|
18624
18724
|
});
|
|
18625
|
-
method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({
|
|
18725
|
+
method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
|
|
18626
18726
|
deviceId: number().int(),
|
|
18627
18727
|
...QueryWindowShape
|
|
18628
18728
|
}), QueryResultSchema), method(object({
|
|
18629
|
-
|
|
18729
|
+
forNodeId: string().min(1),
|
|
18630
18730
|
...QueryWindowShape
|
|
18631
18731
|
}), QueryResultSchema, { auth: "admin" }), method(object({
|
|
18732
|
+
items: array(QueryManyItemSchema).min(1).max(24),
|
|
18733
|
+
from: QueryWindowShape.from,
|
|
18734
|
+
to: QueryWindowShape.to,
|
|
18735
|
+
resolution: QueryWindowShape.resolution,
|
|
18736
|
+
maxPoints: QueryWindowShape.maxPoints
|
|
18737
|
+
}), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
|
|
18632
18738
|
name: string().regex(/^[a-z0-9-]+$/),
|
|
18633
18739
|
subjectKind: _enum(["device", "node"]),
|
|
18634
|
-
kind:
|
|
18740
|
+
kind: DeviceHistoryProducerKindSchema,
|
|
18635
18741
|
unit: string().optional(),
|
|
18636
18742
|
displayName: string().min(1),
|
|
18637
18743
|
ingest: _enum(["points", "buckets"])
|
|
@@ -41529,38 +41635,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
|
|
|
41529
41635
|
auth: "admin",
|
|
41530
41636
|
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
41531
41637
|
});
|
|
41638
|
+
var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
|
|
41639
|
+
/** What a model (or, by default, every model of a kind) can do. */
|
|
41640
|
+
var LlmModelFeaturesSchema = object({
|
|
41641
|
+
vision: boolean(),
|
|
41642
|
+
tools: boolean(),
|
|
41643
|
+
streaming: boolean()
|
|
41644
|
+
});
|
|
41645
|
+
/** One model a provider offers. `features` overrides the kind's defaults, per field. */
|
|
41646
|
+
var LlmModelInfoSchema = object({
|
|
41647
|
+
id: string(),
|
|
41648
|
+
label: string().optional(),
|
|
41649
|
+
contextLength: number().int().positive().optional(),
|
|
41650
|
+
features: LlmModelFeaturesSchema.partial().optional()
|
|
41651
|
+
});
|
|
41532
41652
|
/**
|
|
41533
|
-
*
|
|
41534
|
-
*
|
|
41535
|
-
*
|
|
41536
|
-
*
|
|
41537
|
-
* (hub-placed); the cap stays open for future providers.
|
|
41538
|
-
*
|
|
41539
|
-
* Profiles are ROWS (data), not addons: one row = one usable model endpoint.
|
|
41540
|
-
* `apiKey` is a password field — providers REDACT it on read and merge on
|
|
41541
|
-
* write; a stored key NEVER round-trips to a client.
|
|
41653
|
+
* The provider-specific part of a profile, validated by the provider that owns
|
|
41654
|
+
* the kind (`upsertProfile` refuses what it does not accept). A field its
|
|
41655
|
+
* `connectionSchema` declares `type: 'password'` is a secret: it is held in the
|
|
41656
|
+
* keychain, never in the row, and reads back as the redaction marker.
|
|
41542
41657
|
*/
|
|
41543
|
-
var
|
|
41544
|
-
"openai-compatible",
|
|
41545
|
-
"openai",
|
|
41546
|
-
"anthropic",
|
|
41547
|
-
"google",
|
|
41548
|
-
"managed-local",
|
|
41549
|
-
"apple-foundation"
|
|
41550
|
-
]);
|
|
41658
|
+
var LlmProviderConfigSchema = record(string(), unknown());
|
|
41551
41659
|
var LlmProfileSchema = object({
|
|
41552
41660
|
id: string(),
|
|
41553
41661
|
name: string(),
|
|
41662
|
+
/** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
|
|
41554
41663
|
kind: LlmProfileKindSchema,
|
|
41555
41664
|
/** Stamped by the provider — keeps the fanned catalog routable. */
|
|
41556
41665
|
addonId: string(),
|
|
41557
41666
|
enabled: boolean(),
|
|
41558
41667
|
/** Vendor model id, or the managed runtime's loaded model. */
|
|
41559
41668
|
model: string(),
|
|
41560
|
-
/** Required for openai-compatible; override for cloud kinds. */
|
|
41561
|
-
baseUrl: string().optional(),
|
|
41562
|
-
/** ConfigUISchema type:'password' — never round-trips (spec §5). */
|
|
41563
|
-
apiKey: string().optional(),
|
|
41564
41669
|
/** Vision on/off. A vision call against a `false` profile is REFUSED, never
|
|
41565
41670
|
* degraded to text — that shipped once and produced a confident answer to a
|
|
41566
41671
|
* question about a picture nobody sent. */
|
|
@@ -41568,15 +41673,11 @@ var LlmProfileSchema = object({
|
|
|
41568
41673
|
temperature: number().min(0).max(2).optional(),
|
|
41569
41674
|
/** Nucleus sampling. Every wire we speak has it. */
|
|
41570
41675
|
topP: number().min(0).max(1).optional(),
|
|
41571
|
-
/** Top-k sampling. Carried only by the wires that have it —
|
|
41572
|
-
*
|
|
41573
|
-
* `top_p` and no `top_k`). The profile editor hides the field wherever it
|
|
41574
|
-
* would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
|
|
41676
|
+
/** Top-k sampling. Carried only by the wires that have it — a kind offers the
|
|
41677
|
+
* field in its editor only when its descriptor lists it in `profileFields`. */
|
|
41575
41678
|
topK: number().int().positive().optional(),
|
|
41576
41679
|
maxTokens: number().int().positive().optional(),
|
|
41577
|
-
/** Prompt context window. Advisory for cloud kinds (they enforce their own)
|
|
41578
|
-
* for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
|
|
41579
|
-
* the model with, so it is the one field that changes a PROCESS. */
|
|
41680
|
+
/** Prompt context window. Advisory for cloud kinds (they enforce their own). */
|
|
41580
41681
|
contextLength: number().int().positive().optional(),
|
|
41581
41682
|
/** Default system prompt. A caller's `system` REPLACES it (never appends —
|
|
41582
41683
|
* two system prompts fighting is worse than either alone). */
|
|
@@ -41602,16 +41703,37 @@ var LlmProfileSchema = object({
|
|
|
41602
41703
|
* library; the REGISTRY of callable tools is ours and is empty in v1, so a
|
|
41603
41704
|
* `true` here buys the wiring, not behaviour, until tools are registered. */
|
|
41604
41705
|
toolsEnabled: boolean().default(false),
|
|
41605
|
-
|
|
41606
|
-
|
|
41607
|
-
|
|
41608
|
-
|
|
41609
|
-
|
|
41610
|
-
|
|
41611
|
-
|
|
41612
|
-
|
|
41613
|
-
|
|
41614
|
-
|
|
41706
|
+
/** Everything the kind's provider owns (endpoint, key, node, runtime…). */
|
|
41707
|
+
providerConfig: LlmProviderConfigSchema.default({})
|
|
41708
|
+
});
|
|
41709
|
+
/**
|
|
41710
|
+
* The common profile fields a kind's editor offers. The editor owns how each
|
|
41711
|
+
* one is drawn; the provider says which of them mean something on its wire.
|
|
41712
|
+
*/
|
|
41713
|
+
var LlmProfileFieldSchema = _enum([
|
|
41714
|
+
"temperature",
|
|
41715
|
+
"topP",
|
|
41716
|
+
"topK",
|
|
41717
|
+
"maxTokens",
|
|
41718
|
+
"contextLength",
|
|
41719
|
+
"systemPrompt",
|
|
41720
|
+
"timeoutMs",
|
|
41721
|
+
"connectTimeoutMs",
|
|
41722
|
+
"firstTokenTimeoutMs",
|
|
41723
|
+
"idleTimeoutMs",
|
|
41724
|
+
"retry",
|
|
41725
|
+
"toolsEnabled"
|
|
41726
|
+
]);
|
|
41727
|
+
/**
|
|
41728
|
+
* A provider-drawn part of the editor, by a generic widget id the admin UI
|
|
41729
|
+
* registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
|
|
41730
|
+
* picker: that widget owns the model choice.
|
|
41731
|
+
*/
|
|
41732
|
+
var LlmProviderWidgetSchema = object({
|
|
41733
|
+
id: string(),
|
|
41734
|
+
placement: _enum(["connection", "model"]),
|
|
41735
|
+
/** `providerConfig` keys this widget must fill before the profile can be saved. */
|
|
41736
|
+
requires: array(string()).optional()
|
|
41615
41737
|
});
|
|
41616
41738
|
/** ConfigUISchema tree passed through untyped on the wire (the
|
|
41617
41739
|
* notification-output `ConfigSchemaPassthrough` precedent at
|
|
@@ -41620,11 +41742,56 @@ var ConfigSchemaPassthrough$3 = unknown();
|
|
|
41620
41742
|
var LlmProfileKindDescriptorSchema = object({
|
|
41621
41743
|
kind: LlmProfileKindSchema,
|
|
41622
41744
|
label: string(),
|
|
41745
|
+
/** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
|
|
41623
41746
|
icon: string(),
|
|
41624
41747
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
41625
41748
|
addonId: string(),
|
|
41626
|
-
|
|
41749
|
+
/** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
|
|
41750
|
+
connectionSchema: ConfigSchemaPassthrough$3,
|
|
41751
|
+
/** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
|
|
41752
|
+
advancedSchema: ConfigSchemaPassthrough$3.optional(),
|
|
41753
|
+
/** The kind's defaults; a model from `listModels` may override any of them. */
|
|
41754
|
+
features: LlmModelFeaturesSchema,
|
|
41755
|
+
/** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
|
|
41756
|
+
visionEditable: boolean(),
|
|
41757
|
+
/** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
|
|
41758
|
+
modelCatalog: _enum([
|
|
41759
|
+
"fetch",
|
|
41760
|
+
"static",
|
|
41761
|
+
"none"
|
|
41762
|
+
]),
|
|
41763
|
+
staticModels: array(LlmModelInfoSchema).optional(),
|
|
41764
|
+
/** The common fields that mean something on this kind's wire. */
|
|
41765
|
+
profileFields: array(LlmProfileFieldSchema),
|
|
41766
|
+
providerWidgets: array(LlmProviderWidgetSchema).optional()
|
|
41627
41767
|
});
|
|
41768
|
+
/**
|
|
41769
|
+
* `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
|
|
41770
|
+
* (the editor's form); with `profileId` too, a secret the draft leaves
|
|
41771
|
+
* untouched (absent or the redaction marker) is resolved server-side from the
|
|
41772
|
+
* stored profile — the browser never receives it.
|
|
41773
|
+
*/
|
|
41774
|
+
var LlmListModelsInputSchema = object({
|
|
41775
|
+
addonId: string(),
|
|
41776
|
+
kind: LlmProfileKindSchema,
|
|
41777
|
+
profileId: string().optional(),
|
|
41778
|
+
connection: LlmProviderConfigSchema.optional()
|
|
41779
|
+
});
|
|
41780
|
+
var LlmListModelsErrorCodeSchema = _enum([
|
|
41781
|
+
"auth",
|
|
41782
|
+
"network",
|
|
41783
|
+
"unsupported",
|
|
41784
|
+
"invalid"
|
|
41785
|
+
]);
|
|
41786
|
+
/** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
|
|
41787
|
+
var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
|
|
41788
|
+
ok: literal(true),
|
|
41789
|
+
models: array(LlmModelInfoSchema)
|
|
41790
|
+
}), object({
|
|
41791
|
+
ok: literal(false),
|
|
41792
|
+
code: LlmListModelsErrorCodeSchema,
|
|
41793
|
+
message: string()
|
|
41794
|
+
})]);
|
|
41628
41795
|
var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
|
|
41629
41796
|
var LlmDefaultSchema = object({
|
|
41630
41797
|
selector: LlmDefaultSelectorSchema,
|
|
@@ -41724,7 +41891,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
|
|
|
41724
41891
|
kind: "mutation",
|
|
41725
41892
|
auth: "admin",
|
|
41726
41893
|
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
41727
|
-
}), method(
|
|
41894
|
+
}), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
41895
|
+
kind: "mutation",
|
|
41896
|
+
auth: "admin"
|
|
41897
|
+
}), method(object({}), array(LlmDefaultSchema)), method(object({
|
|
41728
41898
|
selector: LlmDefaultSelectorSchema,
|
|
41729
41899
|
profileId: string().nullable()
|
|
41730
41900
|
}), _void(), {
|
|
@@ -41892,14 +42062,106 @@ var LogEntrySchema = object({
|
|
|
41892
42062
|
meta: record(string(), unknown()).optional(),
|
|
41893
42063
|
tags: record(string(), string()).optional()
|
|
41894
42064
|
});
|
|
41895
|
-
|
|
41896
|
-
|
|
42065
|
+
/**
|
|
42066
|
+
* A history READ against one destination (D898).
|
|
42067
|
+
*
|
|
42068
|
+
* Every filter is applied by the PROVIDER, before the limit — a filter the
|
|
42069
|
+
* browser applied after the limit is what made a rare device's lines
|
|
42070
|
+
* unreachable behind a busy one's. `before` / `after` are cursors the provider
|
|
42071
|
+
* minted (opaque to everyone else): a file position for the rotated files, a
|
|
42072
|
+
* nanosecond timestamp for Loki.
|
|
42073
|
+
*
|
|
42074
|
+
* A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
|
|
42075
|
+
* store answers `done: false` with the cursor it reached and the bytes it
|
|
42076
|
+
* scanned, and the caller decides whether to go on. That is what makes a long
|
|
42077
|
+
* scan show progress and stop when asked — `cancelRead` ends the slice in
|
|
42078
|
+
* flight, and not asking for the next slice ends the scan.
|
|
42079
|
+
*/
|
|
42080
|
+
var LogReadQuerySchema = object({
|
|
42081
|
+
/** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
|
|
42082
|
+
requestId: string().min(1).max(64).optional(),
|
|
42083
|
+
/** The device the line is about (`tags.deviceId`, numeric). */
|
|
42084
|
+
deviceId: number().int().optional(),
|
|
42085
|
+
/**
|
|
42086
|
+
* The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
|
|
42087
|
+
* match. Not `addonId`: a cap router reads that name as "which provider".
|
|
42088
|
+
*/
|
|
42089
|
+
fromAddonId: string().min(1).max(200).optional(),
|
|
42090
|
+
/**
|
|
42091
|
+
* The emitting node: matches the agent that emitted the line, the node
|
|
42092
|
+
* itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
|
|
42093
|
+
* semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
|
|
42094
|
+
* name as "which node's provider".
|
|
42095
|
+
*/
|
|
42096
|
+
fromNodeId: string().min(1).max(200).optional(),
|
|
42097
|
+
/** Any other tag, exact match (AND). */
|
|
42098
|
+
tags: record(string(), union([string(), number()])).optional(),
|
|
42099
|
+
/** Severity FLOOR: this level and above. */
|
|
41897
42100
|
level: LogLevelSchema.optional(),
|
|
41898
|
-
|
|
41899
|
-
|
|
41900
|
-
|
|
41901
|
-
|
|
41902
|
-
|
|
42101
|
+
/** Case-insensitive substring over message, scope, tag values and meta values. */
|
|
42102
|
+
text: string().min(1).max(200).optional(),
|
|
42103
|
+
/** Epoch ms, inclusive. */
|
|
42104
|
+
since: number().optional(),
|
|
42105
|
+
/** Epoch ms, inclusive. */
|
|
42106
|
+
until: number().optional(),
|
|
42107
|
+
/** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
|
|
42108
|
+
before: string().min(1).max(1024).optional(),
|
|
42109
|
+
/** Newer than this cursor (exclusive). */
|
|
42110
|
+
after: string().min(1).max(1024).optional(),
|
|
42111
|
+
limit: number().int().min(1).max(1e3).optional(),
|
|
42112
|
+
/** Wall-clock bound of this slice. The provider caps it. */
|
|
42113
|
+
budgetMs: number().int().min(50).max(1e4).optional()
|
|
42114
|
+
});
|
|
42115
|
+
var LogReadResultSchema = object({
|
|
42116
|
+
/** Newest first. */
|
|
42117
|
+
entries: array(object({
|
|
42118
|
+
/** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
|
|
42119
|
+
id: string().optional(),
|
|
42120
|
+
/** Epoch ms. */
|
|
42121
|
+
timestamp: number(),
|
|
42122
|
+
level: LogLevelSchema,
|
|
42123
|
+
scope: string().optional(),
|
|
42124
|
+
message: string(),
|
|
42125
|
+
tags: record(string(), union([string(), number()])).optional(),
|
|
42126
|
+
meta: record(string(), unknown()).optional()
|
|
42127
|
+
})),
|
|
42128
|
+
/** Pass as `before` for the next older page; null when nothing older exists. */
|
|
42129
|
+
nextBefore: string().nullable(),
|
|
42130
|
+
/** Pass as `after` to read what arrived since; null when unknown. */
|
|
42131
|
+
nextAfter: string().nullable(),
|
|
42132
|
+
/** Bytes this slice read (files) or received (remote). Progress, not a promise. */
|
|
42133
|
+
scannedBytes: number().int().nonnegative(),
|
|
42134
|
+
/**
|
|
42135
|
+
* True when the scan in this direction reached the end of the store.
|
|
42136
|
+
* False with fewer than `limit` entries means the budget ran out first —
|
|
42137
|
+
* call again with `nextBefore` to go on.
|
|
42138
|
+
*/
|
|
42139
|
+
done: boolean(),
|
|
42140
|
+
/** True when `cancelRead` ended this slice early. */
|
|
42141
|
+
cancelled: boolean().optional()
|
|
42142
|
+
});
|
|
42143
|
+
var LogReadCapabilitiesSchema = object({
|
|
42144
|
+
/** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
|
|
42145
|
+
readable: boolean(),
|
|
42146
|
+
/** Why not, when `readable` is false — rendered next to the source. */
|
|
42147
|
+
reason: string().nullable(),
|
|
42148
|
+
/** Filters the provider applies itself. A false one is applied by nobody. */
|
|
42149
|
+
filters: object({
|
|
42150
|
+
deviceId: boolean(),
|
|
42151
|
+
addonId: boolean(),
|
|
42152
|
+
nodeId: boolean(),
|
|
42153
|
+
tags: boolean(),
|
|
42154
|
+
level: boolean(),
|
|
42155
|
+
text: boolean(),
|
|
42156
|
+
timeRange: boolean()
|
|
42157
|
+
}),
|
|
42158
|
+
/** How far back the store reaches, when the provider knows (days). */
|
|
42159
|
+
retentionDays: number().nullable()
|
|
42160
|
+
});
|
|
42161
|
+
method(LogEntrySchema, _void(), { kind: "mutation" }), optionalMethod(_void(), LogReadCapabilitiesSchema, { auth: "admin" }), optionalMethod(LogReadQuerySchema, LogReadResultSchema, { auth: "admin" }), optionalMethod(object({ requestId: string().min(1).max(64) }), object({ cancelled: boolean() }), {
|
|
42162
|
+
kind: "mutation",
|
|
42163
|
+
auth: "admin"
|
|
42164
|
+
});
|
|
41903
42165
|
/**
|
|
41904
42166
|
* `login-method` — collection cap through which auth addons contribute
|
|
41905
42167
|
* their pre-auth login surfaces to the login page. This is the SINGLE,
|
|
@@ -43648,9 +43910,11 @@ var alarmPanelCapability = {
|
|
|
43648
43910
|
*/
|
|
43649
43911
|
durability: "restored",
|
|
43650
43912
|
/**
|
|
43651
|
-
* History (D850):
|
|
43913
|
+
* History (D850): the panel's lifecycle state as an `enum` series —
|
|
43914
|
+
* change-only, no floor, so an `arming -> pending -> triggered` sequence of a
|
|
43915
|
+
* few seconds keeps every step. Who armed it stays in the events ledger.
|
|
43652
43916
|
*/
|
|
43653
|
-
history: "
|
|
43917
|
+
history: { fields: { state: { kind: "enum" } } },
|
|
43654
43918
|
/** Clock fields: written, but excluded from the compare that decides
|
|
43655
43919
|
* whether persisting is worth a SQLite commit. */
|
|
43656
43920
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -44572,6 +44836,33 @@ var NcRuleTargetSchema = object({
|
|
|
44572
44836
|
params: record(string(), unknown()).optional()
|
|
44573
44837
|
});
|
|
44574
44838
|
/**
|
|
44839
|
+
* WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
|
|
44840
|
+
*
|
|
44841
|
+
* Every mode starts from the same CLEAN source frame of the trigger moment
|
|
44842
|
+
* (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
|
|
44843
|
+
* to the zone that fired the rule) and renders it once at send time:
|
|
44844
|
+
* - `scene-boxes` — the whole scene, the subject outlined thick in the accent
|
|
44845
|
+
* colour and every OTHER track visible at that instant outlined thin, each
|
|
44846
|
+
* labelled with class and confidence ("dog 87%").
|
|
44847
|
+
* - `crop` — the subject cut out of that frame around its box at that instant.
|
|
44848
|
+
* - `clean` — the whole scene with nothing drawn on it.
|
|
44849
|
+
* - `none` — no picture.
|
|
44850
|
+
*
|
|
44851
|
+
* A mode that cannot be honoured (no box at that instant, a photograph with no
|
|
44852
|
+
* tracked subject) ships `clean` and names the reason in the log, per camera.
|
|
44853
|
+
* It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
|
|
44854
|
+
* ship a crop on one event and a boxed scene on the next depending on which
|
|
44855
|
+
* stored kind had landed.
|
|
44856
|
+
*/
|
|
44857
|
+
var NcMediaImageSchema = _enum([
|
|
44858
|
+
"scene-boxes",
|
|
44859
|
+
"crop",
|
|
44860
|
+
"clean",
|
|
44861
|
+
"none"
|
|
44862
|
+
]);
|
|
44863
|
+
/**
|
|
44864
|
+
* @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
|
|
44865
|
+
*
|
|
44575
44866
|
* Media attachment policy (P1 still-image subset).
|
|
44576
44867
|
* - `best` — the best AVAILABLE subject image at dispatch time (D-3).
|
|
44577
44868
|
* - `best-matching` — the media that explains WHY the rule fired: a rule
|
|
@@ -44585,6 +44876,8 @@ var NcRuleTargetSchema = object({
|
|
|
44585
44876
|
* - `none` — no attachment.
|
|
44586
44877
|
*/
|
|
44587
44878
|
/**
|
|
44879
|
+
* @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
|
|
44880
|
+
*
|
|
44588
44881
|
* WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
|
|
44589
44882
|
* conflate it with the selection strategy and betray the request: asking for
|
|
44590
44883
|
* the clean scene frame on an object-event owner used to start at
|
|
@@ -44631,16 +44924,29 @@ var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
|
|
|
44631
44924
|
var NC_CLIP_PRE_ROLL_DEFAULT_SEC = 4;
|
|
44632
44925
|
var NC_CLIP_POST_ROLL_DEFAULT_SEC = 6;
|
|
44633
44926
|
var NcMediaPolicySchema = object({
|
|
44927
|
+
/**
|
|
44928
|
+
* The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
|
|
44929
|
+
* saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
|
|
44930
|
+
* triple below, at load and at every write, and the store keeps only this.
|
|
44931
|
+
*/
|
|
44932
|
+
image: NcMediaImageSchema.optional(),
|
|
44933
|
+
/**
|
|
44934
|
+
* Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
|
|
44935
|
+
* a `crop` never shows it). Valid only on a rule whose trigger is a zone —
|
|
44936
|
+
* `conditions.zones` or an occupancy zone — and refused on save otherwise.
|
|
44937
|
+
* Replaces `zoneCrop`.
|
|
44938
|
+
*/
|
|
44939
|
+
showTriggerZone: boolean().optional(),
|
|
44940
|
+
/** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
|
|
44634
44941
|
attach: _enum([
|
|
44635
44942
|
"best",
|
|
44636
44943
|
"best-matching",
|
|
44637
44944
|
"keyFrame",
|
|
44638
44945
|
"none"
|
|
44639
|
-
]).
|
|
44640
|
-
/**
|
|
44946
|
+
]).optional(),
|
|
44947
|
+
/** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
|
|
44641
44948
|
frame: NcMediaFrameSchema.optional(),
|
|
44642
|
-
/**
|
|
44643
|
-
* "show me the ZONE", not the whole scene or the subject crop. */
|
|
44949
|
+
/** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
|
|
44644
44950
|
zoneCrop: boolean().optional(),
|
|
44645
44951
|
/**
|
|
44646
44952
|
* Also attach a short GIF cut from the stream broker's clip ring around the
|
|
@@ -44826,7 +45132,9 @@ var NcRuleInputSchema = object({
|
|
|
44826
45132
|
* targets.
|
|
44827
45133
|
*/
|
|
44828
45134
|
targetUsers: array(string()).optional(),
|
|
44829
|
-
|
|
45135
|
+
/** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
|
|
45136
|
+
* detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
|
|
45137
|
+
media: NcMediaPolicySchema.default({}),
|
|
44830
45138
|
throttle: NcThrottleSchema.default({
|
|
44831
45139
|
cooldownSec: 60,
|
|
44832
45140
|
scope: "rule-device"
|
|
@@ -46361,13 +46669,37 @@ var NcAlarmModeOpeningsSchema = object({
|
|
|
46361
46669
|
/** Covered devices whose state could not be read (D49): neither open nor closed. */
|
|
46362
46670
|
unknown: array(number().int())
|
|
46363
46671
|
});
|
|
46672
|
+
/**
|
|
46673
|
+
* One alarm INPUT — a (rule, device) pair — the operator bypassed until the
|
|
46674
|
+
* next disarm ("Bypass this input until disarm" on a trigger notification, or
|
|
46675
|
+
* `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
|
|
46676
|
+
* never looks fully armed (D62: off must never look like broken).
|
|
46677
|
+
*/
|
|
46678
|
+
var NcAlarmInputBypassViewSchema = object({
|
|
46679
|
+
ruleId: string(),
|
|
46680
|
+
/** The rule's current name (its frozen name when the rule is gone). */
|
|
46681
|
+
ruleName: string(),
|
|
46682
|
+
/** The input: the sensor of the match, else its camera. */
|
|
46683
|
+
deviceId: number().int(),
|
|
46684
|
+
/** The input's current name. */
|
|
46685
|
+
name: string(),
|
|
46686
|
+
/** When it was bypassed (ms epoch). */
|
|
46687
|
+
since: number(),
|
|
46688
|
+
/** Triggers from this input dropped since. */
|
|
46689
|
+
dropped: number().int().min(0)
|
|
46690
|
+
});
|
|
46364
46691
|
var NcAlarmLiveSchema = object({
|
|
46365
46692
|
state: AlarmStateSchema,
|
|
46366
46693
|
/** The mode being armed into (exit delay) or held; null when disarmed. */
|
|
46367
46694
|
targetMode: AlarmArmModeSchema.nullable(),
|
|
46368
46695
|
availableModes: array(AlarmArmModeSchema),
|
|
46369
46696
|
openings: array(NcAlarmModeOpeningsSchema),
|
|
46370
|
-
exclusions: array(NcAlarmExclusionViewSchema)
|
|
46697
|
+
exclusions: array(NcAlarmExclusionViewSchema),
|
|
46698
|
+
/**
|
|
46699
|
+
* Inputs bypassed for the rest of this arm session; cleared on disarm.
|
|
46700
|
+
* Defaulted so an older hub answer still parses (as "none known").
|
|
46701
|
+
*/
|
|
46702
|
+
bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
|
|
46371
46703
|
});
|
|
46372
46704
|
var NcAlarmConfigSchema = object({
|
|
46373
46705
|
/**
|
|
@@ -58277,9 +58609,11 @@ var connectivityCapability = {
|
|
|
58277
58609
|
*/
|
|
58278
58610
|
durability: "restored",
|
|
58279
58611
|
/**
|
|
58280
|
-
* History (D850):
|
|
58612
|
+
* History (D850): `connected` as a boolean series — change-only, no floor. It
|
|
58613
|
+
* is the upstream entity's own link (a HA connectivity sensor), not the
|
|
58614
|
+
* device's reachability, which stays `device-status.online`.
|
|
58281
58615
|
*/
|
|
58282
|
-
history: "
|
|
58616
|
+
history: { fields: { connected: { kind: "boolean" } } },
|
|
58283
58617
|
/** Clock fields: written, but excluded from the compare that decides
|
|
58284
58618
|
* whether persisting is worth a SQLite commit. */
|
|
58285
58619
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -59125,11 +59459,22 @@ var dishwasherCapability = {
|
|
|
59125
59459
|
},
|
|
59126
59460
|
runtimeState: DishwasherStatusSchema,
|
|
59127
59461
|
durability: "session",
|
|
59128
|
-
history: { fields: {
|
|
59129
|
-
|
|
59130
|
-
|
|
59131
|
-
|
|
59132
|
-
|
|
59462
|
+
history: { fields: {
|
|
59463
|
+
progressPercent: {
|
|
59464
|
+
kind: "gauge",
|
|
59465
|
+
unit: "%",
|
|
59466
|
+
deadband: 2
|
|
59467
|
+
},
|
|
59468
|
+
state: { kind: "enum" },
|
|
59469
|
+
operationState: { kind: "enum" },
|
|
59470
|
+
remainingSeconds: {
|
|
59471
|
+
kind: "gauge",
|
|
59472
|
+
unit: "s",
|
|
59473
|
+
minIntervalMs: 6e4
|
|
59474
|
+
},
|
|
59475
|
+
doorOpen: { kind: "boolean" },
|
|
59476
|
+
powerOn: { kind: "boolean" }
|
|
59477
|
+
} }
|
|
59133
59478
|
};
|
|
59134
59479
|
var DoorbellStatusSchema = object({
|
|
59135
59480
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
@@ -59246,9 +59591,15 @@ var enumSensorCapability = {
|
|
|
59246
59591
|
*/
|
|
59247
59592
|
durability: "restored",
|
|
59248
59593
|
/**
|
|
59249
|
-
* History (D850):
|
|
59594
|
+
* History (D850): the value as an `enum` series (an appliance's program or
|
|
59595
|
+
* operation state, an HVAC action). The option set is per device, so the
|
|
59596
|
+
* value list is LEARNED as values are first seen (bounded). A sensor with a
|
|
59597
|
+
* `format` carries a timestamp, not a state, and is not recorded.
|
|
59250
59598
|
*/
|
|
59251
|
-
history:
|
|
59599
|
+
history: { fields: { value: {
|
|
59600
|
+
kind: "enum",
|
|
59601
|
+
skipWhenSet: "format"
|
|
59602
|
+
} } },
|
|
59252
59603
|
/** Clock fields: written, but excluded from the compare that decides
|
|
59253
59604
|
* whether persisting is worth a SQLite commit. */
|
|
59254
59605
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -61282,9 +61633,10 @@ var lockControlCapability = {
|
|
|
61282
61633
|
*/
|
|
61283
61634
|
durability: "restored",
|
|
61284
61635
|
/**
|
|
61285
|
-
* History (D850):
|
|
61636
|
+
* History (D850): the lock's state as an `enum` series — change-only, no
|
|
61637
|
+
* floor: a jam or an unlock lasting seconds is the edge an operator looks for.
|
|
61286
61638
|
*/
|
|
61287
|
-
history: "
|
|
61639
|
+
history: { fields: { state: { kind: "enum" } } },
|
|
61288
61640
|
/** Clock fields: written, but excluded from the compare that decides
|
|
61289
61641
|
* whether persisting is worth a SQLite commit. */
|
|
61290
61642
|
volatileStateFields: ["lastChangedAt"]
|
|
@@ -61458,9 +61810,18 @@ var mediaPlayerCapability = {
|
|
|
61458
61810
|
*/
|
|
61459
61811
|
durability: "session",
|
|
61460
61812
|
/**
|
|
61461
|
-
* History (D850):
|
|
61813
|
+
* History (D850): volume (a level an operator or an automation sets; the
|
|
61814
|
+
* default 10 s floor folds a slider drag into its end value) and mute.
|
|
61815
|
+
* `positionMs` is not recorded: it moves continuously while playing.
|
|
61462
61816
|
*/
|
|
61463
|
-
history:
|
|
61817
|
+
history: { fields: {
|
|
61818
|
+
volumeLevel: {
|
|
61819
|
+
kind: "gauge",
|
|
61820
|
+
unit: "%",
|
|
61821
|
+
deadband: 1
|
|
61822
|
+
},
|
|
61823
|
+
isMuted: { kind: "boolean" }
|
|
61824
|
+
} }
|
|
61464
61825
|
};
|
|
61465
61826
|
/**
|
|
61466
61827
|
* mesh-network — collection cap for mesh-VPN providers.
|
|
@@ -66862,9 +67223,29 @@ var streamParamsCapability = {
|
|
|
66862
67223
|
*/
|
|
66863
67224
|
durability: "restored",
|
|
66864
67225
|
/**
|
|
66865
|
-
* History (D850):
|
|
67226
|
+
* History (D850): the configured bitrate and frame rate of the main and sub
|
|
67227
|
+
* profiles. Configuration, so change-only on the default floor: a point is an
|
|
67228
|
+
* operator's (or a tuner's) edit, which is exactly what a chart of a stream's
|
|
67229
|
+
* quality over time must show.
|
|
66866
67230
|
*/
|
|
66867
|
-
history:
|
|
67231
|
+
history: { fields: {
|
|
67232
|
+
"main.bitrate": {
|
|
67233
|
+
kind: "gauge",
|
|
67234
|
+
unit: "kbps"
|
|
67235
|
+
},
|
|
67236
|
+
"main.framerate": {
|
|
67237
|
+
kind: "gauge",
|
|
67238
|
+
unit: "fps"
|
|
67239
|
+
},
|
|
67240
|
+
"sub.bitrate": {
|
|
67241
|
+
kind: "gauge",
|
|
67242
|
+
unit: "kbps"
|
|
67243
|
+
},
|
|
67244
|
+
"sub.framerate": {
|
|
67245
|
+
kind: "gauge",
|
|
67246
|
+
unit: "fps"
|
|
67247
|
+
}
|
|
67248
|
+
} },
|
|
66868
67249
|
/** Clock fields: written, but excluded from the compare that decides
|
|
66869
67250
|
* whether persisting is worth a SQLite commit. */
|
|
66870
67251
|
volatileStateFields: ["lastFetchedAt"]
|
|
@@ -67699,26 +68080,6 @@ var ApiKeySummarySchema = object({
|
|
|
67699
68080
|
createdAt: number(),
|
|
67700
68081
|
lastUsedAt: number().optional()
|
|
67701
68082
|
});
|
|
67702
|
-
var ScopedTokenSummarySchema = object({
|
|
67703
|
-
id: string(),
|
|
67704
|
-
userId: string(),
|
|
67705
|
-
name: string(),
|
|
67706
|
-
tokenPrefix: string(),
|
|
67707
|
-
scopes: array(TokenScopeSchema),
|
|
67708
|
-
expiresAt: number().nullish(),
|
|
67709
|
-
lastUsedAt: number().nullish(),
|
|
67710
|
-
createdAt: number()
|
|
67711
|
-
});
|
|
67712
|
-
var CreateScopedTokenInputSchema = object({
|
|
67713
|
-
userId: string(),
|
|
67714
|
-
name: string(),
|
|
67715
|
-
scopes: array(TokenScopeSchema),
|
|
67716
|
-
expiresAt: number().optional()
|
|
67717
|
-
});
|
|
67718
|
-
var CreateScopedTokenResultSchema = object({
|
|
67719
|
-
token: string(),
|
|
67720
|
-
record: ScopedTokenSummarySchema
|
|
67721
|
-
});
|
|
67722
68083
|
var OauthSessionSummarySchema = object({
|
|
67723
68084
|
id: string(),
|
|
67724
68085
|
userId: string(),
|
|
@@ -67740,11 +68101,11 @@ var TotpStatusSchema = object({
|
|
|
67740
68101
|
confirmedAt: number().nullable()
|
|
67741
68102
|
});
|
|
67742
68103
|
/**
|
|
67743
|
-
* user-management — singleton capability for user accounts
|
|
67744
|
-
*
|
|
68104
|
+
* user-management — singleton capability for user accounts and the
|
|
68105
|
+
* legacy API-key rows.
|
|
67745
68106
|
*
|
|
67746
68107
|
* v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
|
|
67747
|
-
* — the subset check on `setUserScopes`
|
|
68108
|
+
* — the subset check on `setUserScopes` is moot
|
|
67748
68109
|
* because non-admins never reach these. If/when we open non-admin
|
|
67749
68110
|
* delegation, structural caller-scope subset check goes inside the
|
|
67750
68111
|
* provider.
|
|
@@ -67801,15 +68162,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
|
|
|
67801
68162
|
kind: "mutation",
|
|
67802
68163
|
auth: "admin",
|
|
67803
68164
|
access: "delete"
|
|
67804
|
-
}), method(
|
|
67805
|
-
kind: "mutation",
|
|
67806
|
-
auth: "admin",
|
|
67807
|
-
access: "create"
|
|
67808
|
-
}), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
67809
|
-
kind: "mutation",
|
|
67810
|
-
auth: "admin",
|
|
67811
|
-
access: "delete"
|
|
67812
|
-
}), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
|
|
68165
|
+
}), method(object({ userId: string() }), TotpSetupResultSchema, {
|
|
67813
68166
|
kind: "mutation",
|
|
67814
68167
|
auth: "admin",
|
|
67815
68168
|
access: "create"
|
|
@@ -70123,6 +70476,15 @@ var BaseDevice = class {
|
|
|
70123
70476
|
* Drivers can use the `getProbeFlags()` helper to read the flag bag
|
|
70124
70477
|
* with a typed cast.
|
|
70125
70478
|
*
|
|
70479
|
+
* Answer what you KNOW. A plain array is read as the complete list only
|
|
70480
|
+
* while this device is `online` and probed; return
|
|
70481
|
+
* `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
|
|
70482
|
+
* now (no credentials, parent not connected, a failed or partial read) —
|
|
70483
|
+
* the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
|
|
70484
|
+
* to say "connected, and this is the complete list" explicitly. A shrink is
|
|
70485
|
+
* deleted only after a second agreeing complete read on a later probe (D49;
|
|
70486
|
+
* `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
|
|
70487
|
+
*
|
|
70126
70488
|
* Default: no children.
|
|
70127
70489
|
*/
|
|
70128
70490
|
getAccessoryChildren() {
|
|
@@ -73469,7 +73831,7 @@ Object.freeze({
|
|
|
73469
73831
|
capName: "llm",
|
|
73470
73832
|
capScope: "system",
|
|
73471
73833
|
addonId: null,
|
|
73472
|
-
access: "
|
|
73834
|
+
access: "create"
|
|
73473
73835
|
},
|
|
73474
73836
|
"llm.listNodeModels": {
|
|
73475
73837
|
capName: "llm",
|
|
@@ -73771,7 +74133,19 @@ Object.freeze({
|
|
|
73771
74133
|
addonId: null,
|
|
73772
74134
|
access: "view"
|
|
73773
74135
|
},
|
|
73774
|
-
"logDestination.
|
|
74136
|
+
"logDestination.cancelRead": {
|
|
74137
|
+
capName: "log-destination",
|
|
74138
|
+
capScope: "system",
|
|
74139
|
+
addonId: null,
|
|
74140
|
+
access: "create"
|
|
74141
|
+
},
|
|
74142
|
+
"logDestination.describeRead": {
|
|
74143
|
+
capName: "log-destination",
|
|
74144
|
+
capScope: "system",
|
|
74145
|
+
addonId: null,
|
|
74146
|
+
access: "view"
|
|
74147
|
+
},
|
|
74148
|
+
"logDestination.read": {
|
|
73775
74149
|
capName: "log-destination",
|
|
73776
74150
|
capScope: "system",
|
|
73777
74151
|
addonId: null,
|
|
@@ -78133,12 +78507,6 @@ Object.freeze({
|
|
|
78133
78507
|
addonId: null,
|
|
78134
78508
|
access: "create"
|
|
78135
78509
|
},
|
|
78136
|
-
"userManagement.createScopedToken": {
|
|
78137
|
-
capName: "user-management",
|
|
78138
|
-
capScope: "system",
|
|
78139
|
-
addonId: null,
|
|
78140
|
-
access: "create"
|
|
78141
|
-
},
|
|
78142
78510
|
"userManagement.createUser": {
|
|
78143
78511
|
capName: "user-management",
|
|
78144
78512
|
capScope: "system",
|
|
@@ -78187,12 +78555,6 @@ Object.freeze({
|
|
|
78187
78555
|
addonId: null,
|
|
78188
78556
|
access: "view"
|
|
78189
78557
|
},
|
|
78190
|
-
"userManagement.listScopedTokens": {
|
|
78191
|
-
capName: "user-management",
|
|
78192
|
-
capScope: "system",
|
|
78193
|
-
addonId: null,
|
|
78194
|
-
access: "view"
|
|
78195
|
-
},
|
|
78196
78558
|
"userManagement.listUsers": {
|
|
78197
78559
|
capName: "user-management",
|
|
78198
78560
|
capScope: "system",
|
|
@@ -78247,12 +78609,6 @@ Object.freeze({
|
|
|
78247
78609
|
addonId: null,
|
|
78248
78610
|
access: "delete"
|
|
78249
78611
|
},
|
|
78250
|
-
"userManagement.revokeScopedToken": {
|
|
78251
|
-
capName: "user-management",
|
|
78252
|
-
capScope: "system",
|
|
78253
|
-
addonId: null,
|
|
78254
|
-
access: "delete"
|
|
78255
|
-
},
|
|
78256
78612
|
"userManagement.setupTotp": {
|
|
78257
78613
|
capName: "user-management",
|
|
78258
78614
|
capScope: "system",
|
|
@@ -78283,12 +78639,6 @@ Object.freeze({
|
|
|
78283
78639
|
addonId: null,
|
|
78284
78640
|
access: "view"
|
|
78285
78641
|
},
|
|
78286
|
-
"userManagement.validateScopedToken": {
|
|
78287
|
-
capName: "user-management",
|
|
78288
|
-
capScope: "system",
|
|
78289
|
-
addonId: null,
|
|
78290
|
-
access: "view"
|
|
78291
|
-
},
|
|
78292
78642
|
"userManagement.verifyTotp": {
|
|
78293
78643
|
capName: "user-management",
|
|
78294
78644
|
capScope: "system",
|
|
@@ -79802,6 +80152,11 @@ Object.freeze({
|
|
|
79802
80152
|
form: "single",
|
|
79803
80153
|
optional: false
|
|
79804
80154
|
}],
|
|
80155
|
+
"logDestination.read": [{
|
|
80156
|
+
name: "deviceId",
|
|
80157
|
+
form: "single",
|
|
80158
|
+
optional: true
|
|
80159
|
+
}],
|
|
79805
80160
|
"mediaPlayer.getStatus": [{
|
|
79806
80161
|
name: "deviceId",
|
|
79807
80162
|
form: "single",
|
|
@@ -82051,6 +82406,123 @@ function isSystemRuleKind(kind) {
|
|
|
82051
82406
|
function systemFamilyOfKind(kind) {
|
|
82052
82407
|
return isSystemEventFamily(kind) ? kind : void 0;
|
|
82053
82408
|
}
|
|
82409
|
+
/**
|
|
82410
|
+
* Reasons, written once. Each names the SUBJECT FIELD the engine reads and
|
|
82411
|
+
* finds absent — that is what makes the exclusion checkable against the engine
|
|
82412
|
+
* rather than an opinion about tidiness.
|
|
82413
|
+
*/
|
|
82414
|
+
var NO_SENSOR_KIND = "An occupancy edge is not a sensor event: it carries no sensor kind, so this condition can never match one.";
|
|
82415
|
+
var NO_EVENT_TOKEN = "An occupancy edge carries no device event-type token — that comes from an event-emitter slice, which a count crossing has none of.";
|
|
82416
|
+
var NO_SENSOR_EDGE = "An occupancy edge is a count crossing, not a sensor reading: it has no raise or clear, so this choice could never narrow it.";
|
|
82417
|
+
var OCCUPANCY_SOURCE = "An occupancy edge is always produced by the pipeline, so any other source can never match and “pipeline” narrows nothing.";
|
|
82418
|
+
var AUDIO_SOURCE = "A confirmed sound window is always stamped as an audio subject, so any other source can never match.";
|
|
82419
|
+
var SOUND_NOT_A_PICTURE = "A sound rule fires on what the camera HEARD. Its subject carries no detection, so this condition can never match one — name the sounds in the Sound condition instead.";
|
|
82420
|
+
var SOUND_NO_CONFIDENCE = "A sound window’s evidence is a percentage of samples, not a detector score, so a confidence threshold can never be satisfied.";
|
|
82421
|
+
var SOUND_NO_GEOMETRY = "A sound has no position in the frame, so a zone or a drawn polygon can never match it.";
|
|
82422
|
+
var NC_RULE_KIND_SPECS = [
|
|
82423
|
+
{
|
|
82424
|
+
kind: "detection",
|
|
82425
|
+
label: "Conditions",
|
|
82426
|
+
excluded: { audio: "A detection rule fires on what the camera SAW. Sounds are a Sound rule of their own — adding one here turned the rule into a sound rule and dropped every detection condition." },
|
|
82427
|
+
editable: true,
|
|
82428
|
+
carriesMedia: true,
|
|
82429
|
+
carriesSubjectCrop: true
|
|
82430
|
+
},
|
|
82431
|
+
{
|
|
82432
|
+
kind: "sensor",
|
|
82433
|
+
label: "Conditions",
|
|
82434
|
+
/** `occupancy` is still offered here: authoring it converts a sensor rule into an occupancy rule. */
|
|
82435
|
+
excluded: {},
|
|
82436
|
+
editable: true,
|
|
82437
|
+
carriesMedia: true,
|
|
82438
|
+
carriesSubjectCrop: true,
|
|
82439
|
+
blurb: "A doorbell press or a linked sensor changing state. The picture comes from the camera the sensor is attributed to."
|
|
82440
|
+
},
|
|
82441
|
+
{
|
|
82442
|
+
kind: "occupancy",
|
|
82443
|
+
label: "Occupancy",
|
|
82444
|
+
discriminator: "occupancy",
|
|
82445
|
+
excluded: {
|
|
82446
|
+
sensorKinds: NO_SENSOR_KIND,
|
|
82447
|
+
eventTypeTokens: NO_EVENT_TOKEN,
|
|
82448
|
+
sensorTransition: NO_SENSOR_EDGE,
|
|
82449
|
+
source: OCCUPANCY_SOURCE
|
|
82450
|
+
},
|
|
82451
|
+
editable: true,
|
|
82452
|
+
carriesMedia: true,
|
|
82453
|
+
carriesSubjectCrop: true,
|
|
82454
|
+
blurb: "Fires when the count in a camera frame or a zone crosses your threshold and holds. Pick the camera first — the zone list is that camera’s."
|
|
82455
|
+
},
|
|
82456
|
+
{
|
|
82457
|
+
kind: "sound",
|
|
82458
|
+
label: "Sound",
|
|
82459
|
+
discriminator: "audio",
|
|
82460
|
+
excluded: {
|
|
82461
|
+
classes: SOUND_NOT_A_PICTURE,
|
|
82462
|
+
classesExclude: SOUND_NOT_A_PICTURE,
|
|
82463
|
+
minConfidence: SOUND_NO_CONFIDENCE,
|
|
82464
|
+
zones: SOUND_NO_GEOMETRY,
|
|
82465
|
+
zonesExclude: SOUND_NO_GEOMETRY,
|
|
82466
|
+
customZones: SOUND_NO_GEOMETRY,
|
|
82467
|
+
crossing: SOUND_NO_GEOMETRY,
|
|
82468
|
+
labelEquals: SOUND_NOT_A_PICTURE,
|
|
82469
|
+
identities: SOUND_NOT_A_PICTURE,
|
|
82470
|
+
identitiesExclude: SOUND_NOT_A_PICTURE,
|
|
82471
|
+
plates: SOUND_NOT_A_PICTURE,
|
|
82472
|
+
source: AUDIO_SOURCE
|
|
82473
|
+
},
|
|
82474
|
+
editable: true,
|
|
82475
|
+
carriesMedia: true,
|
|
82476
|
+
carriesSubjectCrop: false,
|
|
82477
|
+
blurb: "Fires on a confirmed sampling window of audio, never on a picture. Name the sounds and/or keep a level threshold — with neither it can never match.",
|
|
82478
|
+
mediaBlurb: "A sound owns no frame, so the picture is a photograph of the camera taken at the moment of the match — the whole scene, never a crop. The GIF and the clip are cut around the same instant, from the camera."
|
|
82479
|
+
},
|
|
82480
|
+
{
|
|
82481
|
+
kind: "device-events",
|
|
82482
|
+
label: "Device events",
|
|
82483
|
+
discriminator: "systemEvent",
|
|
82484
|
+
excluded: {},
|
|
82485
|
+
editable: true,
|
|
82486
|
+
carriesMedia: false,
|
|
82487
|
+
carriesSubjectCrop: false,
|
|
82488
|
+
blurb: "A device or its stream going away or coming back, switched off or on, a battery or consumable running low, a camera detecting nothing. There is no frame to attach."
|
|
82489
|
+
},
|
|
82490
|
+
{
|
|
82491
|
+
kind: "system",
|
|
82492
|
+
label: "System events",
|
|
82493
|
+
discriminator: "systemEvent",
|
|
82494
|
+
excluded: {},
|
|
82495
|
+
editable: true,
|
|
82496
|
+
carriesMedia: false,
|
|
82497
|
+
carriesSubjectCrop: false,
|
|
82498
|
+
blurb: "The installation itself: a node leaving, an addon crash-looping, an update available or installed, a backup or an export finishing."
|
|
82499
|
+
},
|
|
82500
|
+
{
|
|
82501
|
+
kind: "alarm",
|
|
82502
|
+
label: "Alarm",
|
|
82503
|
+
discriminator: "systemEvent",
|
|
82504
|
+
excluded: {},
|
|
82505
|
+
editable: true,
|
|
82506
|
+
carriesMedia: false,
|
|
82507
|
+
carriesSubjectCrop: false,
|
|
82508
|
+
blurb: "The alarm panel: refused, arming, armed, entry delay, triggered, re-armed, sensor bypass, disarmed.",
|
|
82509
|
+
mediaBlurb: "An alarm set off by a rule arrives with THAT rule's pictures, combined into one notification. This rule adds none of its own."
|
|
82510
|
+
},
|
|
82511
|
+
{
|
|
82512
|
+
kind: "mixed",
|
|
82513
|
+
label: "To recreate",
|
|
82514
|
+
discriminator: "systemEvent",
|
|
82515
|
+
excluded: {},
|
|
82516
|
+
editable: false,
|
|
82517
|
+
carriesMedia: false,
|
|
82518
|
+
carriesSubjectCrop: false,
|
|
82519
|
+
blurb: "This rule mixes events from more than one family (device events, system, alarm). It keeps firing as it is, but it can no longer be edited: create one rule per family, then delete this one."
|
|
82520
|
+
}
|
|
82521
|
+
];
|
|
82522
|
+
/** The spec for a kind. Total by construction — every member has an entry. */
|
|
82523
|
+
function ruleKindSpec(kind) {
|
|
82524
|
+
return NC_RULE_KIND_SPECS.find((s) => s.kind === kind) ?? NC_RULE_KIND_SPECS[0];
|
|
82525
|
+
}
|
|
82054
82526
|
/** The delivery a system rule rides — named once, compared everywhere. */
|
|
82055
82527
|
var NC_SYSTEM_DELIVERY = "system-event";
|
|
82056
82528
|
/**
|
|
@@ -82168,6 +82640,98 @@ function systemRuleKindOf(condition) {
|
|
|
82168
82640
|
return verdict.kind === "family" ? verdict.family : "mixed";
|
|
82169
82641
|
}
|
|
82170
82642
|
NC_AUDIO_DEFAULTS.hitPercent, NC_AUDIO_DEFAULTS.samplingSeconds;
|
|
82643
|
+
/** Every mode, in the order an editor offers them. */
|
|
82644
|
+
var NC_MEDIA_IMAGE_MODES = [
|
|
82645
|
+
"scene-boxes",
|
|
82646
|
+
"crop",
|
|
82647
|
+
"clean",
|
|
82648
|
+
"none"
|
|
82649
|
+
];
|
|
82650
|
+
/**
|
|
82651
|
+
* The modes a rule of this kind can honour. A kind that carries no media gets
|
|
82652
|
+
* none (its row ships text, or — an alarm — its SOURCE rule's picture); a kind
|
|
82653
|
+
* whose subject has no region of the frame (a sound) is never offered `crop`.
|
|
82654
|
+
*/
|
|
82655
|
+
function imageModesForKind(kind) {
|
|
82656
|
+
const spec = ruleKindSpec(kind);
|
|
82657
|
+
if (!spec.carriesMedia) return [];
|
|
82658
|
+
return spec.carriesSubjectCrop ? NC_MEDIA_IMAGE_MODES : NC_MEDIA_IMAGE_MODES.filter((mode) => mode !== "crop");
|
|
82659
|
+
}
|
|
82660
|
+
/**
|
|
82661
|
+
* The zone ids that FIRE a rule: its `zones` condition, or an occupancy rule's
|
|
82662
|
+
* own scoped zone. Empty when the trigger is not a zone — and then
|
|
82663
|
+
* `showTriggerZone` has nothing to draw and is refused on save.
|
|
82664
|
+
*/
|
|
82665
|
+
function ruleTriggerZoneIds(conditions) {
|
|
82666
|
+
if (conditions.zones !== void 0) return conditions.zones.ids;
|
|
82667
|
+
const zoneId = conditions.occupancy?.zoneId;
|
|
82668
|
+
return zoneId !== void 0 ? [zoneId] : [];
|
|
82669
|
+
}
|
|
82670
|
+
/**
|
|
82671
|
+
* What the legacy triple MEANT, as a mode. `zoneCrop` forced the clean
|
|
82672
|
+
* keyFrame ladder and dropped `frame`, so it is `clean` whatever else was set;
|
|
82673
|
+
* `frame` decided over `attach` when present; `keyFrame` was the clean scene;
|
|
82674
|
+
* every other still (`best`, `best-matching`, the default) was the subject.
|
|
82675
|
+
*/
|
|
82676
|
+
function legacyImageMode(media) {
|
|
82677
|
+
if (media.attach === "none") return "none";
|
|
82678
|
+
if (media.zoneCrop === true) return "clean";
|
|
82679
|
+
if (media.frame === "full") return "clean";
|
|
82680
|
+
if (media.frame === "boxed") return "scene-boxes";
|
|
82681
|
+
if (media.frame === "cropped") return "crop";
|
|
82682
|
+
if (media.attach === "keyFrame") return "clean";
|
|
82683
|
+
return "crop";
|
|
82684
|
+
}
|
|
82685
|
+
/** A mode the kind cannot honour, mapped to the nearest one it can. */
|
|
82686
|
+
function clampToKind(mode, kind) {
|
|
82687
|
+
const offered = imageModesForKind(kind);
|
|
82688
|
+
if (offered.length === 0 || offered.includes(mode)) return mode;
|
|
82689
|
+
return mode === "crop" ? "clean" : mode;
|
|
82690
|
+
}
|
|
82691
|
+
/**
|
|
82692
|
+
* The mode a rule's picture is rendered in. `image` when stored; else what the
|
|
82693
|
+
* legacy triple meant — and, for a SENSOR rule written before D897, `clean`
|
|
82694
|
+
* whatever it stored (even `attach: 'none'`), because its stored triple was
|
|
82695
|
+
* ignored and one plain snapshot always shipped (operator ruling, 2026-10-01):
|
|
82696
|
+
* the migration keeps what the rule actually DID. Clamped to what the kind can
|
|
82697
|
+
* honour.
|
|
82698
|
+
*/
|
|
82699
|
+
function resolveNcMediaImage(media, kind) {
|
|
82700
|
+
if (media.image !== void 0) return clampToKind(media.image, kind);
|
|
82701
|
+
if (kind === "sensor") return "clean";
|
|
82702
|
+
return clampToKind(legacyImageMode(media), kind);
|
|
82703
|
+
}
|
|
82704
|
+
/**
|
|
82705
|
+
* The stored shape of a media policy: `image` set, the legacy triple gone.
|
|
82706
|
+
* `showTriggerZone` survives only where it can be drawn — a zone trigger and a
|
|
82707
|
+
* mode other than `crop`/`none`; a legacy `zoneCrop` on a zone rule becomes it.
|
|
82708
|
+
* Every other field (gif, clip, rolls, speed, profile, linked cameras) is
|
|
82709
|
+
* carried through untouched. Pure; never throws.
|
|
82710
|
+
*/
|
|
82711
|
+
function normalizeNcMediaPolicy(media, rule) {
|
|
82712
|
+
const image = resolveNcMediaImage(media, ruleKindOf(rule));
|
|
82713
|
+
const { attach: _attach, frame: _frame, zoneCrop, showTriggerZone, image: _image, ...rest } = media;
|
|
82714
|
+
const drawable = (showTriggerZone === true || media.image === void 0 && zoneCrop === true) && image !== "crop" && image !== "none" && ruleTriggerZoneIds(rule.conditions).length > 0;
|
|
82715
|
+
return {
|
|
82716
|
+
...rest,
|
|
82717
|
+
image,
|
|
82718
|
+
...drawable ? { showTriggerZone: true } : {}
|
|
82719
|
+
};
|
|
82720
|
+
}
|
|
82721
|
+
/**
|
|
82722
|
+
* Why a media policy cannot be SAVED on this rule, or null. Server-side and
|
|
82723
|
+
* editor alike: `showTriggerZone` on a rule whose trigger is not a zone, and a
|
|
82724
|
+
* mode the rule's kind cannot honour.
|
|
82725
|
+
*/
|
|
82726
|
+
function ncMediaPolicyError(media, rule) {
|
|
82727
|
+
const kind = ruleKindOf(rule);
|
|
82728
|
+
if (media.image !== void 0) {
|
|
82729
|
+
const offered = imageModesForKind(kind);
|
|
82730
|
+
if (offered.length > 0 && !offered.includes(media.image)) return `media.image '${media.image}' is not available for a ${kind} rule (offered: ${offered.join(", ")})`;
|
|
82731
|
+
}
|
|
82732
|
+
if (media.showTriggerZone === true && ruleTriggerZoneIds(rule.conditions).length === 0) return "media.showTriggerZone needs a rule triggered by a zone (a zones condition or an occupancy zone)";
|
|
82733
|
+
return null;
|
|
82734
|
+
}
|
|
82171
82735
|
var WEEKDAY_TO_DAY = {
|
|
82172
82736
|
Sun: 0,
|
|
82173
82737
|
Mon: 1,
|
|
@@ -86537,6 +87101,12 @@ Object.defineProperty(exports, "RECORD_MAX_DATA_BYTES", {
|
|
|
86537
87101
|
return RECORD_MAX_DATA_BYTES;
|
|
86538
87102
|
}
|
|
86539
87103
|
});
|
|
87104
|
+
Object.defineProperty(exports, "RECORD_QUERY_MAX", {
|
|
87105
|
+
enumerable: true,
|
|
87106
|
+
get: function() {
|
|
87107
|
+
return RECORD_QUERY_MAX;
|
|
87108
|
+
}
|
|
87109
|
+
});
|
|
86540
87110
|
Object.defineProperty(exports, "RebuildObjectEmbeddingsRefusalSchema", {
|
|
86541
87111
|
enumerable: true,
|
|
86542
87112
|
get: function() {
|
|
@@ -87209,12 +87779,24 @@ Object.defineProperty(exports, "memoizePinnedFfmpeg", {
|
|
|
87209
87779
|
return memoizePinnedFfmpeg;
|
|
87210
87780
|
}
|
|
87211
87781
|
});
|
|
87782
|
+
Object.defineProperty(exports, "ncMediaPolicyError", {
|
|
87783
|
+
enumerable: true,
|
|
87784
|
+
get: function() {
|
|
87785
|
+
return ncMediaPolicyError;
|
|
87786
|
+
}
|
|
87787
|
+
});
|
|
87212
87788
|
Object.defineProperty(exports, "nodePin", {
|
|
87213
87789
|
enumerable: true,
|
|
87214
87790
|
get: function() {
|
|
87215
87791
|
return nodePin;
|
|
87216
87792
|
}
|
|
87217
87793
|
});
|
|
87794
|
+
Object.defineProperty(exports, "normalizeNcMediaPolicy", {
|
|
87795
|
+
enumerable: true,
|
|
87796
|
+
get: function() {
|
|
87797
|
+
return normalizeNcMediaPolicy;
|
|
87798
|
+
}
|
|
87799
|
+
});
|
|
87218
87800
|
Object.defineProperty(exports, "normalizeNodeId", {
|
|
87219
87801
|
enumerable: true,
|
|
87220
87802
|
get: function() {
|
|
@@ -87347,6 +87929,12 @@ Object.defineProperty(exports, "resolveModeNotifyPolicy", {
|
|
|
87347
87929
|
return resolveModeNotifyPolicy;
|
|
87348
87930
|
}
|
|
87349
87931
|
});
|
|
87932
|
+
Object.defineProperty(exports, "resolveNcMediaImage", {
|
|
87933
|
+
enumerable: true,
|
|
87934
|
+
get: function() {
|
|
87935
|
+
return resolveNcMediaImage;
|
|
87936
|
+
}
|
|
87937
|
+
});
|
|
87350
87938
|
Object.defineProperty(exports, "resolvePoolMemoryPolicy", {
|
|
87351
87939
|
enumerable: true,
|
|
87352
87940
|
get: function() {
|