@camstack/types 1.2.399 → 1.2.401

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/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-CD18m9HF.js");
2
+ const require_sleep = require("./sleep-DVovpDRU.js");
3
3
  const require_event_category = require("./event-category-7AwNbPjm.js");
4
4
  const require_composition = require("./composition-eoYYVfOp.js");
5
5
  const require_node_color = require("./node-color.js");
@@ -8450,7 +8450,11 @@ var ConfigSectionWithValuesSchema = zod.z.object({
8450
8450
  zod.z.literal(4)
8451
8451
  ]).optional(),
8452
8452
  tab: zod.z.string().optional(),
8453
- location: zod.z.enum(["settings", "top-tab"]).optional(),
8453
+ location: zod.z.enum([
8454
+ "settings",
8455
+ "top-tab",
8456
+ "hero"
8457
+ ]).optional(),
8454
8458
  order: zod.z.number().optional(),
8455
8459
  fields: zod.z.array(zod.z.any())
8456
8460
  });
@@ -15114,6 +15118,56 @@ var TierStatusSchema = zod.z.object({
15114
15118
  countedAt: zod.z.number().nullable()
15115
15119
  });
15116
15120
  /** Operator/diagnostic view: rows per tier, last runs, refusals and drops since boot. */
15121
+ /**
15122
+ * Why a series is orphan. `device-gone`: its device is absent from the
15123
+ * successful device listings (the departure clock). `undeclared`: its `cap:`
15124
+ * key is declared by no capability any more (a field a cap removed).
15125
+ */
15126
+ var DeviceHistoryOrphanReasonSchema = zod.z.enum(["device-gone", "undeclared"]);
15127
+ /** Rows held per stored tier. */
15128
+ var TierRowsSchema = zod.z.object({
15129
+ raw: zod.z.number().int(),
15130
+ "5m": zod.z.number().int(),
15131
+ "1h": zod.z.number().int(),
15132
+ "1d": zod.z.number().int()
15133
+ });
15134
+ var OrphanSeriesSchema = zod.z.object({
15135
+ seriesId: zod.z.number().int(),
15136
+ deviceId: zod.z.number().int(),
15137
+ key: zod.z.string(),
15138
+ scope: zod.z.string(),
15139
+ /** The metric's display name; `null` when its metric row is gone too. */
15140
+ displayName: zod.z.string().nullable(),
15141
+ reason: DeviceHistoryOrphanReasonSchema,
15142
+ /** `device-gone`: since when the device has been absent; `null` otherwise. */
15143
+ missingSince: zod.z.number().nullable(),
15144
+ firstTs: zod.z.number(),
15145
+ lastTs: zod.z.number(),
15146
+ rows: TierRowsSchema
15147
+ });
15148
+ /** At most this many orphans are listed (with their row counts) per call. */
15149
+ var DEVICE_HISTORY_ORPHAN_LIST_MAX = 200;
15150
+ /** At most this many series are deleted per call. */
15151
+ var DEVICE_HISTORY_ORPHAN_DELETE_MAX = 50;
15152
+ var DeviceHistoryOrphanDeleteRefusalSchema = zod.z.enum([
15153
+ "not-found",
15154
+ "not-orphan",
15155
+ "failed"
15156
+ ]);
15157
+ var OrphanDeleteEntrySchema = zod.z.discriminatedUnion("ok", [zod.z.object({
15158
+ seriesId: zod.z.number().int(),
15159
+ ok: zod.z.literal(true),
15160
+ deleted: TierRowsSchema
15161
+ }), zod.z.object({
15162
+ seriesId: zod.z.number().int(),
15163
+ ok: zod.z.literal(false),
15164
+ reason: DeviceHistoryOrphanDeleteRefusalSchema
15165
+ })]);
15166
+ var OrphanListSchema = zod.z.object({
15167
+ series: zod.z.array(OrphanSeriesSchema).readonly(),
15168
+ /** More orphans exist than {@link DEVICE_HISTORY_ORPHAN_LIST_MAX}. */
15169
+ truncated: zod.z.boolean()
15170
+ });
15117
15171
  var DeviceHistoryStatusSchema = zod.z.object({
15118
15172
  startedAt: zod.z.number(),
15119
15173
  /** The store is declared, series loaded and the first reconcile has answered. */
@@ -15255,7 +15309,24 @@ var deviceHistoryCapability = {
15255
15309
  kind: "mutation",
15256
15310
  auth: "admin"
15257
15311
  }),
15258
- getStatus: require_sleep.method(zod.z.object({}), DeviceHistoryStatusSchema, { auth: "admin" })
15312
+ getStatus: require_sleep.method(zod.z.object({}), DeviceHistoryStatusSchema, { auth: "admin" }),
15313
+ /**
15314
+ * Device series no longer linked to a device (D917): the device is absent
15315
+ * from the listings, or the key is declared by no capability. REPORTED,
15316
+ * never purged by this judgement; each entry counts its rows per tier
15317
+ * (a primary-key range per series). Ordered by device, key, scope.
15318
+ */
15319
+ listOrphanSeries: require_sleep.method(zod.z.object({}), OrphanListSchema, { auth: "admin" }),
15320
+ /**
15321
+ * Delete orphan series by id. Each id is re-judged NOW: a series that is
15322
+ * not orphan (its device came back) is refused `not-orphan`, an unknown id
15323
+ * `not-found`. Deletes tier by tier in the retention slices, then the
15324
+ * series row; one entry per id, in order.
15325
+ */
15326
+ deleteOrphanSeries: require_sleep.method(zod.z.object({ seriesIds: zod.z.array(zod.z.number().int()).min(1).max(50) }), zod.z.object({ results: zod.z.array(OrphanDeleteEntrySchema).readonly() }), {
15327
+ kind: "mutation",
15328
+ auth: "admin"
15329
+ })
15259
15330
  }
15260
15331
  };
15261
15332
  //#endregion
@@ -61209,17 +61280,88 @@ var connectivityCapability = {
61209
61280
  //#endregion
61210
61281
  //#region src/capabilities/consumables.cap.ts
61211
61282
  /**
61212
- * Generic device-consumables capability — surfaces a device's
61213
- * maintenance items (vacuum filters/brushes, replaceable cartridges,
61214
- * descaling cycles, …) with their remaining life and an optional
61215
- * "Replaced" reset action. Device-agnostic: any provider that knows its
61216
- * device tracks consumables can register it; the cap declares no
61217
- * vocabulary of its own — the provider names each item verbatim.
61283
+ * Generic device-consumables capability — the ONE place a device reports what
61284
+ * it uses up or fills: wear parts (vacuum filters/brushes, cartridges,
61285
+ * descaling cycles), supplies it draws from (a vacuum's clean-water tank and
61286
+ * detergent, a dishwasher's salt and rinse aid) and waste it collects (a dirty
61287
+ * water tank, a dust bin). Each item carries its remaining life or fill and an
61288
+ * optional "Replaced" reset action. Device-agnostic: any provider that knows
61289
+ * its device tracks consumables registers it; the provider names each item
61290
+ * verbatim and says which `kind` it is.
61291
+ *
61292
+ * The admin UI renders it as ONE collapsible section directly under the
61293
+ * device page's hero card (`placement: 'hero'`), for every device bound to
61294
+ * this cap — never drawn by a device type's hero card itself (D915).
61218
61295
  *
61219
61296
  * Like `childLayout`, the cap is INERT until a provider sets items: no
61220
61297
  * provider populates it by guessing (no HA inference). The UI renders a
61221
61298
  * "No consumables reported" placeholder when `items` is empty.
61222
61299
  */
61300
+ /**
61301
+ * What an item IS, which decides which direction is bad:
61302
+ * - `wear` — a part that wears out (a brush, a filter); low life is bad.
61303
+ * - `supply` — something the device draws from (clean water, detergent,
61304
+ * salt, rinse aid); low or empty is bad.
61305
+ * - `waste` — something the device fills (dirty water, a dust bin); full is
61306
+ * bad.
61307
+ * Absent = `wear`.
61308
+ */
61309
+ var ConsumableKindSchema = zod.z.enum([
61310
+ "wear",
61311
+ "supply",
61312
+ "waste"
61313
+ ]);
61314
+ /**
61315
+ * What an item LOOKS like, which decides how a client draws it — independent
61316
+ * of `kind`, which decides which direction is bad:
61317
+ * - `part` — a part that wears (a brush, a filter, a mop pad): a wear bar,
61318
+ * remaining time and a reset.
61319
+ * - `tank` — a container of liquid (clean water, dirty water): a fill gauge.
61320
+ * - `product` — something bought and refilled (detergent, salt, rinse aid):
61321
+ * a stepped level and "refill".
61322
+ * - `bin` — a container that collects waste (a dust bin): a fill gauge
61323
+ * that warns when full.
61324
+ * Absent = derived from the kind ({@link consumableFormOf}).
61325
+ */
61326
+ var ConsumableFormSchema = zod.z.enum([
61327
+ "part",
61328
+ "tank",
61329
+ "product",
61330
+ "bin"
61331
+ ]);
61332
+ /** The provider's own discrete verdict on an item. */
61333
+ var ConsumableStatusSchema = zod.z.enum([
61334
+ "ok",
61335
+ "low",
61336
+ "empty",
61337
+ "full",
61338
+ "replace"
61339
+ ]);
61340
+ /**
61341
+ * The level vocabulary every client draws a consumable in (badge tone, bar
61342
+ * colour): derived from an item by its kind, level and status. `null` beside
61343
+ * it means unknown (D393).
61344
+ */
61345
+ var ConsumableLevelSchema = zod.z.enum([
61346
+ "ok",
61347
+ "low",
61348
+ "empty",
61349
+ "full"
61350
+ ]);
61351
+ /** The kind of an item, with the documented default for an absent one. */
61352
+ function consumableKindOf(item) {
61353
+ return item.kind ?? "wear";
61354
+ }
61355
+ /** The kind's default form: wear → part, waste → bin, supply → product. */
61356
+ var FORM_OF_KIND = {
61357
+ wear: "part",
61358
+ waste: "bin",
61359
+ supply: "product"
61360
+ };
61361
+ /** The form of an item: its own when the provider names one, else its kind's default. */
61362
+ function consumableFormOf(item) {
61363
+ return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
61364
+ }
61223
61365
  /** Units a remaining-life counter is reported in. Closed: the panel renders
61224
61366
  * each. */
61225
61367
  var ConsumableRemainingUnitSchema = zod.z.enum([
@@ -61234,18 +61376,23 @@ var ConsumableRemainingSchema = zod.z.object({
61234
61376
  unit: ConsumableRemainingUnitSchema
61235
61377
  });
61236
61378
  /** A single consumable item. Either a continuous `level` (remaining
61237
- * life %) or a discrete `status` may be known — both may be null when a
61238
- * provider only knows the item exists. `level` and `status` are not
61239
- * mutually exclusive; a provider may report both. */
61379
+ * life %, or fill % for a `supply` / `waste` item) or a discrete `status`
61380
+ * may be known — both may be null when a provider only knows the item
61381
+ * exists. `level` and `status` are not mutually exclusive; a provider may
61382
+ * report both. */
61240
61383
  var ConsumableItemSchema = zod.z.object({
61241
61384
  /** Stable id, e.g. 'main-brush'. */
61242
61385
  key: zod.z.string().min(1),
61243
61386
  /** Display name. */
61244
61387
  label: zod.z.string().min(1),
61245
- /** Remaining life % when known (0..100). */
61388
+ /** Remaining life % (`wear`) or fill % (`supply`, `waste`) when known (0..100). */
61246
61389
  level: zod.z.number().min(0).max(100).nullable(),
61247
- /** Discrete state when known (binary mode). */
61248
- status: zod.z.enum(["ok", "replace"]).nullable(),
61390
+ /** The provider's discrete verdict when known (binary mode). */
61391
+ status: ConsumableStatusSchema.nullable(),
61392
+ /** What the item is — decides whether low or full is bad. Absent = `wear`. */
61393
+ kind: ConsumableKindSchema.optional(),
61394
+ /** How the item is drawn (part, tank, product, bin). Absent = derived from `kind`. */
61395
+ form: ConsumableFormSchema.optional(),
61249
61396
  /** Ms epoch of the last replace, when known. */
61250
61397
  lastResetAt: zod.z.number().nullable(),
61251
61398
  /** Whether `reset()` is meaningful for this item. */
@@ -61268,7 +61415,7 @@ var consumablesCapability = {
61268
61415
  kind: "widget",
61269
61416
  widgetId: "host/consumables-panel",
61270
61417
  tab: "consumables",
61271
- topTab: true,
61418
+ placement: "hero",
61272
61419
  label: "Consumables",
61273
61420
  order: 5
61274
61421
  } },
@@ -61329,9 +61476,37 @@ reset: require_sleep.method(zod.z.object({
61329
61476
  */
61330
61477
  durability: "restored",
61331
61478
  /**
61332
- * History (D850): none — `items` is an array keyed by runtime ids; a history path never enters it.
61479
+ * History (D850, D917): one series per (item field, item `key`) — the item key
61480
+ * is the series scope, the item `label` names it. A vacuum tank's fill, a
61481
+ * brush's remaining life and a dishwasher's salt are each recorded the moment
61482
+ * their provider reports them; an item that appears later gets its series.
61333
61483
  */
61334
- history: "none",
61484
+ history: {
61485
+ fields: {},
61486
+ items: {
61487
+ path: "items",
61488
+ key: "key",
61489
+ label: "label",
61490
+ fields: {
61491
+ level: {
61492
+ kind: "gauge",
61493
+ unit: "%",
61494
+ deadband: 2,
61495
+ displayName: "Level"
61496
+ },
61497
+ status: {
61498
+ kind: "enum",
61499
+ displayName: "Status"
61500
+ },
61501
+ "remaining.value": {
61502
+ kind: "gauge",
61503
+ unitFrom: "remaining.unit",
61504
+ deadband: 1,
61505
+ displayName: "Remaining"
61506
+ }
61507
+ }
61508
+ }
61509
+ },
61335
61510
  /** Clocks, not content: a re-read that changed no item costs no commit. */
61336
61511
  volatileStateFields: ["lastChangedAt", "lastFetchedAt"]
61337
61512
  };
@@ -61804,8 +61979,9 @@ onStatusChanged: { data: zod.z.object({
61804
61979
  //#endregion
61805
61980
  //#region src/capabilities/dishwasher.cap.ts
61806
61981
  /**
61807
- * Smart-dishwasher cap — program lifecycle, door / remote-start gates,
61808
- * consumable levels (salt, rinse aid) and common program options.
61982
+ * Smart-dishwasher cap — program lifecycle, door / remote-start gates and
61983
+ * common program options. Salt and rinse aid are NOT here: they are items of
61984
+ * the device's `consumables` cap, like every other device's (D915).
61809
61985
  *
61810
61986
  * Sources: native Bosch Home Connect (`dishwasher` device type). Reusable
61811
61987
  * by any integration that exposes the same program / option surface.
@@ -61853,11 +62029,6 @@ var DishwasherAvailabilitySchema = zod.z.enum([
61853
62029
  "offline",
61854
62030
  "description-missing"
61855
62031
  ]);
61856
- var DishwasherConsumableLevelSchema = zod.z.enum([
61857
- "ok",
61858
- "low",
61859
- "empty"
61860
- ]);
61861
62032
  var DishwasherStatusSchema = zod.z.object({
61862
62033
  availability: DishwasherAvailabilitySchema,
61863
62034
  /** Coarse state for compact surfaces; `unavailable` whenever the appliance state is not known. */
@@ -61890,8 +62061,6 @@ var DishwasherStatusSchema = zod.z.object({
61890
62061
  powerOn: zod.z.boolean().nullable(),
61891
62062
  /** The raw power state (`On`, `Off`, `Standby`, …); null when not known. */
61892
62063
  powerState: zod.z.string().nullable(),
61893
- saltLevel: DishwasherConsumableLevelSchema.nullable(),
61894
- rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
61895
62064
  /**
61896
62065
  * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
61897
62066
  * combined care-and-filter reminder raised); false when every such reminder reads clear; null
@@ -73144,14 +73313,9 @@ var userManagementCapability = {
73144
73313
  * validates it against the vacuum's own list. `locate` triggers the
73145
73314
  * find-me chirp; `returnToBase` sends it home.
73146
73315
  *
73147
- * Consumable / waste tanks: `cleanWater` / `dirtyWater` / `detergent` /
73148
- * `dustBin` each carry a nullable `{ level (0..100 %), status ('ok' |
73149
- * 'low' | 'full') }` reading. Native providers (e.g. Dreame, Roborock)
73150
- * SHOULD populate whichever tanks the hardware has — leave a field `null`
73151
- * only when the device has no such tank at all, and use a `TankStatus`
73152
- * with both inner fields `null` when the tank exists but its level is
73153
- * currently unknown. HA `vacuum.*` entities expose no per-tank telemetry,
73154
- * so the HA provider leaves all four `null`.
73316
+ * Tanks (clean water, dirty water, detergent, dust bin) are NOT here: they
73317
+ * are `supply` / `waste` items of the device's `consumables` cap, like every
73318
+ * other device's consumables (D915).
73155
73319
  */
73156
73320
  var VacuumStateSchema = zod.z.enum([
73157
73321
  "idle",
@@ -73162,23 +73326,6 @@ var VacuumStateSchema = zod.z.enum([
73162
73326
  "drying",
73163
73327
  "error"
73164
73328
  ]);
73165
- /**
73166
- * One consumable / waste tank on a robot vacuum (clean-water, dirty-water,
73167
- * detergent or dust-bin). A tank can report a numeric fill `level` (0..100),
73168
- * a discrete `status` (binary-style hardware), or both. Both `null` means the
73169
- * level is currently unknown; the OWNING field being `null` means the
73170
- * hardware has no such tank at all.
73171
- */
73172
- var TankStatusSchema = zod.z.object({
73173
- /** Numeric fill 0..100 when the hardware reports a percentage; null otherwise. */
73174
- level: zod.z.number().min(0).max(100).nullable(),
73175
- /** Discrete state when the hardware is binary-mode; null otherwise. */
73176
- status: zod.z.enum([
73177
- "ok",
73178
- "low",
73179
- "full"
73180
- ]).nullable()
73181
- });
73182
73329
  var VacuumControlStatusSchema = zod.z.object({
73183
73330
  /** Lifecycle state of the vacuum. */
73184
73331
  state: VacuumStateSchema,
@@ -73190,14 +73337,6 @@ var VacuumControlStatusSchema = zod.z.object({
73190
73337
  fanSpeed: zod.z.string().nullable(),
73191
73338
  /** Speed tokens the hardware accepts — drives the UI selector. */
73192
73339
  availableFanSpeeds: zod.z.array(zod.z.string()),
73193
- /** Clean-water (mop) tank. Null when the hardware has no clean-water tank. */
73194
- cleanWater: TankStatusSchema.nullable(),
73195
- /** Dirty-water (recovery) tank. Null when the hardware has no dirty-water tank. */
73196
- dirtyWater: TankStatusSchema.nullable(),
73197
- /** Detergent tank. Null when the hardware has no detergent tank. */
73198
- detergent: TankStatusSchema.nullable(),
73199
- /** Dust bin. Null when the hardware has no dust bin. */
73200
- dustBin: TankStatusSchema.nullable(),
73201
73340
  /** 0..100 cleaning-completion percentage of the current task, or null. */
73202
73341
  progressPercent: zod.z.number().min(0).max(100).nullable(),
73203
73342
  /** Current error code (0 / null = no error). */
@@ -73259,35 +73398,14 @@ var vacuumControlCapability = {
73259
73398
  */
73260
73399
  durability: "session",
73261
73400
  /**
73262
- * History (D850): recorded series. Tank levels are fixed-object paths (`cleanWater.level`, ...).
73401
+ * History (D850): recorded series. The tanks moved to `consumables` (D915), whose
73402
+ * items are keyed by runtime ids and record no history.
73263
73403
  */
73264
- history: { fields: {
73265
- batteryLevel: {
73266
- kind: "gauge",
73267
- unit: "%",
73268
- deadband: 2
73269
- },
73270
- "cleanWater.level": {
73271
- kind: "gauge",
73272
- unit: "%",
73273
- deadband: 2
73274
- },
73275
- "dirtyWater.level": {
73276
- kind: "gauge",
73277
- unit: "%",
73278
- deadband: 2
73279
- },
73280
- "detergent.level": {
73281
- kind: "gauge",
73282
- unit: "%",
73283
- deadband: 2
73284
- },
73285
- "dustBin.level": {
73286
- kind: "gauge",
73287
- unit: "%",
73288
- deadband: 2
73289
- }
73290
- } }
73404
+ history: { fields: { batteryLevel: {
73405
+ kind: "gauge",
73406
+ unit: "%",
73407
+ deadband: 2
73408
+ } } }
73291
73409
  };
73292
73410
  //#endregion
73293
73411
  //#region src/capabilities/valve.cap.ts
@@ -79805,6 +79923,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
79805
79923
  addonId: null,
79806
79924
  access: "create"
79807
79925
  },
79926
+ "deviceHistory.deleteOrphanSeries": {
79927
+ capName: "device-history",
79928
+ capScope: "system",
79929
+ addonId: null,
79930
+ access: "delete"
79931
+ },
79808
79932
  "deviceHistory.getDeviceEnabled": {
79809
79933
  capName: "device-history",
79810
79934
  capScope: "system",
@@ -79823,6 +79947,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
79823
79947
  addonId: null,
79824
79948
  access: "view"
79825
79949
  },
79950
+ "deviceHistory.listOrphanSeries": {
79951
+ capName: "device-history",
79952
+ capScope: "system",
79953
+ addonId: null,
79954
+ access: "view"
79955
+ },
79826
79956
  "deviceHistory.listSeries": {
79827
79957
  capName: "device-history",
79828
79958
  capScope: "system",
@@ -93343,7 +93473,7 @@ var BucketAccumulator = class {
93343
93473
  //#region src/generated/history-catalog.ts
93344
93474
  /**
93345
93475
  * Cap history catalog, projected from every `*.cap.ts` `history` block.
93346
- * 40 caps with series (77 series), 31 caps answered `'none'`.
93476
+ * 40 caps with series (73 series), 30 caps answered `'none'`.
93347
93477
  * Field keys are `runtimeState` paths (`a.b` into fixed objects only).
93348
93478
  */
93349
93479
  var HISTORY_CATALOG = {
@@ -93646,33 +93776,11 @@ var HISTORY_CATALOG = {
93646
93776
  unit: "°C",
93647
93777
  deadband: .1
93648
93778
  } },
93649
- "vacuum-control": {
93650
- "batteryLevel": {
93651
- kind: "gauge",
93652
- unit: "%",
93653
- deadband: 2
93654
- },
93655
- "cleanWater.level": {
93656
- kind: "gauge",
93657
- unit: "%",
93658
- deadband: 2
93659
- },
93660
- "dirtyWater.level": {
93661
- kind: "gauge",
93662
- unit: "%",
93663
- deadband: 2
93664
- },
93665
- "detergent.level": {
93666
- kind: "gauge",
93667
- unit: "%",
93668
- deadband: 2
93669
- },
93670
- "dustBin.level": {
93671
- kind: "gauge",
93672
- unit: "%",
93673
- deadband: 2
93674
- }
93675
- },
93779
+ "vacuum-control": { "batteryLevel": {
93780
+ kind: "gauge",
93781
+ unit: "%",
93782
+ deadband: 2
93783
+ } },
93676
93784
  "valve": { "position": {
93677
93785
  kind: "gauge",
93678
93786
  unit: "%",
@@ -93714,13 +93822,47 @@ var HISTORY_CATALOG = {
93714
93822
  }
93715
93823
  }
93716
93824
  };
93825
+ /**
93826
+ * Keyed-array series (D917), projected from every `history.items` block:
93827
+ * 1 caps (3 item fields). The item key is the series SCOPE;
93828
+ * the series key is `cap:<capName>.<path>[].<field>`.
93829
+ */
93830
+ var HISTORY_ITEM_CATALOG = { "consumables": {
93831
+ path: "items",
93832
+ key: "key",
93833
+ label: "label",
93834
+ fields: {
93835
+ "level": {
93836
+ kind: "gauge",
93837
+ unit: "%",
93838
+ deadband: 2,
93839
+ displayName: "Level"
93840
+ },
93841
+ "status": {
93842
+ kind: "enum",
93843
+ displayName: "Status",
93844
+ values: [
93845
+ "ok",
93846
+ "low",
93847
+ "empty",
93848
+ "full",
93849
+ "replace"
93850
+ ]
93851
+ },
93852
+ "remaining.value": {
93853
+ kind: "gauge",
93854
+ unitFrom: "remaining.unit",
93855
+ deadband: 1,
93856
+ displayName: "Remaining"
93857
+ }
93858
+ }
93859
+ } };
93717
93860
  /** Caps that declared `history: 'none'`, sorted. */
93718
93861
  var HISTORY_NONE_CAPS = [
93719
93862
  "audio-metrics",
93720
93863
  "automation-control",
93721
93864
  "camera-streams",
93722
93865
  "color",
93723
- "consumables",
93724
93866
  "control",
93725
93867
  "day-night",
93726
93868
  "device-discovery",
@@ -94018,7 +94160,9 @@ function createSystemProxy(api) {
94018
94160
  declareSeries: (input) => dispatch("deviceHistory", "declareSeries", "mutation", input),
94019
94161
  record: (input) => dispatch("deviceHistory", "record", "mutation", input),
94020
94162
  recordBuckets: (input) => dispatch("deviceHistory", "recordBuckets", "mutation", input),
94021
- getStatus: (input) => dispatch("deviceHistory", "getStatus", "query", input)
94163
+ getStatus: (input) => dispatch("deviceHistory", "getStatus", "query", input),
94164
+ listOrphanSeries: (input) => dispatch("deviceHistory", "listOrphanSeries", "query", input),
94165
+ deleteOrphanSeries: (input) => dispatch("deviceHistory", "deleteOrphanSeries", "mutation", input)
94022
94166
  },
94023
94167
  deviceManager: {
94024
94168
  allocateDeviceId: (input) => dispatch("deviceManager", "allocateDeviceId", "mutation", input),
@@ -97981,17 +98125,18 @@ var NC_TEMPLATE_VARS = [
97981
98125
  {
97982
98126
  name: "item",
97983
98127
  label: "Consumable",
98128
+ description: "The device's own name for the item: a filter, a brush, the salt, a tank.",
97984
98129
  example: "Filtro",
97985
98130
  group: "system",
97986
98131
  families: ["rule"],
97987
98132
  fields: [...RULE_TEXT],
97988
98133
  kinds: ["system"],
97989
- systemEventKinds: [...CONSUMABLE]
98134
+ systemEventKinds: [...CONSUMABLE, ...TANK]
97990
98135
  },
97991
98136
  {
97992
98137
  name: "tank",
97993
98138
  label: "Tank",
97994
- description: "Which tank: clean water, dirty water, detergent or dust bin.",
98139
+ description: "Which tank, as a stable token: cleanWater, dirtyWater, detergent, dustBin, or the device key of any other supply (salt, rinse aid).",
97995
98140
  example: "clean water",
97996
98141
  group: "system",
97997
98142
  families: ["rule"],
@@ -100912,28 +101057,33 @@ var DETECTOR_PERF = {
100912
101057
  },
100913
101058
  "amd-igpu": {
100914
101059
  "yolov9t-320": {
100915
- p50Ms: 188,
100916
- fps: 5,
101060
+ p50Ms: 40,
101061
+ fps: 25,
100917
101062
  measured: true
100918
101063
  },
100919
101064
  "yolov9t-640": {
100920
- p50Ms: 671,
100921
- fps: 1,
101065
+ p50Ms: 89,
101066
+ fps: 11,
100922
101067
  measured: true
100923
101068
  },
100924
101069
  "yolov9s-320": {
100925
- p50Ms: 401,
100926
- fps: 2,
101070
+ p50Ms: 65,
101071
+ fps: 15,
100927
101072
  measured: true
100928
101073
  },
100929
101074
  "yolov9s-640": {
100930
- p50Ms: 1434,
100931
- fps: 1,
101075
+ p50Ms: 125,
101076
+ fps: 8,
100932
101077
  measured: true
100933
101078
  },
100934
101079
  "yolov9m-320": {
100935
- p50Ms: 1076,
100936
- fps: 1,
101080
+ p50Ms: 85,
101081
+ fps: 12,
101082
+ measured: true
101083
+ },
101084
+ "yolov9m-640": {
101085
+ p50Ms: 228,
101086
+ fps: 4,
100937
101087
  measured: true
100938
101088
  }
100939
101089
  },
@@ -101371,15 +101521,23 @@ function byDeficit(a, b) {
101371
101521
  function spareOf(c) {
101372
101522
  return c.spare ?? Number.POSITIVE_INFINITY;
101373
101523
  }
101374
- function electByShare(candidates) {
101375
- if (candidates.length === 0) return { kind: "none" };
101524
+ function loadOf(c) {
101525
+ return Math.max(c.running, 0) + Math.max(c.recent ?? 0, 0);
101526
+ }
101527
+ /** Every candidate with its deficit, the turn holder first. */
101528
+ function scoreShares(candidates) {
101376
101529
  const shareSum = candidates.reduce((s, c) => s + Math.max(c.share, 0), 0);
101377
- const loadOf = (c) => Math.max(c.running, 0) + Math.max(c.recent ?? 0, 0);
101378
101530
  const running = candidates.reduce((s, c) => s + loadOf(c), 0);
101379
- const scored = candidates.map((candidate) => ({
101531
+ return candidates.map((candidate) => ({
101380
101532
  candidate,
101381
101533
  deficit: (shareSum > 0 ? Math.max(candidate.share, 0) / shareSum : 1 / candidates.length) * (running + 1) - loadOf(candidate)
101382
101534
  })).toSorted(byDeficit);
101535
+ }
101536
+ function electByShare(candidates) {
101537
+ if (candidates.length === 0) return { kind: "none" };
101538
+ return electFromScored(scoreShares(candidates));
101539
+ }
101540
+ function electFromScored(scored) {
101383
101541
  const turn = scored[0].candidate;
101384
101542
  if (!turn.capped && !turn.saturated) return {
101385
101543
  kind: "elected",
@@ -101403,6 +101561,55 @@ function electByShare(candidates) {
101403
101561
  reason: "share"
101404
101562
  };
101405
101563
  }
101564
+ /**
101565
+ * Affinity (D916, amends D913): a camera's sessions are short and frequent, and
101566
+ * every election is a fresh one — with the recency memory rotating on purpose,
101567
+ * one camera hopped node on 11 of 14 sessions in ten minutes, each hop a stream
101568
+ * dial, a decode-worker fork and a cold pre-roll. The candidate a camera ran on
101569
+ * last is kept while its deficit is within {@link SHARE_AFFINITY_TOLERANCE_SESSIONS}
101570
+ * of the turn holder's, and while it has room (offered, not capped, not
101571
+ * drowning). It moves only when the share is really off — and because a kept
101572
+ * session still counts toward its candidate, the cumulative split still follows
101573
+ * the shares: no candidate runs more than about one session over its share
101574
+ * before its cameras leave.
101575
+ */
101576
+ var SHARE_AFFINITY_TOLERANCE_SESSIONS = 1;
101577
+ function toScoredCandidate(s) {
101578
+ return {
101579
+ key: s.candidate.key,
101580
+ share: s.candidate.share,
101581
+ running: s.candidate.running,
101582
+ recent: s.candidate.recent ?? 0,
101583
+ deficit: s.deficit
101584
+ };
101585
+ }
101586
+ /** {@link electByShare}, keeping the previous candidate while the share allows it. */
101587
+ function electByShareWithAffinity(candidates, previousKey, toleranceSessions = 1) {
101588
+ const scored = candidates.length === 0 ? [] : scoreShares(candidates);
101589
+ const plain = scored.length === 0 ? { kind: "none" } : electFromScored(scored);
101590
+ const turnKey = plain.kind === "elected" ? plain.key : null;
101591
+ const result = (election, sticky, affinityReason) => ({
101592
+ election,
101593
+ sticky,
101594
+ affinityReason,
101595
+ previousKey,
101596
+ turnKey,
101597
+ scored: scored.map(toScoredCandidate)
101598
+ });
101599
+ if (previousKey === null) return result(plain, false, "no-previous");
101600
+ if (turnKey === previousKey) return result(plain, true, "previous-is-turn");
101601
+ const previous = scored.find((s) => s.candidate.key === previousKey);
101602
+ if (previous === void 0) return result(plain, false, "previous-ineligible");
101603
+ if (previous.candidate.capped || previous.candidate.saturated) return result(plain, false, "previous-no-room");
101604
+ const elected = scored.find((s) => s.candidate.key === turnKey);
101605
+ if (elected === void 0) return result(plain, false, "share-off");
101606
+ if (previous.deficit >= elected.deficit - toleranceSessions - DEFICIT_EPSILON) return result({
101607
+ kind: "elected",
101608
+ key: previousKey,
101609
+ reason: "share"
101610
+ }, true, "within-one-session");
101611
+ return result(plain, false, "share-off");
101612
+ }
101406
101613
  //#endregion
101407
101614
  //#region src/pipeline/load-balancing/effective-shares.ts
101408
101615
  /**
@@ -101490,6 +101697,39 @@ function resolveEffectiveShares(input) {
101490
101697
  * every enabled device it would be sized on is sized from `hardware`
101491
101698
  * instead, and the answer says so per node — never a silent mix.
101492
101699
  */
101700
+ /**
101701
+ * The measured capacity of `deviceKey` for the model it runs NOW, or
101702
+ * undefined. A cell measured for another model says nothing about this one
101703
+ * (a failed load of a heavier build is not this build's capacity), and a cell
101704
+ * that names no model cannot be matched. The ONE predicate behind both the
101705
+ * automatic shares and the automatic benchmark's "has results".
101706
+ */
101707
+ function capacityForModel(node, deviceKey, modelId) {
101708
+ if (node === void 0 || modelId === null) return void 0;
101709
+ return node.devices.filter((d) => d.deviceKey === deviceKey && d.modelId === modelId).toSorted((a, b) => b.measuredAtMs - a.measuredAtMs)[0];
101710
+ }
101711
+ /**
101712
+ * Every measured (device × model) cell that no device runs now — what
101713
+ * {@link capacityForModel} skips, so the caller can say so once.
101714
+ */
101715
+ function foreignCapacityCells(recommendations, measured) {
101716
+ const out = [];
101717
+ for (const rec of recommendations) {
101718
+ const node = measured.get(rec.nodeId);
101719
+ if (node === void 0) continue;
101720
+ for (const cell of node.devices) {
101721
+ const runs = rec.devices.find((d) => d.deviceKey === cell.deviceKey)?.chosen?.modelId ?? null;
101722
+ if (cell.modelId === null || cell.modelId === runs) continue;
101723
+ out.push({
101724
+ nodeId: rec.nodeId,
101725
+ deviceKey: cell.deviceKey,
101726
+ measuredModelId: cell.modelId,
101727
+ runsModelId: runs
101728
+ });
101729
+ }
101730
+ }
101731
+ return out;
101732
+ }
101493
101733
  /** A source that has no results — the benchmark store before it exists. */
101494
101734
  var NO_MEASURED_CAPACITY = { readMeasuredCapacity: async () => /* @__PURE__ */ new Map() };
101495
101735
  /** Integer shares summing to 100 (largest remainder); ties broken by key. */
@@ -101543,7 +101783,11 @@ function sizeNode(rec, input) {
101543
101783
  if (input.source === "hardware") return fromHardware(null);
101544
101784
  if (!rec.reachable) return fromHardware(null);
101545
101785
  const results = input.measured.get(rec.nodeId);
101546
- const byKey = new Map((results?.devices ?? []).map((d) => [d.deviceKey, d]));
101786
+ const byKey = /* @__PURE__ */ new Map();
101787
+ for (const d of rec.devices) {
101788
+ const row = capacityForModel(results, d.deviceKey, d.chosen?.modelId ?? null);
101789
+ if (row !== void 0) byKey.set(d.deviceKey, row);
101790
+ }
101547
101791
  const usable = rec.devices.filter((d) => d.enabled && d.available);
101548
101792
  const mustCover = rec.devices.filter((d) => d.enabled && d.available && d.chosen !== null);
101549
101793
  const covered = usable.filter((d) => byKey.has(d.deviceKey));
@@ -101797,16 +102041,34 @@ function measuredDetectorCells(rows, nodeId, ctx) {
101797
102041
  return out;
101798
102042
  }
101799
102043
  /**
101800
- * Per node, each device at its newest fresh `pipeline` measurement — the
101801
- * `NodeCapacitySource` answer the automatic shares read.
102044
+ * Parallel sessions a `device`-phase cell stands for.
102045
+ *
102046
+ * Both numbers are "streams at the camera rate the hardware carried inside
102047
+ * the frame interval" (`kMax` for the detector alone, `maxSessions` for the
102048
+ * detector plus its enrichment steps) and the benchmark page already shows
102049
+ * `kMax` as "streams", so the unit is the same and the conversion is the
102050
+ * identity. It is an UPPER bound for a session that also runs enrichment —
102051
+ * which is why a `pipeline` cell for the same model always wins over it.
102052
+ */
102053
+ function sessionsOfDeviceCell(kMax) {
102054
+ return Math.max(0, Math.floor(kMax));
102055
+ }
102056
+ /**
102057
+ * Per node, every (device × model) at its best fresh measurement: the newest
102058
+ * `pipeline` cell, else the newest `device` cell read as
102059
+ * {@link sessionsOfDeviceCell}. Several models of one device are kept apart —
102060
+ * the caller picks the one the device runs NOW (a cell for another model says
102061
+ * nothing about it).
101802
102062
  */
101803
102063
  function measuredCapacityFromResults(rows, nodeIds, ctx) {
101804
102064
  const byNode = /* @__PURE__ */ new Map();
101805
102065
  for (const row of freshResults(rows, ctx)) {
101806
- if (!nodeIds.includes(row.nodeId) || row.cell.phase !== "pipeline") continue;
102066
+ if (!nodeIds.includes(row.nodeId)) continue;
102067
+ const candidate = capacityOfRow(row);
101807
102068
  const devices = byNode.get(row.nodeId) ?? /* @__PURE__ */ new Map();
101808
- const held = devices.get(row.cell.deviceKey);
101809
- if (held === void 0 || row.measuredAtMs > held.measuredAtMs) devices.set(row.cell.deviceKey, row);
102069
+ const key = `${candidate.deviceKey}\u0000${candidate.modelId ?? ""}`;
102070
+ const held = devices.get(key);
102071
+ if (held === void 0 || betterCapacityCell(candidate, held)) devices.set(key, candidate);
101810
102072
  byNode.set(row.nodeId, devices);
101811
102073
  }
101812
102074
  const out = /* @__PURE__ */ new Map();
@@ -101815,16 +102077,32 @@ function measuredCapacityFromResults(rows, nodeIds, ctx) {
101815
102077
  if (devices === void 0) continue;
101816
102078
  out.set(nodeId, {
101817
102079
  nodeId,
101818
- devices: [...devices.values()].toSorted((a, b) => a.cell.deviceKey.localeCompare(b.cell.deviceKey)).map((r) => ({
101819
- deviceKey: r.cell.deviceKey,
101820
- maxSessions: r.cell.phase === "pipeline" ? r.cell.maxSessions : 0,
101821
- modelId: r.cell.modelId,
101822
- measuredAtMs: r.measuredAtMs
101823
- }))
102080
+ devices: [...devices.values()].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey) || (a.modelId ?? "").localeCompare(b.modelId ?? ""))
101824
102081
  });
101825
102082
  }
101826
102083
  return out;
101827
102084
  }
102085
+ function capacityOfRow(row) {
102086
+ const { cell } = row;
102087
+ return cell.phase === "pipeline" ? {
102088
+ deviceKey: cell.deviceKey,
102089
+ maxSessions: cell.maxSessions,
102090
+ modelId: cell.modelId,
102091
+ measuredAtMs: row.measuredAtMs,
102092
+ phase: "pipeline"
102093
+ } : {
102094
+ deviceKey: cell.deviceKey,
102095
+ maxSessions: sessionsOfDeviceCell(cell.kMax),
102096
+ modelId: cell.modelId,
102097
+ measuredAtMs: row.measuredAtMs,
102098
+ phase: "device"
102099
+ };
102100
+ }
102101
+ /** A pipeline cell beats a device cell; within a phase the newer one wins. */
102102
+ function betterCapacityCell(a, b) {
102103
+ if (a.phase !== b.phase) return a.phase === "pipeline";
102104
+ return a.measuredAtMs > b.measuredAtMs;
102105
+ }
101828
102106
  //#endregion
101829
102107
  //#region src/pipeline/node-benchmark/step-tree.ts
101830
102108
  var BENCH_ROOT_STEP_ID = "object-detection";
@@ -104564,9 +104842,13 @@ exports.ConnectionTestDescriptorSchema = ConnectionTestDescriptorSchema;
104564
104842
  exports.ConnectionTestInputSchema = ConnectionTestInputSchema;
104565
104843
  exports.ConnectionTestOutcomeSchema = ConnectionTestOutcomeSchema;
104566
104844
  exports.ConnectivityStatusSchema = ConnectivityStatusSchema;
104845
+ exports.ConsumableFormSchema = ConsumableFormSchema;
104567
104846
  exports.ConsumableItemSchema = ConsumableItemSchema;
104847
+ exports.ConsumableKindSchema = ConsumableKindSchema;
104848
+ exports.ConsumableLevelSchema = ConsumableLevelSchema;
104568
104849
  exports.ConsumableRemainingSchema = ConsumableRemainingSchema;
104569
104850
  exports.ConsumableRemainingUnitSchema = ConsumableRemainingUnitSchema;
104851
+ exports.ConsumableStatusSchema = ConsumableStatusSchema;
104570
104852
  exports.ConsumablesStatusSchema = ConsumablesStatusSchema;
104571
104853
  exports.ContactStatusSchema = ContactStatusSchema;
104572
104854
  exports.ControlKindSchema = ControlKindSchema;
@@ -104647,6 +104929,8 @@ exports.DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE = DEVICE_DEFINITIVE_REFUSALS_BE
104647
104929
  exports.DEVICE_DO_ACTIONS = DEVICE_DO_ACTIONS;
104648
104930
  exports.DEVICE_ENROLLMENT_TTL_MS = DEVICE_ENROLLMENT_TTL_MS;
104649
104931
  exports.DEVICE_HISTORY_ENERGY_KEY = DEVICE_HISTORY_ENERGY_KEY;
104932
+ exports.DEVICE_HISTORY_ORPHAN_DELETE_MAX = DEVICE_HISTORY_ORPHAN_DELETE_MAX;
104933
+ exports.DEVICE_HISTORY_ORPHAN_LIST_MAX = DEVICE_HISTORY_ORPHAN_LIST_MAX;
104650
104934
  exports.DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS = DEVICE_HISTORY_QUERY_MANY_MAX_ITEMS;
104651
104935
  exports.DEVICE_NONCE_TTL_MS = DEVICE_NONCE_TTL_MS;
104652
104936
  exports.DEVICE_PROFILES = DEVICE_PROFILES;
@@ -104706,6 +104990,8 @@ exports.DeviceExportStatusSchema = DeviceExportStatusSchema;
104706
104990
  exports.DeviceExportUnexposeInputSchema = UnexposeInputSchema;
104707
104991
  exports.DeviceFeature = require_err_msg.DeviceFeature;
104708
104992
  exports.DeviceHistoryKindSchema = DeviceHistoryKindSchema;
104993
+ exports.DeviceHistoryOrphanDeleteRefusalSchema = DeviceHistoryOrphanDeleteRefusalSchema;
104994
+ exports.DeviceHistoryOrphanReasonSchema = DeviceHistoryOrphanReasonSchema;
104709
104995
  exports.DeviceHistoryProducerKindSchema = DeviceHistoryProducerKindSchema;
104710
104996
  exports.DeviceHistoryRefusalReasonSchema = DeviceHistoryRefusalReasonSchema;
104711
104997
  exports.DeviceHistoryResolutionSchema = DeviceHistoryResolutionSchema;
@@ -104738,7 +105024,6 @@ exports.DiscoveredDeviceSchema = DiscoveredDeviceSchema;
104738
105024
  exports.DiscoveredTargetSchema = DiscoveredTargetSchema;
104739
105025
  exports.DishwasherAccessSchema = DishwasherAccessSchema;
104740
105026
  exports.DishwasherAvailabilitySchema = DishwasherAvailabilitySchema;
104741
- exports.DishwasherConsumableLevelSchema = DishwasherConsumableLevelSchema;
104742
105027
  exports.DishwasherOperationStateSchema = DishwasherOperationStateSchema;
104743
105028
  exports.DishwasherOptionDescriptorSchema = DishwasherOptionDescriptorSchema;
104744
105029
  exports.DishwasherOptionsSchema = DishwasherOptionsSchema;
@@ -104899,6 +105184,7 @@ exports.HF_REPO = require_sleep.HF_REPO;
104899
105184
  exports.HISTORY_BUCKET_MS = HISTORY_BUCKET_MS;
104900
105185
  exports.HISTORY_CATALOG = HISTORY_CATALOG;
104901
105186
  exports.HISTORY_DEFAULT_MIN_INTERVAL_MS = require_sleep.HISTORY_DEFAULT_MIN_INTERVAL_MS;
105187
+ exports.HISTORY_ITEM_CATALOG = HISTORY_ITEM_CATALOG;
104902
105188
  exports.HISTORY_NONE_CAPS = HISTORY_NONE_CAPS;
104903
105189
  exports.HISTORY_UNIT_LABELS = require_sleep.HISTORY_UNIT_LABELS;
104904
105190
  exports.HOURS_PER_DAY = HOURS_PER_DAY;
@@ -105787,6 +106073,7 @@ exports.SENSOR_MAP = SENSOR_MAP;
105787
106073
  exports.SERVER_NAME_MAX_LENGTH = SERVER_NAME_MAX_LENGTH;
105788
106074
  exports.SERVER_NAME_SETTING_KEY = SERVER_NAME_SETTING_KEY;
105789
106075
  exports.SESSION_PLACEMENT_SETTING_KEY = SESSION_PLACEMENT_SETTING_KEY;
106076
+ exports.SHARE_AFFINITY_TOLERANCE_SESSIONS = SHARE_AFFINITY_TOLERANCE_SESSIONS;
105790
106077
  exports.SHARE_SOURCE_SETTING_KEY = SHARE_SOURCE_SETTING_KEY;
105791
106078
  exports.SHARE_VIEW_KINDS = require_sleep.SHARE_VIEW_KINDS;
105792
106079
  exports.SHARE_VIEW_MAX_DEVICES = SHARE_VIEW_MAX_DEVICES;
@@ -105951,7 +106238,6 @@ exports.TRAINING_RESULT_SCHEMA = TRAINING_RESULT_SCHEMA;
105951
106238
  exports.TRANSCODE_DOWN_MAX_BITRATE_KBPS = TRANSCODE_DOWN_MAX_BITRATE_KBPS;
105952
106239
  exports.TRANSCODE_DOWN_MAX_HEIGHT = TRANSCODE_DOWN_MAX_HEIGHT;
105953
106240
  exports.TamperStatusSchema = TamperStatusSchema;
105954
- exports.TankStatusSchema = TankStatusSchema;
105955
106241
  exports.TargetKindCapsSchema = TargetKindCapsSchema;
105956
106242
  exports.TargetKindLevelSchema = TargetKindLevelSchema;
105957
106243
  exports.TargetKindSchema = TargetKindSchema;
@@ -106223,6 +106509,7 @@ exports.canonicalEgressPlan = canonicalEgressPlan;
106223
106509
  exports.canonicalIconKey = canonicalIconKey;
106224
106510
  exports.canonicalizeAppCallback = canonicalizeAppCallback;
106225
106511
  exports.capabilityScopesOf = capabilityScopesOf;
106512
+ exports.capacityForModel = capacityForModel;
106226
106513
  exports.capacitySessionsOf = capacitySessionsOf;
106227
106514
  exports.carbonMonoxideCapability = carbonMonoxideCapability;
106228
106515
  exports.cellsToRects = cellsToRects;
@@ -106281,6 +106568,8 @@ exports.conditionExclusionReason = conditionExclusionReason;
106281
106568
  exports.conditionVisibleForKind = conditionVisibleForKind;
106282
106569
  exports.connectionTestCapability = connectionTestCapability;
106283
106570
  exports.connectivityCapability = connectivityCapability;
106571
+ exports.consumableFormOf = consumableFormOf;
106572
+ exports.consumableKindOf = consumableKindOf;
106284
106573
  exports.consumableLowPercentOf = consumableLowPercentOf;
106285
106574
  exports.consumablesCapability = consumablesCapability;
106286
106575
  exports.contactCapability = contactCapability;
@@ -106387,6 +106676,7 @@ exports.effectiveStepSettings = effectiveStepSettings;
106387
106676
  exports.egressTranscodeSharingKey = egressTranscodeSharingKey;
106388
106677
  exports.egressTransportFromRequest = egressTransportFromRequest;
106389
106678
  exports.electByShare = electByShare;
106679
+ exports.electByShareWithAffinity = electByShareWithAffinity;
106390
106680
  exports.eligibleUnderBenchmark = eligibleUnderBenchmark;
106391
106681
  exports.embeddingEncoderCapability = embeddingEncoderCapability;
106392
106682
  exports.embeddingModelFailedError = embeddingModelFailedError;
@@ -106451,6 +106741,7 @@ exports.findCompositionCycles = findCompositionCycles;
106451
106741
  exports.findTimezone = findTimezone;
106452
106742
  exports.floodCapability = floodCapability;
106453
106743
  exports.foldSnapshotByFunction = foldSnapshotByFunction;
106744
+ exports.foreignCapacityCells = foreignCapacityCells;
106454
106745
  exports.forgetKnownSecret = require_sleep.forgetKnownSecret;
106455
106746
  exports.formatDeviceRevoker = formatDeviceRevoker;
106456
106747
  exports.formatForRuntime = formatForRuntime;
@@ -106479,6 +106770,7 @@ exports.hasUrlScheme = hasUrlScheme;
106479
106770
  exports.heatingValveCapability = heatingValveCapability;
106480
106771
  exports.hfModelUrl = require_sleep.hfModelUrl;
106481
106772
  exports.historyFieldsFor = historyFieldsFor;
106773
+ exports.historyItemFieldPath = require_sleep.historyItemFieldPath;
106482
106774
  exports.htmlToText = htmlToText;
106483
106775
  exports.hubAddressHostname = hubAddressHostname;
106484
106776
  exports.hubMotionNativeProvider = hubMotionNativeProvider;
@@ -106882,6 +107174,7 @@ exports.sensorTransitionNeverFires = sensorTransitionNeverFires;
106882
107174
  exports.sensorTransitionOffered = sensorTransitionOffered;
106883
107175
  exports.servedTemplateVars = servedTemplateVars;
106884
107176
  exports.serverManagementCapability = serverManagementCapability;
107177
+ exports.sessionsOfDeviceCell = sessionsOfDeviceCell;
106885
107178
  exports.setByPath = setByPath;
106886
107179
  exports.settingValuesEqual = settingValuesEqual;
106887
107180
  exports.settingsBelow = settingsBelow;