@camstack/addon-provider-rtsp 1.2.130 → 1.2.132

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.
Files changed (3) hide show
  1. package/dist/addon.js +496 -141
  2. package/dist/addon.mjs +496 -141
  3. package/package.json +1 -1
package/dist/addon.mjs CHANGED
@@ -5414,7 +5414,7 @@ var ZodIssueCode = {
5414
5414
  var ZodFirstPartyTypeKind;
5415
5415
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5416
5416
  //#endregion
5417
- //#region ../types/dist/sleep-BxjU_fJM.mjs
5417
+ //#region ../types/dist/sleep-BSuCCFjf.mjs
5418
5418
  /**
5419
5419
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5420
5420
  * window to float samples (D455).
@@ -7797,9 +7797,9 @@ function normalizeAddonInitResult(result) {
7797
7797
  return result;
7798
7798
  }
7799
7799
  /**
7800
- * The share-view scope kinds a `csv_*` share token can carry. The hub mints
7801
- * and validates them (`share-token.service.ts` builds its enum from this
7802
- * list); a data plane names the kinds it ACCEPTS in `share`.
7800
+ * The share-view scope kinds a share-link token can carry. The hub mints
7801
+ * and validates them (`ShareViewGrantSchema` builds its
7802
+ * enum from this list); a data plane names the kinds it ACCEPTS in `share`.
7803
7803
  */
7804
7804
  var SHARE_VIEW_KINDS = ["grid-view", "events-view"];
7805
7805
  /** The wire shape of {@link PeerBytesTicket} — see the type for what it is. */
@@ -12610,7 +12610,7 @@ var ConvertResultSchema = object({
12610
12610
  * `super_admin` — collapsed onto the single boolean because every
12611
12611
  * non-admin caller is governed by the same scope-check rules; the
12612
12612
  * distinction was only ever used to route role-specific procedures
12613
- * which we no longer have. CLI / webhook integrations are `cst_*` tokens
12613
+ * which we no longer have. CLI / webhook integrations are tokens (`auth.mintToken`)
12614
12614
  * with `isAdmin: false` + an explicit scope list.
12615
12615
  */
12616
12616
  /** Per-method access flavour. Materialised on every cap method via codegen. */
@@ -12799,10 +12799,12 @@ var AddonRoutesScopeSchema = object({
12799
12799
  type: literal("addon-routes"),
12800
12800
  access: array(MethodAccessSchema).min(1)
12801
12801
  });
12802
+ var PreferencesSelfScopeSchema = object({ type: literal("preferences-self") });
12802
12803
  var CredentialScopeSchema = union([
12803
12804
  literal("*"),
12804
12805
  ShareViewScopeSchema,
12805
12806
  AddonRoutesScopeSchema,
12807
+ PreferencesSelfScopeSchema,
12806
12808
  TokenScopeSchema
12807
12809
  ]);
12808
12810
  object({
@@ -12811,6 +12813,55 @@ object({
12811
12813
  jti: string().min(16),
12812
12814
  scopes: array(CredentialScopeSchema).min(1)
12813
12815
  });
12816
+ var PreferenceNamespaceSchema = string().regex(/^[a-z][a-z0-9.-]{0,63}$/);
12817
+ /** A namespace's value: a JSON object, opaque to the hub. */
12818
+ var PreferenceValueSchema = record(string(), unknown());
12819
+ var PreferenceDeviceIdSchema = string().min(1).max(64);
12820
+ /** A stored row, as the owner reads it. */
12821
+ var PreferenceRowSchema = object({
12822
+ namespace: PreferenceNamespaceSchema,
12823
+ value: PreferenceValueSchema,
12824
+ /** Starts at 1, +1 on every write of this namespace. A delete ends the row and its count. */
12825
+ revision: number().int().positive(),
12826
+ updatedAt: number().int(),
12827
+ /** The client id the last writer sent; `null` when it sent none. */
12828
+ updatedByDevice: PreferenceDeviceIdSchema.nullable()
12829
+ });
12830
+ object({
12831
+ /** Absent: every namespace the caller holds. */
12832
+ namespaces: array(PreferenceNamespaceSchema).max(32).optional() });
12833
+ object({ rows: array(PreferenceRowSchema) });
12834
+ object({
12835
+ namespace: PreferenceNamespaceSchema,
12836
+ value: PreferenceValueSchema,
12837
+ /**
12838
+ * The revision the edit was based on. Absent: last write wins. `0`: the
12839
+ * namespace must not exist yet. Any other value that is not the current
12840
+ * revision answers `conflict` and writes nothing.
12841
+ */
12842
+ baseRevision: number().int().nonnegative().optional(),
12843
+ deviceId: PreferenceDeviceIdSchema.optional()
12844
+ });
12845
+ discriminatedUnion("status", [object({
12846
+ status: literal("saved"),
12847
+ row: PreferenceRowSchema
12848
+ }), object({
12849
+ status: literal("conflict"),
12850
+ current: PreferenceRowSchema.nullable()
12851
+ })]);
12852
+ object({ namespace: PreferenceNamespaceSchema });
12853
+ object({
12854
+ /** `false` when the namespace did not exist. */
12855
+ deleted: boolean() });
12856
+ object({
12857
+ /** The revision the client holds per namespace; a namespace it does not list is new to it. */
12858
+ revisionByNamespace: record(PreferenceNamespaceSchema, number().int().nonnegative()).refine((map) => Object.keys(map).length <= 32, { message: `at most 32 namespaces` }) });
12859
+ object({
12860
+ /** Every row whose revision differs from the client's, and every row it did not list. */
12861
+ rows: array(PreferenceRowSchema),
12862
+ /** Namespaces the client listed that no longer exist. */
12863
+ deleted: array(PreferenceNamespaceSchema)
12864
+ });
12814
12865
  _enum(["new-session", "step-up"]);
12815
12866
  /** The languages the hub's app landing pages are written in (D858). */
12816
12867
  var AppPageLangSchema = _enum(["en", "it"]);
@@ -17064,7 +17115,19 @@ var DeviceHistorySubjectSchema = discriminatedUnion("kind", [object({
17064
17115
  kind: literal("node"),
17065
17116
  nodeId: string().min(1)
17066
17117
  })]);
17118
+ /**
17119
+ * `enum` stores a STATE as the ordinal of its value in the series' value list
17120
+ * (`DeviceHistorySeriesInfo.values`, append-only, so an ordinal never changes
17121
+ * meaning); a rollup keeps the time spent in each state (`states`).
17122
+ */
17067
17123
  var DeviceHistoryKindSchema = _enum([
17124
+ "gauge",
17125
+ "counter",
17126
+ "boolean",
17127
+ "enum"
17128
+ ]);
17129
+ /** What a PRODUCER may declare. `enum` is cap-only: its value list is the cap field's. */
17130
+ var DeviceHistoryProducerKindSchema = _enum([
17068
17131
  "gauge",
17069
17132
  "counter",
17070
17133
  "boolean"
@@ -17101,7 +17164,13 @@ var SeriesInfoSchema = object({
17101
17164
  /** `null` is unknown (a `unitFrom` series whose device does not state a unit right now), never a guess. */
17102
17165
  unit: string().nullable(),
17103
17166
  displayName: string(),
17104
- source: _enum(["cap", "addon"]),
17167
+ source: _enum([
17168
+ "cap",
17169
+ "addon",
17170
+ "derived"
17171
+ ]),
17172
+ /** `enum`: the value of each ordinal (index = ordinal); `null` for every other kind. */
17173
+ values: array(string()).readonly().nullable(),
17105
17174
  firstTs: number(),
17106
17175
  lastTs: number()
17107
17176
  });
@@ -17115,17 +17184,31 @@ var QueryPointSchema = object({
17115
17184
  twMean: number().nullable(),
17116
17185
  min: number(),
17117
17186
  max: number(),
17118
- /** `null` is unknown, never zero (D393). */
17119
- last: number().nullable()
17187
+ /** `null` is unknown, never zero (D393). For an `enum` series: the ordinal of {@link state}. */
17188
+ last: number().nullable(),
17189
+ /**
17190
+ * The increase over the point: a `counter`'s growth since the previous point
17191
+ * or bucket (a drop is a reset, counted from zero), and for
17192
+ * {@link DEVICE_HISTORY_ENERGY_KEY} the kWh used in the bucket. `null` for
17193
+ * every other kind, and when it cannot be known.
17194
+ */
17195
+ delta: number().nullable(),
17196
+ /** `enum`: the state in force at the end of the point (the name of `last`); `null` otherwise. */
17197
+ state: string().nullable(),
17198
+ /** `enum` rollup: milliseconds spent in each state inside the bucket; `null` for raw points and other kinds. */
17199
+ states: record(string(), number()).nullable()
17120
17200
  });
17121
17201
  var QuerySeriesSchema = object({
17122
17202
  scope: string(),
17123
17203
  /** The last point STRICTLY BEFORE `from` in the chosen tier, so a step chart can start at the held value. */
17124
17204
  before: object({
17125
17205
  t: number(),
17126
- value: number().nullable()
17206
+ value: number().nullable(),
17207
+ state: string().nullable()
17127
17208
  }).nullable(),
17128
- points: array(QueryPointSchema).readonly()
17209
+ points: array(QueryPointSchema).readonly(),
17210
+ /** A derived key: the stored key its points were computed from; `null` for a stored series. */
17211
+ derivedFrom: string().nullable()
17129
17212
  });
17130
17213
  /** The window part of a query, shared by the device and node forms. */
17131
17214
  var QueryWindowShape = {
@@ -17141,6 +17224,23 @@ var QueryResultSchema = object({
17141
17224
  series: array(QuerySeriesSchema).readonly(),
17142
17225
  truncated: boolean()
17143
17226
  });
17227
+ /** One read of a batch: a device's key or a node's key (exactly one subject). */
17228
+ var QueryManyItemSchema = union([object({
17229
+ deviceId: number().int(),
17230
+ key: string(),
17231
+ scope: string().optional()
17232
+ }), object({
17233
+ forNodeId: string().min(1),
17234
+ key: string(),
17235
+ scope: string().optional()
17236
+ })]);
17237
+ var QueryManyEntrySchema = discriminatedUnion("ok", [object({
17238
+ ok: literal(true),
17239
+ result: QueryResultSchema
17240
+ }), object({
17241
+ ok: literal(false),
17242
+ error: string()
17243
+ })]);
17144
17244
  var TierStatusSchema = object({
17145
17245
  tier: DeviceHistoryResolutionSchema,
17146
17246
  /** `null` until the first background count answered. */
@@ -17196,16 +17296,22 @@ var DeviceHistoryStatusSchema = object({
17196
17296
  lastRefreshAt: number().nullable()
17197
17297
  })
17198
17298
  });
17199
- method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ nodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17299
+ method(object({ deviceId: number().int() }), array(SeriesInfoSchema).readonly()), method(object({ forNodeId: string().min(1) }), array(SeriesInfoSchema).readonly(), { auth: "admin" }), method(object({
17200
17300
  deviceId: number().int(),
17201
17301
  ...QueryWindowShape
17202
17302
  }), QueryResultSchema), method(object({
17203
- nodeId: string().min(1),
17303
+ forNodeId: string().min(1),
17204
17304
  ...QueryWindowShape
17205
17305
  }), QueryResultSchema, { auth: "admin" }), method(object({
17306
+ items: array(QueryManyItemSchema).min(1).max(24),
17307
+ from: QueryWindowShape.from,
17308
+ to: QueryWindowShape.to,
17309
+ resolution: QueryWindowShape.resolution,
17310
+ maxPoints: QueryWindowShape.maxPoints
17311
+ }), object({ results: array(QueryManyEntrySchema).readonly() }), { auth: "admin" }), method(object({
17206
17312
  name: string().regex(/^[a-z0-9-]+$/),
17207
17313
  subjectKind: _enum(["device", "node"]),
17208
- kind: DeviceHistoryKindSchema,
17314
+ kind: DeviceHistoryProducerKindSchema,
17209
17315
  unit: string().optional(),
17210
17316
  displayName: string().min(1),
17211
17317
  ingest: _enum(["points", "buckets"])
@@ -39987,38 +40093,37 @@ method(LlmRuntimeCompleteInputSchema, LlmGenerateResultSchema, {
39987
40093
  auth: "admin",
39988
40094
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
39989
40095
  });
40096
+ var LlmProfileKindSchema = string().regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "a kind id is lower-case letters, digits and dashes");
40097
+ /** What a model (or, by default, every model of a kind) can do. */
40098
+ var LlmModelFeaturesSchema = object({
40099
+ vision: boolean(),
40100
+ tools: boolean(),
40101
+ streaming: boolean()
40102
+ });
40103
+ /** One model a provider offers. `features` overrides the kind's defaults, per field. */
40104
+ var LlmModelInfoSchema = object({
40105
+ id: string(),
40106
+ label: string().optional(),
40107
+ contextLength: number().int().positive().optional(),
40108
+ features: LlmModelFeaturesSchema.partial().optional()
40109
+ });
39990
40110
  /**
39991
- * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
39992
- * methods concat-fan across providers; single-row methods route to ONE
39993
- * provider by the `addonId` in the call input (the notification-output
39994
- * posture, notification-output.cap.ts:215-250). Provided by `addon-ai`
39995
- * (hub-placed); the cap stays open for future providers.
39996
- *
39997
- * Profiles are ROWS (data), not addons: one row = one usable model endpoint.
39998
- * `apiKey` is a password field — providers REDACT it on read and merge on
39999
- * write; a stored key NEVER round-trips to a client.
40111
+ * The provider-specific part of a profile, validated by the provider that owns
40112
+ * the kind (`upsertProfile` refuses what it does not accept). A field its
40113
+ * `connectionSchema` declares `type: 'password'` is a secret: it is held in the
40114
+ * keychain, never in the row, and reads back as the redaction marker.
40000
40115
  */
40001
- var LlmProfileKindSchema = _enum([
40002
- "openai-compatible",
40003
- "openai",
40004
- "anthropic",
40005
- "google",
40006
- "managed-local",
40007
- "apple-foundation"
40008
- ]);
40116
+ var LlmProviderConfigSchema = record(string(), unknown());
40009
40117
  var LlmProfileSchema = object({
40010
40118
  id: string(),
40011
40119
  name: string(),
40120
+ /** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
40012
40121
  kind: LlmProfileKindSchema,
40013
40122
  /** Stamped by the provider — keeps the fanned catalog routable. */
40014
40123
  addonId: string(),
40015
40124
  enabled: boolean(),
40016
40125
  /** Vendor model id, or the managed runtime's loaded model. */
40017
40126
  model: string(),
40018
- /** Required for openai-compatible; override for cloud kinds. */
40019
- baseUrl: string().optional(),
40020
- /** ConfigUISchema type:'password' — never round-trips (spec §5). */
40021
- apiKey: string().optional(),
40022
40127
  /** Vision on/off. A vision call against a `false` profile is REFUSED, never
40023
40128
  * degraded to text — that shipped once and produced a confident answer to a
40024
40129
  * question about a picture nobody sent. */
@@ -40026,15 +40131,11 @@ var LlmProfileSchema = object({
40026
40131
  temperature: number().min(0).max(2).optional(),
40027
40132
  /** Nucleus sampling. Every wire we speak has it. */
40028
40133
  topP: number().min(0).max(1).optional(),
40029
- /** Top-k sampling. Carried only by the wires that have it — NEITHER OpenAI
40030
- * wire does, and the client drops it there (measured: the request body gets
40031
- * `top_p` and no `top_k`). The profile editor hides the field wherever it
40032
- * would change nothing; `KINDS_WITH_TOP_K` is the single owner of that list. */
40134
+ /** Top-k sampling. Carried only by the wires that have it — a kind offers the
40135
+ * field in its editor only when its descriptor lists it in `profileFields`. */
40033
40136
  topK: number().int().positive().optional(),
40034
40137
  maxTokens: number().int().positive().optional(),
40035
- /** Prompt context window. Advisory for cloud kinds (they enforce their own);
40036
- * for `managed-local` it is the llama.cpp `--ctx-size` the runtime starts
40037
- * the model with, so it is the one field that changes a PROCESS. */
40138
+ /** Prompt context window. Advisory for cloud kinds (they enforce their own). */
40038
40139
  contextLength: number().int().positive().optional(),
40039
40140
  /** Default system prompt. A caller's `system` REPLACES it (never appends —
40040
40141
  * two system prompts fighting is worse than either alone). */
@@ -40060,16 +40161,37 @@ var LlmProfileSchema = object({
40060
40161
  * library; the REGISTRY of callable tools is ours and is empty in v1, so a
40061
40162
  * `true` here buys the wiring, not behaviour, until tools are registered. */
40062
40163
  toolsEnabled: boolean().default(false),
40063
- extraHeaders: record(string(), string()).optional(),
40064
- /** kind === 'managed-local' only (spec §4). */
40065
- runtime: ManagedRuntimeConfigSchema.optional(),
40066
- /**
40067
- * kind === 'apple-foundation' only: WHERE it runs — the only thing there is
40068
- * to configure (no key, no URL, no download; `model` is `apple-system`).
40069
- * `supportsVision` on such a row is stamped by the provider from the node's
40070
- * reported `imageInput`, never taken from the operator (D62).
40071
- */
40072
- appleFoundation: object({ nodeId: string() }).optional()
40164
+ /** Everything the kind's provider owns (endpoint, key, node, runtime…). */
40165
+ providerConfig: LlmProviderConfigSchema.default({})
40166
+ });
40167
+ /**
40168
+ * The common profile fields a kind's editor offers. The editor owns how each
40169
+ * one is drawn; the provider says which of them mean something on its wire.
40170
+ */
40171
+ var LlmProfileFieldSchema = _enum([
40172
+ "temperature",
40173
+ "topP",
40174
+ "topK",
40175
+ "maxTokens",
40176
+ "contextLength",
40177
+ "systemPrompt",
40178
+ "timeoutMs",
40179
+ "connectTimeoutMs",
40180
+ "firstTokenTimeoutMs",
40181
+ "idleTimeoutMs",
40182
+ "retry",
40183
+ "toolsEnabled"
40184
+ ]);
40185
+ /**
40186
+ * A provider-drawn part of the editor, by a generic widget id the admin UI
40187
+ * registers (`ai/apple-node`). `placement: 'model'` replaces the generic model
40188
+ * picker: that widget owns the model choice.
40189
+ */
40190
+ var LlmProviderWidgetSchema = object({
40191
+ id: string(),
40192
+ placement: _enum(["connection", "model"]),
40193
+ /** `providerConfig` keys this widget must fill before the profile can be saved. */
40194
+ requires: array(string()).optional()
40073
40195
  });
40074
40196
  /** ConfigUISchema tree passed through untyped on the wire (the
40075
40197
  * notification-output `ConfigSchemaPassthrough` precedent at
@@ -40078,11 +40200,56 @@ var ConfigSchemaPassthrough$3 = unknown();
40078
40200
  var LlmProfileKindDescriptorSchema = object({
40079
40201
  kind: LlmProfileKindSchema,
40080
40202
  label: string(),
40203
+ /** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
40081
40204
  icon: string(),
40082
40205
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
40083
40206
  addonId: string(),
40084
- configSchema: ConfigSchemaPassthrough$3
40207
+ /** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
40208
+ connectionSchema: ConfigSchemaPassthrough$3,
40209
+ /** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
40210
+ advancedSchema: ConfigSchemaPassthrough$3.optional(),
40211
+ /** The kind's defaults; a model from `listModels` may override any of them. */
40212
+ features: LlmModelFeaturesSchema,
40213
+ /** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
40214
+ visionEditable: boolean(),
40215
+ /** Where the model list comes from: `listModels`, `staticModels`, or nowhere. */
40216
+ modelCatalog: _enum([
40217
+ "fetch",
40218
+ "static",
40219
+ "none"
40220
+ ]),
40221
+ staticModels: array(LlmModelInfoSchema).optional(),
40222
+ /** The common fields that mean something on this kind's wire. */
40223
+ profileFields: array(LlmProfileFieldSchema),
40224
+ providerWidgets: array(LlmProviderWidgetSchema).optional()
40085
40225
  });
40226
+ /**
40227
+ * `listModels` input. `connection` is an UNSAVED draft of `providerConfig`
40228
+ * (the editor's form); with `profileId` too, a secret the draft leaves
40229
+ * untouched (absent or the redaction marker) is resolved server-side from the
40230
+ * stored profile — the browser never receives it.
40231
+ */
40232
+ var LlmListModelsInputSchema = object({
40233
+ addonId: string(),
40234
+ kind: LlmProfileKindSchema,
40235
+ profileId: string().optional(),
40236
+ connection: LlmProviderConfigSchema.optional()
40237
+ });
40238
+ var LlmListModelsErrorCodeSchema = _enum([
40239
+ "auth",
40240
+ "network",
40241
+ "unsupported",
40242
+ "invalid"
40243
+ ]);
40244
+ /** A RESULT, never a throw: "wrong key" is an answer the editor renders inline. */
40245
+ var LlmListModelsResultSchema = discriminatedUnion("ok", [object({
40246
+ ok: literal(true),
40247
+ models: array(LlmModelInfoSchema)
40248
+ }), object({
40249
+ ok: literal(false),
40250
+ code: LlmListModelsErrorCodeSchema,
40251
+ message: string()
40252
+ })]);
40086
40253
  var LlmDefaultSelectorSchema = union([object({ consumer: string() }), object({ purpose: _enum(["text", "vision"]) })]);
40087
40254
  var LlmDefaultSchema = object({
40088
40255
  selector: LlmDefaultSelectorSchema,
@@ -40182,7 +40349,10 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
40182
40349
  kind: "mutation",
40183
40350
  auth: "admin",
40184
40351
  timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
40185
- }), method(ProfileRefInputSchema, array(string())), method(object({}), array(LlmDefaultSchema)), method(object({
40352
+ }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
40353
+ kind: "mutation",
40354
+ auth: "admin"
40355
+ }), method(object({}), array(LlmDefaultSchema)), method(object({
40186
40356
  selector: LlmDefaultSelectorSchema,
40187
40357
  profileId: string().nullable()
40188
40358
  }), _void(), {
@@ -40350,14 +40520,106 @@ var LogEntrySchema = object({
40350
40520
  meta: record(string(), unknown()).optional(),
40351
40521
  tags: record(string(), string()).optional()
40352
40522
  });
40353
- method(LogEntrySchema, _void(), { kind: "mutation" }), method(object({
40354
- scope: array(string()).optional(),
40523
+ /**
40524
+ * A history READ against one destination (D898).
40525
+ *
40526
+ * Every filter is applied by the PROVIDER, before the limit — a filter the
40527
+ * browser applied after the limit is what made a rare device's lines
40528
+ * unreachable behind a busy one's. `before` / `after` are cursors the provider
40529
+ * minted (opaque to everyone else): a file position for the rotated files, a
40530
+ * nanosecond timestamp for Loki.
40531
+ *
40532
+ * A read is BOUNDED by `budgetMs`: a filter that matches nothing on a 30-day
40533
+ * store answers `done: false` with the cursor it reached and the bytes it
40534
+ * scanned, and the caller decides whether to go on. That is what makes a long
40535
+ * scan show progress and stop when asked — `cancelRead` ends the slice in
40536
+ * flight, and not asking for the next slice ends the scan.
40537
+ */
40538
+ var LogReadQuerySchema = object({
40539
+ /** Correlates `cancelRead`. Caller-chosen, unique per in-flight read. */
40540
+ requestId: string().min(1).max(64).optional(),
40541
+ /** The device the line is about (`tags.deviceId`, numeric). */
40542
+ deviceId: number().int().optional(),
40543
+ /**
40544
+ * The emitting addon — bare manifest id; `@<version>` / `::<sub>` suffixes
40545
+ * match. Not `addonId`: a cap router reads that name as "which provider".
40546
+ */
40547
+ fromAddonId: string().min(1).max(200).optional(),
40548
+ /**
40549
+ * The emitting node: matches the agent that emitted the line, the node
40550
+ * itself, or a worker under it (`<agent>/<runner>`) — the `agentId`
40551
+ * semantics of `matchesLogTags`. Not `nodeId`: a cap router reads that
40552
+ * name as "which node's provider".
40553
+ */
40554
+ fromNodeId: string().min(1).max(200).optional(),
40555
+ /** Any other tag, exact match (AND). */
40556
+ tags: record(string(), union([string(), number()])).optional(),
40557
+ /** Severity FLOOR: this level and above. */
40355
40558
  level: LogLevelSchema.optional(),
40356
- since: date().optional(),
40357
- until: date().optional(),
40358
- limit: number().optional(),
40359
- tags: record(string(), string()).optional()
40360
- }), array(LogEntrySchema).readonly());
40559
+ /** Case-insensitive substring over message, scope, tag values and meta values. */
40560
+ text: string().min(1).max(200).optional(),
40561
+ /** Epoch ms, inclusive. */
40562
+ since: number().optional(),
40563
+ /** Epoch ms, inclusive. */
40564
+ until: number().optional(),
40565
+ /** Older than this cursor (exclusive). Absent with `after` absent ⇒ from the newest. */
40566
+ before: string().min(1).max(1024).optional(),
40567
+ /** Newer than this cursor (exclusive). */
40568
+ after: string().min(1).max(1024).optional(),
40569
+ limit: number().int().min(1).max(1e3).optional(),
40570
+ /** Wall-clock bound of this slice. The provider caps it. */
40571
+ budgetMs: number().int().min(50).max(1e4).optional()
40572
+ });
40573
+ var LogReadResultSchema = object({
40574
+ /** Newest first. */
40575
+ entries: array(object({
40576
+ /** `<bootId>.<seq>` minted by the emitting LogManager — the dedupe key. */
40577
+ id: string().optional(),
40578
+ /** Epoch ms. */
40579
+ timestamp: number(),
40580
+ level: LogLevelSchema,
40581
+ scope: string().optional(),
40582
+ message: string(),
40583
+ tags: record(string(), union([string(), number()])).optional(),
40584
+ meta: record(string(), unknown()).optional()
40585
+ })),
40586
+ /** Pass as `before` for the next older page; null when nothing older exists. */
40587
+ nextBefore: string().nullable(),
40588
+ /** Pass as `after` to read what arrived since; null when unknown. */
40589
+ nextAfter: string().nullable(),
40590
+ /** Bytes this slice read (files) or received (remote). Progress, not a promise. */
40591
+ scannedBytes: number().int().nonnegative(),
40592
+ /**
40593
+ * True when the scan in this direction reached the end of the store.
40594
+ * False with fewer than `limit` entries means the budget ran out first —
40595
+ * call again with `nextBefore` to go on.
40596
+ */
40597
+ done: boolean(),
40598
+ /** True when `cancelRead` ended this slice early. */
40599
+ cancelled: boolean().optional()
40600
+ });
40601
+ var LogReadCapabilitiesSchema = object({
40602
+ /** False ⇒ this destination only ships lines (console, forwarder, an unconfigured Loki). */
40603
+ readable: boolean(),
40604
+ /** Why not, when `readable` is false — rendered next to the source. */
40605
+ reason: string().nullable(),
40606
+ /** Filters the provider applies itself. A false one is applied by nobody. */
40607
+ filters: object({
40608
+ deviceId: boolean(),
40609
+ addonId: boolean(),
40610
+ nodeId: boolean(),
40611
+ tags: boolean(),
40612
+ level: boolean(),
40613
+ text: boolean(),
40614
+ timeRange: boolean()
40615
+ }),
40616
+ /** How far back the store reaches, when the provider knows (days). */
40617
+ retentionDays: number().nullable()
40618
+ });
40619
+ 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() }), {
40620
+ kind: "mutation",
40621
+ auth: "admin"
40622
+ });
40361
40623
  /**
40362
40624
  * `login-method` — collection cap through which auth addons contribute
40363
40625
  * their pre-auth login surfaces to the login page. This is the SINGLE,
@@ -42075,9 +42337,11 @@ var alarmPanelCapability = {
42075
42337
  */
42076
42338
  durability: "restored",
42077
42339
  /**
42078
- * History (D850): none — enum state; arm/disarm history belongs in the events ledger.
42340
+ * History (D850): the panel's lifecycle state as an `enum` series —
42341
+ * change-only, no floor, so an `arming -> pending -> triggered` sequence of a
42342
+ * few seconds keeps every step. Who armed it stays in the events ledger.
42079
42343
  */
42080
- history: "none",
42344
+ history: { fields: { state: { kind: "enum" } } },
42081
42345
  /** Clock fields: written, but excluded from the compare that decides
42082
42346
  * whether persisting is worth a SQLite commit. */
42083
42347
  volatileStateFields: ["lastChangedAt"]
@@ -42955,6 +43219,33 @@ var NcRuleTargetSchema = object({
42955
43219
  params: record(string(), unknown()).optional()
42956
43220
  });
42957
43221
  /**
43222
+ * WHAT THE NOTIFICATION'S PICTURE IS (D897) — the ONE media choice of a rule.
43223
+ *
43224
+ * Every mode starts from the same CLEAN source frame of the trigger moment
43225
+ * (keyFrame → sceneFrame → lastSceneFrame, narrowed to the trigger instant and
43226
+ * to the zone that fired the rule) and renders it once at send time:
43227
+ * - `scene-boxes` — the whole scene, the subject outlined thick in the accent
43228
+ * colour and every OTHER track visible at that instant outlined thin, each
43229
+ * labelled with class and confidence ("dog 87%").
43230
+ * - `crop` — the subject cut out of that frame around its box at that instant.
43231
+ * - `clean` — the whole scene with nothing drawn on it.
43232
+ * - `none` — no picture.
43233
+ *
43234
+ * A mode that cannot be honoured (no box at that instant, a photograph with no
43235
+ * tracked subject) ships `clean` and names the reason in the log, per camera.
43236
+ * It replaces the `attach` × `frame` × `zoneCrop` triple, which let one rule
43237
+ * ship a crop on one event and a boxed scene on the next depending on which
43238
+ * stored kind had landed.
43239
+ */
43240
+ var NcMediaImageSchema = _enum([
43241
+ "scene-boxes",
43242
+ "crop",
43243
+ "clean",
43244
+ "none"
43245
+ ]);
43246
+ /**
43247
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43248
+ *
42958
43249
  * Media attachment policy (P1 still-image subset).
42959
43250
  * - `best` — the best AVAILABLE subject image at dispatch time (D-3).
42960
43251
  * - `best-matching` — the media that explains WHY the rule fired: a rule
@@ -42968,6 +43259,8 @@ var NcRuleTargetSchema = object({
42968
43259
  * - `none` — no attachment.
42969
43260
  */
42970
43261
  /**
43262
+ * @deprecated Read only by `normalizeNcMediaPolicy` (D897) — see {@link NcMediaImageSchema}.
43263
+ *
42971
43264
  * WHAT THE PICTURE SHOWS — chosen explicitly, because the implicit ladders
42972
43265
  * conflate it with the selection strategy and betray the request: asking for
42973
43266
  * the clean scene frame on an object-event owner used to start at
@@ -42996,16 +43289,29 @@ var NcMediaFrameSchema = _enum([
42996
43289
  */
42997
43290
  var NcLinkedCameraModeSchema = _enum(["mosaic", "each"]);
42998
43291
  var NcMediaPolicySchema = object({
43292
+ /**
43293
+ * The picture — see {@link NcMediaImageSchema}. Absent on a rule nobody has
43294
+ * saved since D897: `normalizeNcMediaPolicy` derives it from the legacy
43295
+ * triple below, at load and at every write, and the store keeps only this.
43296
+ */
43297
+ image: NcMediaImageSchema.optional(),
43298
+ /**
43299
+ * Draw the zone that FIRED the rule on the picture (`scene-boxes` / `clean`;
43300
+ * a `crop` never shows it). Valid only on a rule whose trigger is a zone —
43301
+ * `conditions.zones` or an occupancy zone — and refused on save otherwise.
43302
+ * Replaces `zoneCrop`.
43303
+ */
43304
+ showTriggerZone: boolean().optional(),
43305
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
42999
43306
  attach: _enum([
43000
43307
  "best",
43001
43308
  "best-matching",
43002
43309
  "keyFrame",
43003
43310
  "none"
43004
- ]).default("best"),
43005
- /** What the still shows. Absent = `cropped` (the historical `best` shape). */
43311
+ ]).optional(),
43312
+ /** @deprecated D897 — accepted from an editor that predates `image`, folded into it on save. */
43006
43313
  frame: NcMediaFrameSchema.optional(),
43007
- /** Crop the attached still to the rule's condition-zone bbox (padded) —
43008
- * "show me the ZONE", not the whole scene or the subject crop. */
43314
+ /** @deprecated D897 — folded into `image: 'clean'` + `showTriggerZone` on save. */
43009
43315
  zoneCrop: boolean().optional(),
43010
43316
  /**
43011
43317
  * Also attach a short GIF cut from the stream broker's clip ring around the
@@ -43177,7 +43483,9 @@ var NcRuleInputSchema = object({
43177
43483
  * targets.
43178
43484
  */
43179
43485
  targetUsers: array(string()).optional(),
43180
- media: NcMediaPolicySchema.default({ attach: "best" }),
43486
+ /** Absent = the kind's default picture (`resolveNcMediaImage`): the subject crop for a
43487
+ * detection, the clean scene for a sensor or a sound. Set explicitly on save (D897). */
43488
+ media: NcMediaPolicySchema.default({}),
43181
43489
  throttle: NcThrottleSchema.default({
43182
43490
  cooldownSec: 60,
43183
43491
  scope: "rule-device"
@@ -44114,13 +44422,37 @@ var NcAlarmModeOpeningsSchema = object({
44114
44422
  /** Covered devices whose state could not be read (D49): neither open nor closed. */
44115
44423
  unknown: array(number().int())
44116
44424
  });
44425
+ /**
44426
+ * One alarm INPUT — a (rule, device) pair — the operator bypassed until the
44427
+ * next disarm ("Bypass this input until disarm" on a trigger notification, or
44428
+ * `nc.bypassAlarmInput`). Reported so an armed alarm with a silenced input
44429
+ * never looks fully armed (D62: off must never look like broken).
44430
+ */
44431
+ var NcAlarmInputBypassViewSchema = object({
44432
+ ruleId: string(),
44433
+ /** The rule's current name (its frozen name when the rule is gone). */
44434
+ ruleName: string(),
44435
+ /** The input: the sensor of the match, else its camera. */
44436
+ deviceId: number().int(),
44437
+ /** The input's current name. */
44438
+ name: string(),
44439
+ /** When it was bypassed (ms epoch). */
44440
+ since: number(),
44441
+ /** Triggers from this input dropped since. */
44442
+ dropped: number().int().min(0)
44443
+ });
44117
44444
  var NcAlarmLiveSchema = object({
44118
44445
  state: AlarmStateSchema,
44119
44446
  /** The mode being armed into (exit delay) or held; null when disarmed. */
44120
44447
  targetMode: AlarmArmModeSchema.nullable(),
44121
44448
  availableModes: array(AlarmArmModeSchema),
44122
44449
  openings: array(NcAlarmModeOpeningsSchema),
44123
- exclusions: array(NcAlarmExclusionViewSchema)
44450
+ exclusions: array(NcAlarmExclusionViewSchema),
44451
+ /**
44452
+ * Inputs bypassed for the rest of this arm session; cleared on disarm.
44453
+ * Defaulted so an older hub answer still parses (as "none known").
44454
+ */
44455
+ bypassedInputs: array(NcAlarmInputBypassViewSchema).default([])
44124
44456
  });
44125
44457
  var NcAlarmConfigSchema = object({
44126
44458
  /**
@@ -54951,9 +55283,11 @@ var connectivityCapability = {
54951
55283
  */
54952
55284
  durability: "restored",
54953
55285
  /**
54954
- * History (D850): none — duplicates device-status.online (one authority for availability).
55286
+ * History (D850): `connected` as a boolean series — change-only, no floor. It
55287
+ * is the upstream entity's own link (a HA connectivity sensor), not the
55288
+ * device's reachability, which stays `device-status.online`.
54955
55289
  */
54956
- history: "none",
55290
+ history: { fields: { connected: { kind: "boolean" } } },
54957
55291
  /** Clock fields: written, but excluded from the compare that decides
54958
55292
  * whether persisting is worth a SQLite commit. */
54959
55293
  volatileStateFields: ["lastChangedAt"]
@@ -55777,11 +56111,22 @@ var dishwasherCapability = {
55777
56111
  },
55778
56112
  runtimeState: DishwasherStatusSchema,
55779
56113
  durability: "session",
55780
- history: { fields: { progressPercent: {
55781
- kind: "gauge",
55782
- unit: "%",
55783
- deadband: 2
55784
- } } }
56114
+ history: { fields: {
56115
+ progressPercent: {
56116
+ kind: "gauge",
56117
+ unit: "%",
56118
+ deadband: 2
56119
+ },
56120
+ state: { kind: "enum" },
56121
+ operationState: { kind: "enum" },
56122
+ remainingSeconds: {
56123
+ kind: "gauge",
56124
+ unit: "s",
56125
+ minIntervalMs: 6e4
56126
+ },
56127
+ doorOpen: { kind: "boolean" },
56128
+ powerOn: { kind: "boolean" }
56129
+ } }
55785
56130
  };
55786
56131
  var DoorbellStatusSchema = object({
55787
56132
  /** Ms epoch of the last press. null = never observed since this provider started. */
@@ -55898,9 +56243,15 @@ var enumSensorCapability = {
55898
56243
  */
55899
56244
  durability: "restored",
55900
56245
  /**
55901
- * History (D850): none — text/enum state has no history (non-goal).
56246
+ * History (D850): the value as an `enum` series (an appliance's program or
56247
+ * operation state, an HVAC action). The option set is per device, so the
56248
+ * value list is LEARNED as values are first seen (bounded). A sensor with a
56249
+ * `format` carries a timestamp, not a state, and is not recorded.
55902
56250
  */
55903
- history: "none",
56251
+ history: { fields: { value: {
56252
+ kind: "enum",
56253
+ skipWhenSet: "format"
56254
+ } } },
55904
56255
  /** Clock fields: written, but excluded from the compare that decides
55905
56256
  * whether persisting is worth a SQLite commit. */
55906
56257
  volatileStateFields: ["lastFetchedAt"]
@@ -57874,9 +58225,10 @@ var lockControlCapability = {
57874
58225
  */
57875
58226
  durability: "restored",
57876
58227
  /**
57877
- * History (D850): none — enum state; lock events belong in the events ledger.
58228
+ * History (D850): the lock's state as an `enum` series — change-only, no
58229
+ * floor: a jam or an unlock lasting seconds is the edge an operator looks for.
57878
58230
  */
57879
- history: "none",
58231
+ history: { fields: { state: { kind: "enum" } } },
57880
58232
  /** Clock fields: written, but excluded from the compare that decides
57881
58233
  * whether persisting is worth a SQLite commit. */
57882
58234
  volatileStateFields: ["lastChangedAt"]
@@ -58050,9 +58402,18 @@ var mediaPlayerCapability = {
58050
58402
  */
58051
58403
  durability: "session",
58052
58404
  /**
58053
- * History (D850): none — `positionMs` moves continuously while playing; volume is transient.
58405
+ * History (D850): volume (a level an operator or an automation sets; the
58406
+ * default 10 s floor folds a slider drag into its end value) and mute.
58407
+ * `positionMs` is not recorded: it moves continuously while playing.
58054
58408
  */
58055
- history: "none"
58409
+ history: { fields: {
58410
+ volumeLevel: {
58411
+ kind: "gauge",
58412
+ unit: "%",
58413
+ deadband: 1
58414
+ },
58415
+ isMuted: { kind: "boolean" }
58416
+ } }
58056
58417
  };
58057
58418
  /**
58058
58419
  * mesh-network — collection cap for mesh-VPN providers.
@@ -63345,9 +63706,29 @@ var streamParamsCapability = {
63345
63706
  */
63346
63707
  durability: "restored",
63347
63708
  /**
63348
- * History (D850): none — encoder configuration.
63709
+ * History (D850): the configured bitrate and frame rate of the main and sub
63710
+ * profiles. Configuration, so change-only on the default floor: a point is an
63711
+ * operator's (or a tuner's) edit, which is exactly what a chart of a stream's
63712
+ * quality over time must show.
63349
63713
  */
63350
- history: "none",
63714
+ history: { fields: {
63715
+ "main.bitrate": {
63716
+ kind: "gauge",
63717
+ unit: "kbps"
63718
+ },
63719
+ "main.framerate": {
63720
+ kind: "gauge",
63721
+ unit: "fps"
63722
+ },
63723
+ "sub.bitrate": {
63724
+ kind: "gauge",
63725
+ unit: "kbps"
63726
+ },
63727
+ "sub.framerate": {
63728
+ kind: "gauge",
63729
+ unit: "fps"
63730
+ }
63731
+ } },
63351
63732
  /** Clock fields: written, but excluded from the compare that decides
63352
63733
  * whether persisting is worth a SQLite commit. */
63353
63734
  volatileStateFields: ["lastFetchedAt"]
@@ -64182,26 +64563,6 @@ var ApiKeySummarySchema = object({
64182
64563
  createdAt: number(),
64183
64564
  lastUsedAt: number().optional()
64184
64565
  });
64185
- var ScopedTokenSummarySchema = object({
64186
- id: string(),
64187
- userId: string(),
64188
- name: string(),
64189
- tokenPrefix: string(),
64190
- scopes: array(TokenScopeSchema),
64191
- expiresAt: number().nullish(),
64192
- lastUsedAt: number().nullish(),
64193
- createdAt: number()
64194
- });
64195
- var CreateScopedTokenInputSchema = object({
64196
- userId: string(),
64197
- name: string(),
64198
- scopes: array(TokenScopeSchema),
64199
- expiresAt: number().optional()
64200
- });
64201
- var CreateScopedTokenResultSchema = object({
64202
- token: string(),
64203
- record: ScopedTokenSummarySchema
64204
- });
64205
64566
  var OauthSessionSummarySchema = object({
64206
64567
  id: string(),
64207
64568
  userId: string(),
@@ -64223,11 +64584,11 @@ var TotpStatusSchema = object({
64223
64584
  confirmedAt: number().nullable()
64224
64585
  });
64225
64586
  /**
64226
- * user-management — singleton capability for user accounts, API keys,
64227
- * and scoped tokens.
64587
+ * user-management — singleton capability for user accounts and the
64588
+ * legacy API-key rows.
64228
64589
  *
64229
64590
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
64230
- * — the subset check on `setUserScopes` / `createScopedToken` is moot
64591
+ * — the subset check on `setUserScopes` is moot
64231
64592
  * because non-admins never reach these. If/when we open non-admin
64232
64593
  * delegation, structural caller-scope subset check goes inside the
64233
64594
  * provider.
@@ -64284,15 +64645,7 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
64284
64645
  kind: "mutation",
64285
64646
  auth: "admin",
64286
64647
  access: "delete"
64287
- }), method(CreateScopedTokenInputSchema, CreateScopedTokenResultSchema, {
64288
- kind: "mutation",
64289
- auth: "admin",
64290
- access: "create"
64291
- }), method(object({ id: string() }), object({ success: literal(true) }), {
64292
- kind: "mutation",
64293
- auth: "admin",
64294
- access: "delete"
64295
- }), method(object({ token: string() }), ScopedTokenSummarySchema.nullable(), { access: "view" }), method(object({ userId: string() }), array(ScopedTokenSummarySchema), { auth: "admin" }), method(object({ userId: string() }), TotpSetupResultSchema, {
64648
+ }), method(object({ userId: string() }), TotpSetupResultSchema, {
64296
64649
  kind: "mutation",
64297
64650
  auth: "admin",
64298
64651
  access: "create"
@@ -66553,6 +66906,15 @@ var BaseDevice = class {
66553
66906
  * Drivers can use the `getProbeFlags()` helper to read the flag bag
66554
66907
  * with a typed cast.
66555
66908
  *
66909
+ * Answer what you KNOW. A plain array is read as the complete list only
66910
+ * while this device is `online` and probed; return
66911
+ * `accessoryChildrenUnknown(reason)` whenever you cannot know the list right
66912
+ * now (no credentials, parent not connected, a failed or partial read) —
66913
+ * the kernel then deletes nothing. Return `accessoryChildrenComplete(list)`
66914
+ * to say "connected, and this is the complete list" explicitly. A shrink is
66915
+ * deleted only after a second agreeing complete read on a later probe (D49;
66916
+ * `packages/system/src/kernel/moleculer/accessory-prune-gate.ts`).
66917
+ *
66556
66918
  * Default: no children.
66557
66919
  */
66558
66920
  getAccessoryChildren() {
@@ -70382,7 +70744,7 @@ Object.freeze({
70382
70744
  capName: "llm",
70383
70745
  capScope: "system",
70384
70746
  addonId: null,
70385
- access: "view"
70747
+ access: "create"
70386
70748
  },
70387
70749
  "llm.listNodeModels": {
70388
70750
  capName: "llm",
@@ -70684,7 +71046,19 @@ Object.freeze({
70684
71046
  addonId: null,
70685
71047
  access: "view"
70686
71048
  },
70687
- "logDestination.query": {
71049
+ "logDestination.cancelRead": {
71050
+ capName: "log-destination",
71051
+ capScope: "system",
71052
+ addonId: null,
71053
+ access: "create"
71054
+ },
71055
+ "logDestination.describeRead": {
71056
+ capName: "log-destination",
71057
+ capScope: "system",
71058
+ addonId: null,
71059
+ access: "view"
71060
+ },
71061
+ "logDestination.read": {
70688
71062
  capName: "log-destination",
70689
71063
  capScope: "system",
70690
71064
  addonId: null,
@@ -75046,12 +75420,6 @@ Object.freeze({
75046
75420
  addonId: null,
75047
75421
  access: "create"
75048
75422
  },
75049
- "userManagement.createScopedToken": {
75050
- capName: "user-management",
75051
- capScope: "system",
75052
- addonId: null,
75053
- access: "create"
75054
- },
75055
75423
  "userManagement.createUser": {
75056
75424
  capName: "user-management",
75057
75425
  capScope: "system",
@@ -75100,12 +75468,6 @@ Object.freeze({
75100
75468
  addonId: null,
75101
75469
  access: "view"
75102
75470
  },
75103
- "userManagement.listScopedTokens": {
75104
- capName: "user-management",
75105
- capScope: "system",
75106
- addonId: null,
75107
- access: "view"
75108
- },
75109
75471
  "userManagement.listUsers": {
75110
75472
  capName: "user-management",
75111
75473
  capScope: "system",
@@ -75160,12 +75522,6 @@ Object.freeze({
75160
75522
  addonId: null,
75161
75523
  access: "delete"
75162
75524
  },
75163
- "userManagement.revokeScopedToken": {
75164
- capName: "user-management",
75165
- capScope: "system",
75166
- addonId: null,
75167
- access: "delete"
75168
- },
75169
75525
  "userManagement.setupTotp": {
75170
75526
  capName: "user-management",
75171
75527
  capScope: "system",
@@ -75196,12 +75552,6 @@ Object.freeze({
75196
75552
  addonId: null,
75197
75553
  access: "view"
75198
75554
  },
75199
- "userManagement.validateScopedToken": {
75200
- capName: "user-management",
75201
- capScope: "system",
75202
- addonId: null,
75203
- access: "view"
75204
- },
75205
75555
  "userManagement.verifyTotp": {
75206
75556
  capName: "user-management",
75207
75557
  capScope: "system",
@@ -76781,6 +77131,11 @@ Object.freeze({
76781
77131
  form: "single",
76782
77132
  optional: false
76783
77133
  }],
77134
+ "logDestination.read": [{
77135
+ name: "deviceId",
77136
+ form: "single",
77137
+ optional: true
77138
+ }],
76784
77139
  "mediaPlayer.getStatus": [{
76785
77140
  name: "deviceId",
76786
77141
  form: "single",