@camstack/addon-pipeline 1.1.27 → 1.1.29
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/audio-analyzer/index.js +7 -6
- package/dist/audio-analyzer/index.mjs +7 -6
- package/dist/audio-codec-ffmpeg/index.js +1 -5
- package/dist/audio-codec-ffmpeg/index.mjs +1 -5
- package/dist/decoder-ffmpeg/index.js +138 -356
- package/dist/decoder-ffmpeg/index.mjs +118 -336
- package/dist/decoder-nodeav/index.js +17 -10
- package/dist/decoder-nodeav/index.mjs +17 -10
- package/dist/detection-pipeline/index.js +341 -379
- package/dist/detection-pipeline/index.mjs +341 -379
- package/dist/{dist-DAIlCdAx.js → dist-Cwc0TUQr.js} +378 -76
- package/dist/{dist-CgEP_0OL.mjs → dist-DjuGmyG9.mjs} +379 -65
- package/dist/ffmpeg-args-C5GPp8Cw.mjs +323 -0
- package/dist/ffmpeg-args-D6h1edXK.js +418 -0
- package/dist/frame-dropper-AjheBGMG.mjs +22 -0
- package/dist/frame-dropper-DKLM6pMz.js +27 -0
- package/dist/{frame-handle-plane-Dq20KtKL.mjs → frame-handle-plane-Bkxz-TTD.mjs} +13 -5
- package/dist/{frame-handle-plane-DtTRX_0n.js → frame-handle-plane-DQNCTrpC.js} +13 -5
- package/dist/{frame-ring-sink-BbzrqTWj.js → frame-ring-sink-8LLV-cvH.js} +128 -23
- package/dist/{frame-ring-sink-B_NvPTJZ.mjs → frame-ring-sink-ClEWjiRU.mjs} +117 -24
- package/dist/motion-wasm/index.js +55 -3
- package/dist/motion-wasm/index.mjs +55 -3
- package/dist/node-topology-platform-BkR_k6WT.mjs +15 -0
- package/dist/node-topology-platform-CFZ7F4xW.js +20 -0
- package/dist/pipeline-runner/index.js +50 -16
- package/dist/pipeline-runner/index.mjs +50 -16
- package/dist/recorder/index.js +36 -40
- package/dist/recorder/index.mjs +36 -40
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-5tQlh9h4.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D567z31g.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DhY3MZ2C.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-BJK0-svt.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DtoYGpTp.mjs} +1 -1
- package/dist/stream-broker/{hostInit-DyLqyJaS.mjs → hostInit-B_b3PIZB.mjs} +3 -3
- package/dist/stream-broker/index.js +198 -115
- package/dist/stream-broker/index.mjs +189 -106
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-BDLNwJ_F.js → MaskShapeCanvas-DI4BY7W2-x-DZOuQL.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CoLjNiUN.js → MotionZonesSettings-NcxxQN8r-DTeuDGCU.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-DJE3OU-q.js → PrivacyMaskSettings-APgPLF7p-CirtxO3e.js} +1 -1
- package/embed-dist/assets/index-C5UpuPr8.css +2 -0
- package/embed-dist/assets/{index-C-pL8ETk.js → index-CpUy8OIE.js} +10 -10
- package/embed-dist/index.html +2 -2
- package/package.json +1 -1
- package/python/inference_pool.py +93 -102
- package/python/test_inference_pool_device_selection.py +43 -38
- package/dist/frame-dropper-7RTo_YyG.js +0 -68
- package/dist/frame-dropper-CwkBTPGV.mjs +0 -51
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CkOPfV8r.mjs +0 -26
- package/embed-dist/assets/index-DrJ0ee3f.css +0 -2
|
@@ -4627,7 +4627,7 @@ function _instanceof(cls, params = {}) {
|
|
|
4627
4627
|
return inst;
|
|
4628
4628
|
}
|
|
4629
4629
|
//#endregion
|
|
4630
|
-
//#region ../types/dist/sleep-
|
|
4630
|
+
//#region ../types/dist/sleep-BiDFW0E7.mjs
|
|
4631
4631
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4632
4632
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4633
4633
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -5440,6 +5440,100 @@ function createDurableState(deps) {
|
|
|
5440
5440
|
};
|
|
5441
5441
|
}
|
|
5442
5442
|
/**
|
|
5443
|
+
* Per-node scoping for the shared addon-settings blob.
|
|
5444
|
+
*
|
|
5445
|
+
* An addon's settings store is hub-central (the `addon-settings` cap is
|
|
5446
|
+
* hub-routed — the hub instance answers for every node), so fields whose
|
|
5447
|
+
* value is a NODE fact (decoder backend, engine pick, probed hardware
|
|
5448
|
+
* capabilities) persist under the node-scoped key `<key>@<nodeId>` inside
|
|
5449
|
+
* the single shared blob. The SCHEMA field key stays bare: the write path
|
|
5450
|
+
* ({@link scopePatch}) maps the bare field onto the target node's scoped
|
|
5451
|
+
* key; the read/hydrate path ({@link projectStore}) maps THIS node's value
|
|
5452
|
+
* back, so UI forms and `resolveConfig` only ever see the bare key.
|
|
5453
|
+
*
|
|
5454
|
+
* Fields opt in via the `perNode: true` schema marker on `ConfigFieldBase`
|
|
5455
|
+
* (`interfaces/config-ui.ts`); `BaseAddon` derives the key set from the
|
|
5456
|
+
* schema and routes reads/writes through these helpers.
|
|
5457
|
+
*
|
|
5458
|
+
* ## No bare-key fallback — deliberate
|
|
5459
|
+
*
|
|
5460
|
+
* {@link readNodeValue} reads the node-scoped key ONLY. A node with no
|
|
5461
|
+
* scoped key resolves to `undefined` so the field's schema `default` wins —
|
|
5462
|
+
* NEVER `store[base]` and never another node's value. A bare legacy key in
|
|
5463
|
+
* the store is invisible to every node, hub included, so one node's
|
|
5464
|
+
* selection can never leak onto another. (This generalizes the
|
|
5465
|
+
* `decoder-backend-keys.ts` semantics — the no-fallback variant — over an
|
|
5466
|
+
* arbitrary set of per-node field keys.)
|
|
5467
|
+
*
|
|
5468
|
+
* Pure functions only — no I/O, no imports beyond the language. This is a
|
|
5469
|
+
* LEAF module: import it via its deep path, never from the root barrel.
|
|
5470
|
+
*/
|
|
5471
|
+
/**
|
|
5472
|
+
* Normalize a raw kernel node id to the bare node id used for scoping.
|
|
5473
|
+
* `localNodeId` can carry a `<node>/<addon>` suffix on forked child
|
|
5474
|
+
* processes; per-node settings are per-NODE, so strip the addon segment.
|
|
5475
|
+
* `undefined` / `null` / empty falls back to `'hub'`.
|
|
5476
|
+
*/
|
|
5477
|
+
function normalizeNodeId(raw) {
|
|
5478
|
+
if (raw === void 0 || raw === null || raw === "") return "hub";
|
|
5479
|
+
const slashIdx = raw.indexOf("/");
|
|
5480
|
+
if (slashIdx < 0) return raw;
|
|
5481
|
+
const bare = raw.slice(0, slashIdx);
|
|
5482
|
+
return bare === "" ? "hub" : bare;
|
|
5483
|
+
}
|
|
5484
|
+
/** The node-scoped store key for a per-node field: `<base>@<nodeId>`. */
|
|
5485
|
+
function nodeScopedKey(base, nodeId) {
|
|
5486
|
+
return `${base}@${normalizeNodeId(nodeId)}`;
|
|
5487
|
+
}
|
|
5488
|
+
/**
|
|
5489
|
+
* Read a node's value for a per-node field from the raw shared store:
|
|
5490
|
+
* the node-scoped key when present, otherwise `undefined`.
|
|
5491
|
+
* Deliberately NO bare-key fallback (see module doc) — the caller lets the
|
|
5492
|
+
* schema `default` win on `undefined`.
|
|
5493
|
+
*/
|
|
5494
|
+
function readNodeValue(store, base, nodeId) {
|
|
5495
|
+
return store[nodeScopedKey(base, nodeId)];
|
|
5496
|
+
}
|
|
5497
|
+
/**
|
|
5498
|
+
* Re-map a UI/settings patch so every bare perNode field persists under the
|
|
5499
|
+
* TARGET node's scoped key; all other keys pass through unchanged. Used on
|
|
5500
|
+
* the write path so a save for one node never clobbers another node's value
|
|
5501
|
+
* (and the bare key is never written). Returns a new object — the input
|
|
5502
|
+
* patch is not mutated.
|
|
5503
|
+
*/
|
|
5504
|
+
function scopePatch(patch, perNodeKeys, nodeId) {
|
|
5505
|
+
const out = {};
|
|
5506
|
+
for (const [key, value] of Object.entries(patch)) out[perNodeKeys.has(key) ? nodeScopedKey(key, nodeId) : key] = value;
|
|
5507
|
+
return out;
|
|
5508
|
+
}
|
|
5509
|
+
/**
|
|
5510
|
+
* Project the raw shared store onto the bare schema keys for ONE node so a
|
|
5511
|
+
* UI schema (whose field keys are bare) hydrates from that node's own
|
|
5512
|
+
* values:
|
|
5513
|
+
*
|
|
5514
|
+
* - EVERY `@`-scoped key (any node's) is dropped from the pass-through.
|
|
5515
|
+
* - Every bare perNode key is dropped from the pass-through (a stray bare
|
|
5516
|
+
* legacy key must never hydrate any node — no bare fallback).
|
|
5517
|
+
* - THIS node's effective value ({@link readNodeValue}) is then laid onto
|
|
5518
|
+
* each bare perNode key; when the node has no scoped key the bare key is
|
|
5519
|
+
* left ABSENT so the field's schema `default` wins.
|
|
5520
|
+
*
|
|
5521
|
+
* Returns a new object — the input store is not mutated.
|
|
5522
|
+
*/
|
|
5523
|
+
function projectStore(store, perNodeKeys, nodeId) {
|
|
5524
|
+
const out = {};
|
|
5525
|
+
for (const [key, value] of Object.entries(store)) {
|
|
5526
|
+
if (key.includes("@")) continue;
|
|
5527
|
+
if (perNodeKeys.has(key)) continue;
|
|
5528
|
+
out[key] = value;
|
|
5529
|
+
}
|
|
5530
|
+
for (const base of perNodeKeys) {
|
|
5531
|
+
const value = readNodeValue(store, base, nodeId);
|
|
5532
|
+
if (value !== void 0) out[base] = value;
|
|
5533
|
+
}
|
|
5534
|
+
return out;
|
|
5535
|
+
}
|
|
5536
|
+
/**
|
|
5443
5537
|
* Base class for CamStack addons. Eliminates settings boilerplate:
|
|
5444
5538
|
*
|
|
5445
5539
|
* - Typed `config` property with automatic resolution from store + defaults
|
|
@@ -5607,23 +5701,63 @@ var BaseAddon = class {
|
|
|
5607
5701
|
deviceSettingsSchema() {
|
|
5608
5702
|
return null;
|
|
5609
5703
|
}
|
|
5610
|
-
async getGlobalSettings(overlay, cap,
|
|
5704
|
+
async getGlobalSettings(overlay, cap, nodeId) {
|
|
5611
5705
|
const schema = this.globalSettingsSchema(cap);
|
|
5612
5706
|
if (!schema) return { sections: [] };
|
|
5613
|
-
const
|
|
5707
|
+
const projected = await this.resolveGlobalStore(nodeId, cap);
|
|
5614
5708
|
return hydrateSchema(schema, overlay ? {
|
|
5615
|
-
...
|
|
5709
|
+
...projected,
|
|
5616
5710
|
...overlay
|
|
5617
|
-
} :
|
|
5711
|
+
} : projected);
|
|
5712
|
+
}
|
|
5713
|
+
/**
|
|
5714
|
+
* The raw addon store PROJECTED onto the target node's bare per-node keys:
|
|
5715
|
+
* every `perNode: true` field carries THAT node's scoped value on its bare
|
|
5716
|
+
* key (absent scoped key ⇒ key absent, so the schema `default` wins — no
|
|
5717
|
+
* bare fallback), all `@`-scoped and stray bare per-node keys are dropped.
|
|
5718
|
+
* A no-op passthrough when the schema declares no `perNode` field.
|
|
5719
|
+
*
|
|
5720
|
+
* This is the sanctioned way for a `getGlobalSettings` OVERRIDE that needs
|
|
5721
|
+
* the store for custom option logic (option narrowing, value snapping) to
|
|
5722
|
+
* read it per-node — never `ctx.settings.readAddonStore()` directly.
|
|
5723
|
+
* `nodeId` omitted ⇒ the local node (node-blind injection from ctx).
|
|
5724
|
+
*/
|
|
5725
|
+
async resolveGlobalStore(nodeId, cap) {
|
|
5726
|
+
const raw = await this._ctx?.settings?.readAddonStore() ?? {};
|
|
5727
|
+
const keys = this.perNodeKeys(cap);
|
|
5728
|
+
const node = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
|
|
5729
|
+
return keys.size > 0 ? projectStore(raw, keys, node) : raw;
|
|
5618
5730
|
}
|
|
5619
|
-
async updateGlobalSettings(patch,
|
|
5620
|
-
|
|
5731
|
+
async updateGlobalSettings(patch, nodeId) {
|
|
5732
|
+
const keys = this.perNodeKeys();
|
|
5733
|
+
const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
|
|
5734
|
+
const target = normalizeNodeId(nodeId ?? this._ctx?.kernel?.localNodeId);
|
|
5735
|
+
const barePatch = patch;
|
|
5736
|
+
const scoped = keys.size > 0 ? scopePatch(barePatch, keys, target) : barePatch;
|
|
5737
|
+
await this._ctx?.settings?.writeAddonStore(scoped);
|
|
5738
|
+
if (target !== localNode) return;
|
|
5621
5739
|
await this.resolveConfig();
|
|
5622
5740
|
await this.onConfigChanged();
|
|
5623
5741
|
this.emitLifecycle(EventCategory.AddonUpdated, { level: "global" });
|
|
5624
5742
|
this.maybeAutoRestart(patch, this.globalSettingsSchema());
|
|
5625
5743
|
}
|
|
5626
5744
|
/**
|
|
5745
|
+
* The set of field keys the global settings schema declares `perNode: true`
|
|
5746
|
+
* — derived once per `cap` argument and memoized (schemas are static
|
|
5747
|
+
* declarations). Empty set ⇒ every per-node code path is bypassed and the
|
|
5748
|
+
* settings API behaves exactly like the legacy node-agnostic one.
|
|
5749
|
+
*/
|
|
5750
|
+
_perNodeKeysCache = /* @__PURE__ */ new Map();
|
|
5751
|
+
perNodeKeys(cap) {
|
|
5752
|
+
const cacheKey = cap ?? "";
|
|
5753
|
+
const cached = this._perNodeKeysCache.get(cacheKey);
|
|
5754
|
+
if (cached) return cached;
|
|
5755
|
+
const schema = this.globalSettingsSchema(cap);
|
|
5756
|
+
const keys = new Set(schema ? schema.sections.flatMap((section) => collectPerNodeFieldKeys(section.fields)) : []);
|
|
5757
|
+
this._perNodeKeysCache.set(cacheKey, keys);
|
|
5758
|
+
return keys;
|
|
5759
|
+
}
|
|
5760
|
+
/**
|
|
5627
5761
|
* If any field in `patch` is marked `requiresRestart` in `schema`,
|
|
5628
5762
|
* schedule an addon restart for the next tick. Deferred via
|
|
5629
5763
|
* `setImmediate` so the tRPC mutation that triggered the write has
|
|
@@ -5776,12 +5910,19 @@ var BaseAddon = class {
|
|
|
5776
5910
|
* The merge is shallow: each key in `defaults` is checked against the store.
|
|
5777
5911
|
* Only keys present in defaults are read — the store can contain extra keys
|
|
5778
5912
|
* (e.g. from older versions) without polluting the typed config.
|
|
5913
|
+
*
|
|
5914
|
+
* Keys the global settings schema declares `perNode: true` resolve from
|
|
5915
|
+
* THIS node's scoped key (`<key>@<localNode>`) via `readNodeValue` — never
|
|
5916
|
+
* from the bare key — so a per-node field resolves to this node's own
|
|
5917
|
+
* selection at boot (absent scoped key ⇒ the constructor default wins).
|
|
5779
5918
|
*/
|
|
5780
5919
|
async resolveConfig() {
|
|
5781
5920
|
const stored = await this.readAddonStoreWithRetry();
|
|
5921
|
+
const perNode = this.perNodeKeys();
|
|
5922
|
+
const localNode = normalizeNodeId(this._ctx?.kernel?.localNodeId);
|
|
5782
5923
|
const resolved = { ...this.defaults };
|
|
5783
5924
|
for (const key of Object.keys(this.defaults)) {
|
|
5784
|
-
const storedValue = stored[key];
|
|
5925
|
+
const storedValue = perNode.has(key) ? readNodeValue(stored, key, localNode) : stored[key];
|
|
5785
5926
|
if (storedValue !== void 0 && storedValue !== null) {
|
|
5786
5927
|
const defaultType = typeof this.defaults[key];
|
|
5787
5928
|
if (typeof storedValue === defaultType) resolved[key] = storedValue;
|
|
@@ -5865,6 +6006,27 @@ var BaseAddon = class {
|
|
|
5865
6006
|
}
|
|
5866
6007
|
};
|
|
5867
6008
|
/**
|
|
6009
|
+
* Collect the keys of every field marked `perNode: true`, recursing into
|
|
6010
|
+
* layout containers (`group` fields and `sub-tabs` tabs) the same way
|
|
6011
|
+
* `hydrateSchema` does. Valueless structural fields (separator/info/…)
|
|
6012
|
+
* don't declare `perNode` and are excluded by the `in` narrowing.
|
|
6013
|
+
*/
|
|
6014
|
+
function collectPerNodeFieldKeys(fields) {
|
|
6015
|
+
const collected = [];
|
|
6016
|
+
for (const field of fields) {
|
|
6017
|
+
if (field.type === "group") {
|
|
6018
|
+
collected.push(...collectPerNodeFieldKeys(field.fields));
|
|
6019
|
+
continue;
|
|
6020
|
+
}
|
|
6021
|
+
if (field.type === "sub-tabs") {
|
|
6022
|
+
for (const tab of field.tabs) collected.push(...collectPerNodeFieldKeys(tab.fields));
|
|
6023
|
+
continue;
|
|
6024
|
+
}
|
|
6025
|
+
if ("perNode" in field && field.perNode === true) collected.push(field.key);
|
|
6026
|
+
}
|
|
6027
|
+
return collected;
|
|
6028
|
+
}
|
|
6029
|
+
/**
|
|
5868
6030
|
* Normalize an `ICamstackAddon.initialize()` return value into the
|
|
5869
6031
|
* `AddonInitResult` envelope. Arrays are wrapped into `{ providers }`;
|
|
5870
6032
|
* envelopes pass through; void stays void.
|
|
@@ -6272,11 +6434,6 @@ var ProfileRtspEntrySchema = object({
|
|
|
6272
6434
|
function parseJsonUnknown(text) {
|
|
6273
6435
|
return JSON.parse(text);
|
|
6274
6436
|
}
|
|
6275
|
-
/** Narrow an unknown value to a plain `Record<string, unknown>` or return null. */
|
|
6276
|
-
function asJsonObject(value) {
|
|
6277
|
-
if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
|
|
6278
|
-
return { ...value };
|
|
6279
|
-
}
|
|
6280
6437
|
var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
6281
6438
|
DeviceType["Camera"] = "camera";
|
|
6282
6439
|
DeviceType["Hub"] = "hub";
|
|
@@ -6361,6 +6518,13 @@ var DeviceType = /* @__PURE__ */ function(DeviceType) {
|
|
|
6361
6518
|
/** Single still-image entity (HA `image.*`). Read-only display of an
|
|
6362
6519
|
* `entity_picture` signed URL the browser loads directly. `image` cap. */
|
|
6363
6520
|
DeviceType["Image"] = "image";
|
|
6521
|
+
/** Smart pet feeder — cloud-connected food dispenser with a bowl food
|
|
6522
|
+
* level, battery, desiccant life, feeding state and manual-feed /
|
|
6523
|
+
* call-pet / maintenance actions. Installed with the `pet-feeder` cap;
|
|
6524
|
+
* dual-hopper models (D4S/D4SH) expose per-hopper portions. Sources:
|
|
6525
|
+
* native PetKit (`nodepetkit` `FeederDevice`), reusable by other feeder
|
|
6526
|
+
* integrations sharing the same food/desiccant/hopper surface. */
|
|
6527
|
+
DeviceType["PetFeeder"] = "pet-feeder";
|
|
6364
6528
|
return DeviceType;
|
|
6365
6529
|
}({});
|
|
6366
6530
|
var DeviceFeature = /* @__PURE__ */ function(DeviceFeature) {
|
|
@@ -10840,7 +11004,8 @@ var motionDetectionCapability = {
|
|
|
10840
11004
|
methods: {
|
|
10841
11005
|
analyze: method(object({
|
|
10842
11006
|
deviceId: number(),
|
|
10843
|
-
frame: FrameInputSchema
|
|
11007
|
+
frame: FrameInputSchema.optional(),
|
|
11008
|
+
frameHandle: FrameHandleSchema.optional()
|
|
10844
11009
|
}), MotionAnalysisResultSchema, { kind: "mutation" }),
|
|
10845
11010
|
removeCamera: method(object({ deviceId: number() }), _void(), { kind: "mutation" }),
|
|
10846
11011
|
reset: method(_void(), _void(), { kind: "mutation" })
|
|
@@ -11152,11 +11317,20 @@ var pipelineExecutorCapability = {
|
|
|
11152
11317
|
* legacy call shape used by existing benchmark code; once all
|
|
11153
11318
|
* callers pass it explicitly we make it required.
|
|
11154
11319
|
*
|
|
11155
|
-
* Exactly one of `frame`, `
|
|
11156
|
-
* provided:
|
|
11320
|
+
* Exactly one of `frame`, `frameHandle`, `imageBase64`,
|
|
11321
|
+
* `referenceImage` must be provided:
|
|
11157
11322
|
* - `frame`: runtime dispatch path (runner → decoded broker frame).
|
|
11158
11323
|
* Carries the raw buffer, dimensions, and format; the executor
|
|
11159
11324
|
* uses it directly without base64 round-tripping.
|
|
11325
|
+
* - `frameHandle` (CB5): a zero-pixel shm `FrameHandle` for the SAME
|
|
11326
|
+
* decoded frame. Both runner and executor are hub-local processes
|
|
11327
|
+
* sharing `/dev/shm`, so the executor maps the named segment and
|
|
11328
|
+
* reads the pixels back zero-copy — eliminating the ~1.2MB
|
|
11329
|
+
* re-serialisation over UDS/MsgPack the `frame` path pays per call.
|
|
11330
|
+
* High-risk: the FrameRing is a latest-wins seqlock with no
|
|
11331
|
+
* refcount, so a recycled slot yields a null read; the executor
|
|
11332
|
+
* then degrades to an empty result and the runner ships pixels via
|
|
11333
|
+
* `frame` as the fallback (queue-depth gated on the runner side).
|
|
11160
11334
|
* - `imageBase64`: one-shot test path (benchmark ImageTab).
|
|
11161
11335
|
* - `referenceImage`: named file from the reference-image store.
|
|
11162
11336
|
*/
|
|
@@ -11164,6 +11338,12 @@ var pipelineExecutorCapability = {
|
|
|
11164
11338
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
11165
11339
|
steps: array(PipelineStepInputSchema).min(1),
|
|
11166
11340
|
frame: FrameInputSchema.optional(),
|
|
11341
|
+
/**
|
|
11342
|
+
* CB5 shm passthrough — a `FrameHandle` naming the same ring slot
|
|
11343
|
+
* the decoded pixels live in. One more member of the one-of
|
|
11344
|
+
* frame/frameHandle/image/imageBase64/referenceImage group.
|
|
11345
|
+
*/
|
|
11346
|
+
frameHandle: FrameHandleSchema.optional(),
|
|
11167
11347
|
imageBase64: string().optional(),
|
|
11168
11348
|
/**
|
|
11169
11349
|
* Binary JPEG bytes — preferred over `imageBase64` on internal
|
|
@@ -11972,6 +12152,113 @@ object({
|
|
|
11972
12152
|
lastFetchedAt: number()
|
|
11973
12153
|
});
|
|
11974
12154
|
DeviceType.Sensor;
|
|
12155
|
+
/**
|
|
12156
|
+
* Feeder connectivity / power status — mirrors the HA petkit device-status
|
|
12157
|
+
* enum: `normal` (online, mains), `offline` (not reaching PetKit cloud),
|
|
12158
|
+
* `on_batteries` (running on battery backup). `null` until first reported.
|
|
12159
|
+
*/
|
|
12160
|
+
var PetFeederDeviceStatusSchema = _enum([
|
|
12161
|
+
"normal",
|
|
12162
|
+
"offline",
|
|
12163
|
+
"on_batteries"
|
|
12164
|
+
]);
|
|
12165
|
+
var gramsPortion = number().int().min(4).max(200);
|
|
12166
|
+
object({
|
|
12167
|
+
/** Food currently in the bowl (grams). Null when the device has not
|
|
12168
|
+
* reported a reading yet. On dual-hopper models this is the combined
|
|
12169
|
+
* bowl reading; per-hopper levels live in `food1`/`food2`. */
|
|
12170
|
+
foodLevel: number().nullable(),
|
|
12171
|
+
/** Hopper-1 food level (grams) on dual-hopper feeders; null on
|
|
12172
|
+
* single-hopper models. */
|
|
12173
|
+
food1: number().nullable(),
|
|
12174
|
+
/** Hopper-2 food level (grams) on dual-hopper feeders; null on
|
|
12175
|
+
* single-hopper models. */
|
|
12176
|
+
food2: number().nullable(),
|
|
12177
|
+
/** Derived low-food flag — mirrors the HA `food_level` binary_sensor
|
|
12178
|
+
* (`device_class: problem`, on = low). True when the bowl is empty /
|
|
12179
|
+
* below the feeder's low threshold. */
|
|
12180
|
+
lowFood: boolean(),
|
|
12181
|
+
/** Battery charge 0..100 (%). Null on mains-powered models or when the
|
|
12182
|
+
* device has no battery reading. */
|
|
12183
|
+
batteryPower: number().min(0).max(100).nullable(),
|
|
12184
|
+
/** Days of desiccant life remaining. Null when the model has no
|
|
12185
|
+
* desiccant sensor. */
|
|
12186
|
+
desiccantLeftDays: number().nullable(),
|
|
12187
|
+
/** True while a feed is in progress. */
|
|
12188
|
+
feeding: boolean(),
|
|
12189
|
+
/** Decoded connectivity / power status (HA petkit device-status enum).
|
|
12190
|
+
* Null until the device has reported a status. */
|
|
12191
|
+
status: PetFeederDeviceStatusSchema.nullable(),
|
|
12192
|
+
/** Decoded human-readable fault message. Null (or the device's `no_error`
|
|
12193
|
+
* sentinel) means healthy; a non-null string is an active fault. Pairs
|
|
12194
|
+
* with `errorCode` for consumers that want the raw integer. */
|
|
12195
|
+
error: string().nullable(),
|
|
12196
|
+
/** Raw device error code (0 / null = no error). */
|
|
12197
|
+
errorCode: number().nullable(),
|
|
12198
|
+
/** True for D4S/D4SH dual-hopper hardware — gates the per-hopper UI. */
|
|
12199
|
+
isDualHopper: boolean(),
|
|
12200
|
+
/** Child-lock (manual-lock) setting — buttons on the unit are disabled. */
|
|
12201
|
+
childLock: boolean(),
|
|
12202
|
+
/** Front indicator-light setting. */
|
|
12203
|
+
indicatorLight: boolean(),
|
|
12204
|
+
/** Play a chime when dispensing. */
|
|
12205
|
+
feedSound: boolean(),
|
|
12206
|
+
/** Speaker / prompt volume level (device-scaled integer). */
|
|
12207
|
+
volume: number(),
|
|
12208
|
+
/** Ms epoch when the slice was last refreshed from the cloud. */
|
|
12209
|
+
lastFetchedAt: number()
|
|
12210
|
+
});
|
|
12211
|
+
DeviceType.PetFeeder, method(object({
|
|
12212
|
+
deviceId: number().int().nonnegative(),
|
|
12213
|
+
grams: gramsPortion.optional(),
|
|
12214
|
+
hopper1: gramsPortion.optional(),
|
|
12215
|
+
hopper2: gramsPortion.optional()
|
|
12216
|
+
}), _void(), {
|
|
12217
|
+
kind: "mutation",
|
|
12218
|
+
auth: "admin"
|
|
12219
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
12220
|
+
kind: "mutation",
|
|
12221
|
+
auth: "admin"
|
|
12222
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
12223
|
+
kind: "mutation",
|
|
12224
|
+
auth: "admin"
|
|
12225
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
12226
|
+
kind: "mutation",
|
|
12227
|
+
auth: "admin"
|
|
12228
|
+
}), method(object({ deviceId: number().int().nonnegative() }), _void(), {
|
|
12229
|
+
kind: "mutation",
|
|
12230
|
+
auth: "admin"
|
|
12231
|
+
}), method(object({
|
|
12232
|
+
deviceId: number().int().nonnegative(),
|
|
12233
|
+
soundId: number().int().nonnegative()
|
|
12234
|
+
}), _void(), {
|
|
12235
|
+
kind: "mutation",
|
|
12236
|
+
auth: "admin"
|
|
12237
|
+
}), method(object({
|
|
12238
|
+
deviceId: number().int().nonnegative(),
|
|
12239
|
+
on: boolean()
|
|
12240
|
+
}), _void(), {
|
|
12241
|
+
kind: "mutation",
|
|
12242
|
+
auth: "admin"
|
|
12243
|
+
}), method(object({
|
|
12244
|
+
deviceId: number().int().nonnegative(),
|
|
12245
|
+
on: boolean()
|
|
12246
|
+
}), _void(), {
|
|
12247
|
+
kind: "mutation",
|
|
12248
|
+
auth: "admin"
|
|
12249
|
+
}), method(object({
|
|
12250
|
+
deviceId: number().int().nonnegative(),
|
|
12251
|
+
on: boolean()
|
|
12252
|
+
}), _void(), {
|
|
12253
|
+
kind: "mutation",
|
|
12254
|
+
auth: "admin"
|
|
12255
|
+
}), method(object({
|
|
12256
|
+
deviceId: number().int().nonnegative(),
|
|
12257
|
+
level: number().int().nonnegative()
|
|
12258
|
+
}), _void(), {
|
|
12259
|
+
kind: "mutation",
|
|
12260
|
+
auth: "admin"
|
|
12261
|
+
});
|
|
11975
12262
|
object({
|
|
11976
12263
|
/** Instantaneous power draw in watts. */
|
|
11977
12264
|
watts: number().optional(),
|
|
@@ -14087,11 +14374,13 @@ var decoderCapability = {
|
|
|
14087
14374
|
}), _void()),
|
|
14088
14375
|
pullFrames: method(object({
|
|
14089
14376
|
sessionId: string(),
|
|
14090
|
-
maxCount: number().default(1)
|
|
14377
|
+
maxCount: number().default(1),
|
|
14378
|
+
waitMs: number().optional()
|
|
14091
14379
|
}), array(DecodedFrameSchema)),
|
|
14092
14380
|
pullHandles: method(object({
|
|
14093
14381
|
sessionId: string(),
|
|
14094
|
-
maxCount: number().default(1)
|
|
14382
|
+
maxCount: number().default(1),
|
|
14383
|
+
waitMs: number().optional()
|
|
14095
14384
|
}), array(FrameHandleSchema)),
|
|
14096
14385
|
getFrame: method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()),
|
|
14097
14386
|
getShmStats: method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()),
|
|
@@ -16114,7 +16403,10 @@ var AgentLoadSummarySchema = object({
|
|
|
16114
16403
|
online: boolean(),
|
|
16115
16404
|
load: RunnerLocalLoadSchema,
|
|
16116
16405
|
/** Computed score used by the L2 capacity balancer (lower = less loaded). */
|
|
16117
|
-
score: number()
|
|
16406
|
+
score: number(),
|
|
16407
|
+
/** This node's decode hwaccel backend (per-node `probedBestHwaccel`), or null
|
|
16408
|
+
* when not yet probed — for the cluster Pipeline table UI (P0.2). */
|
|
16409
|
+
decodeHwaccel: string().nullable()
|
|
16118
16410
|
});
|
|
16119
16411
|
/**
|
|
16120
16412
|
* Aggregate metrics across the whole detection cluster. Replaces the legacy
|
|
@@ -18727,7 +19019,10 @@ var HwAccelBackendInputSchema = _enum([
|
|
|
18727
19019
|
"webgpu",
|
|
18728
19020
|
"none"
|
|
18729
19021
|
]).nullable().optional();
|
|
18730
|
-
var HwAccelResolutionSchema = object({
|
|
19022
|
+
var HwAccelResolutionSchema = object({
|
|
19023
|
+
preferred: array(string()).readonly(),
|
|
19024
|
+
rationale: string()
|
|
19025
|
+
});
|
|
18731
19026
|
var HardwareEncoderIdSchema = _enum([
|
|
18732
19027
|
"h264_videotoolbox",
|
|
18733
19028
|
"hevc_videotoolbox",
|
|
@@ -18742,7 +19037,7 @@ var HardwareEncoderIdSchema = _enum([
|
|
|
18742
19037
|
"libx264",
|
|
18743
19038
|
"libx265"
|
|
18744
19039
|
]);
|
|
18745
|
-
|
|
19040
|
+
object({
|
|
18746
19041
|
encoders: array(object({
|
|
18747
19042
|
encoder: HardwareEncoderIdSchema,
|
|
18748
19043
|
codec: _enum(["H264", "H265"]),
|
|
@@ -18761,15 +19056,7 @@ var HardwareEncodersSchema = object({
|
|
|
18761
19056
|
defaultH265: HardwareEncoderIdSchema,
|
|
18762
19057
|
probedAt: number()
|
|
18763
19058
|
});
|
|
18764
|
-
|
|
18765
|
-
* Decode-side companion to {@link HardwareEncodersSchema}: the `-hwaccel`
|
|
18766
|
-
* methods the configured ffmpeg binary actually supports (parsed from
|
|
18767
|
-
* `ffmpeg -hwaccels`). Used to gate decode-hwaccel attempts so the transcode
|
|
18768
|
-
* egress never spends a spawn on a backend this build cannot offer. Per-stream
|
|
18769
|
-
* decode fragility (e.g. VideoToolbox HEVC) is still handled by the egress's
|
|
18770
|
-
* software fallback — this only filters out wholly-unsupported backends.
|
|
18771
|
-
*/
|
|
18772
|
-
var HardwareDecodeAccelsSchema = object({
|
|
19059
|
+
object({
|
|
18773
19060
|
methods: array(string()).readonly(),
|
|
18774
19061
|
probedAt: number()
|
|
18775
19062
|
});
|
|
@@ -18832,16 +19119,7 @@ var ResolvedInferenceConfigSchema = object({
|
|
|
18832
19119
|
format: ModelFormatSchema,
|
|
18833
19120
|
reason: string()
|
|
18834
19121
|
});
|
|
18835
|
-
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({
|
|
18836
|
-
prefer: HwAccelBackendInputSchema,
|
|
18837
|
-
nodeId: string().optional()
|
|
18838
|
-
}), HwAccelResolutionSchema), method(_void(), HardwareEncodersSchema), method(_void(), HardwareEncodersSchema, {
|
|
18839
|
-
kind: "mutation",
|
|
18840
|
-
auth: "admin"
|
|
18841
|
-
}), method(_void(), HardwareDecodeAccelsSchema), method(_void(), HardwareDecodeAccelsSchema, {
|
|
18842
|
-
kind: "mutation",
|
|
18843
|
-
auth: "admin"
|
|
18844
|
-
});
|
|
19122
|
+
method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema), method(object({ requirements: array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema), method(object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema);
|
|
18845
19123
|
var PtzPresetSchema = object({
|
|
18846
19124
|
id: string(),
|
|
18847
19125
|
name: string()
|
|
@@ -21833,6 +22111,66 @@ Object.freeze({
|
|
|
21833
22111
|
addonId: null,
|
|
21834
22112
|
access: "create"
|
|
21835
22113
|
},
|
|
22114
|
+
"petFeeder.callPet": {
|
|
22115
|
+
capName: "pet-feeder",
|
|
22116
|
+
capScope: "device",
|
|
22117
|
+
addonId: null,
|
|
22118
|
+
access: "create"
|
|
22119
|
+
},
|
|
22120
|
+
"petFeeder.cancelFeed": {
|
|
22121
|
+
capName: "pet-feeder",
|
|
22122
|
+
capScope: "device",
|
|
22123
|
+
addonId: null,
|
|
22124
|
+
access: "create"
|
|
22125
|
+
},
|
|
22126
|
+
"petFeeder.feed": {
|
|
22127
|
+
capName: "pet-feeder",
|
|
22128
|
+
capScope: "device",
|
|
22129
|
+
addonId: null,
|
|
22130
|
+
access: "create"
|
|
22131
|
+
},
|
|
22132
|
+
"petFeeder.markFoodReplenished": {
|
|
22133
|
+
capName: "pet-feeder",
|
|
22134
|
+
capScope: "device",
|
|
22135
|
+
addonId: null,
|
|
22136
|
+
access: "create"
|
|
22137
|
+
},
|
|
22138
|
+
"petFeeder.playSound": {
|
|
22139
|
+
capName: "pet-feeder",
|
|
22140
|
+
capScope: "device",
|
|
22141
|
+
addonId: null,
|
|
22142
|
+
access: "create"
|
|
22143
|
+
},
|
|
22144
|
+
"petFeeder.resetDesiccant": {
|
|
22145
|
+
capName: "pet-feeder",
|
|
22146
|
+
capScope: "device",
|
|
22147
|
+
addonId: null,
|
|
22148
|
+
access: "delete"
|
|
22149
|
+
},
|
|
22150
|
+
"petFeeder.setChildLock": {
|
|
22151
|
+
capName: "pet-feeder",
|
|
22152
|
+
capScope: "device",
|
|
22153
|
+
addonId: null,
|
|
22154
|
+
access: "create"
|
|
22155
|
+
},
|
|
22156
|
+
"petFeeder.setFeedSound": {
|
|
22157
|
+
capName: "pet-feeder",
|
|
22158
|
+
capScope: "device",
|
|
22159
|
+
addonId: null,
|
|
22160
|
+
access: "create"
|
|
22161
|
+
},
|
|
22162
|
+
"petFeeder.setIndicatorLight": {
|
|
22163
|
+
capName: "pet-feeder",
|
|
22164
|
+
capScope: "device",
|
|
22165
|
+
addonId: null,
|
|
22166
|
+
access: "create"
|
|
22167
|
+
},
|
|
22168
|
+
"petFeeder.setVolume": {
|
|
22169
|
+
capName: "pet-feeder",
|
|
22170
|
+
capScope: "device",
|
|
22171
|
+
addonId: null,
|
|
22172
|
+
access: "create"
|
|
22173
|
+
},
|
|
21836
22174
|
"pipelineAnalytics.clearTracks": {
|
|
21837
22175
|
capName: "pipeline-analytics",
|
|
21838
22176
|
capScope: "device",
|
|
@@ -22439,30 +22777,6 @@ Object.freeze({
|
|
|
22439
22777
|
addonId: null,
|
|
22440
22778
|
access: "view"
|
|
22441
22779
|
},
|
|
22442
|
-
"platformProbe.getHardwareDecodeAccels": {
|
|
22443
|
-
capName: "platform-probe",
|
|
22444
|
-
capScope: "system",
|
|
22445
|
-
addonId: null,
|
|
22446
|
-
access: "view"
|
|
22447
|
-
},
|
|
22448
|
-
"platformProbe.getHardwareEncoders": {
|
|
22449
|
-
capName: "platform-probe",
|
|
22450
|
-
capScope: "system",
|
|
22451
|
-
addonId: null,
|
|
22452
|
-
access: "view"
|
|
22453
|
-
},
|
|
22454
|
-
"platformProbe.refreshHardwareDecodeAccels": {
|
|
22455
|
-
capName: "platform-probe",
|
|
22456
|
-
capScope: "system",
|
|
22457
|
-
addonId: null,
|
|
22458
|
-
access: "create"
|
|
22459
|
-
},
|
|
22460
|
-
"platformProbe.refreshHardwareEncoders": {
|
|
22461
|
-
capName: "platform-probe",
|
|
22462
|
-
capScope: "system",
|
|
22463
|
-
addonId: null,
|
|
22464
|
-
access: "create"
|
|
22465
|
-
},
|
|
22466
22780
|
"platformProbe.resolveHwAccel": {
|
|
22467
22781
|
capName: "platform-probe",
|
|
22468
22782
|
capScope: "system",
|
|
@@ -24113,12 +24427,6 @@ Object.defineProperty(exports, "array", {
|
|
|
24113
24427
|
return array;
|
|
24114
24428
|
}
|
|
24115
24429
|
});
|
|
24116
|
-
Object.defineProperty(exports, "asJsonObject", {
|
|
24117
|
-
enumerable: true,
|
|
24118
|
-
get: function() {
|
|
24119
|
-
return asJsonObject;
|
|
24120
|
-
}
|
|
24121
|
-
});
|
|
24122
24430
|
Object.defineProperty(exports, "audioAnalysisCapability", {
|
|
24123
24431
|
enumerable: true,
|
|
24124
24432
|
get: function() {
|
|
@@ -24149,12 +24457,6 @@ Object.defineProperty(exports, "cameraStreamsCapability", {
|
|
|
24149
24457
|
return cameraStreamsCapability;
|
|
24150
24458
|
}
|
|
24151
24459
|
});
|
|
24152
|
-
Object.defineProperty(exports, "createDurableState", {
|
|
24153
|
-
enumerable: true,
|
|
24154
|
-
get: function() {
|
|
24155
|
-
return createDurableState;
|
|
24156
|
-
}
|
|
24157
|
-
});
|
|
24158
24460
|
Object.defineProperty(exports, "createEvent", {
|
|
24159
24461
|
enumerable: true,
|
|
24160
24462
|
get: function() {
|