@camstack/addon-ai 0.4.72 → 0.4.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/addon.js CHANGED
@@ -27112,6 +27112,203 @@ DeviceType.Camera, method(object({ deviceId: number$1() }), PtzAutotrackStatusSc
27112
27112
  deviceId: number$1(),
27113
27113
  status: PtzAutotrackStatusSchema
27114
27114
  });
27115
+ /**
27116
+ * `navigation` — a device-scoped capability that natively expresses the FULL
27117
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
27118
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
27119
+ *
27120
+ * Why a NEW cap rather than overloading `ptz`:
27121
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
27122
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
27123
+ * The two are different physical models: PTZ is absolute-position + presets,
27124
+ * navigation is momentary drive nudges + discrete robot ACTIONS
27125
+ * (dock / spot-clean / follow-pet / go-to-point / …).
27126
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
27127
+ * the reverse:
27128
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
27129
+ * / `getOptions`), and
27130
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
27131
+ * robot camera shows up in the existing PTZ control path without every
27132
+ * PTZ provider learning about robots. The mapping lives in the adapter,
27133
+ * not here (see the addon design note):
27134
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
27135
+ * ptz.stop() → navigation.stop()
27136
+ * ptz.goHome() → navigation.runAction('goHome')
27137
+ * ptz.getPresets() → navigation.listActions() (id→preset)
27138
+ * ptz.goToPreset(id) → navigation.runAction(id)
27139
+ *
27140
+ * ## Continuous drive
27141
+ *
27142
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
27143
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
27144
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
27145
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
27146
+ * coalesce them. The UI owns the cadence.
27147
+ *
27148
+ * ## The action dictionary
27149
+ *
27150
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
27151
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
27152
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
27153
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
27154
+ * vendor-specific list. `kind: 'action'` entries are triggered with
27155
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
27156
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
27157
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
27158
+ *
27159
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
27160
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
27161
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
27162
+ * every device handle. A future nodedreame publish adds a typed
27163
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
27164
+ * provider can then swap the raw calls for the typed methods with no change to
27165
+ * THIS contract.
27166
+ */
27167
+ /**
27168
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
27169
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
27170
+ * halts it.
27171
+ *
27172
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
27173
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
27174
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
27175
+ * vector by it (drivers without proportional drive ignore it).
27176
+ *
27177
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
27178
+ * axis alone; an all-undefined nudge is a no-op.
27179
+ */
27180
+ var NavigationMoveCommandSchema = object({
27181
+ pan: number$1().min(-1).max(1).optional(),
27182
+ tilt: number$1().min(-1).max(1).optional(),
27183
+ speed: number$1().min(0).max(1).optional()
27184
+ });
27185
+ /**
27186
+ * The enumerated discrete actions a navigation-capable robot can perform via
27187
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
27188
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
27189
+ * `playSound` (see the `sound` dictionary entries).
27190
+ */
27191
+ var NavigationActionIdSchema = _enum([
27192
+ "goHome",
27193
+ "locate",
27194
+ "spotClean",
27195
+ "findPet",
27196
+ "personFollow",
27197
+ "stop",
27198
+ "startClean",
27199
+ "pauseClean",
27200
+ "dockWash",
27201
+ "autoEmpty",
27202
+ "flashOn",
27203
+ "flashOff"
27204
+ ]);
27205
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
27206
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
27207
+ /**
27208
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
27209
+ * native panel and the PTZ mimic render as a button.
27210
+ *
27211
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
27212
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
27213
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
27214
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
27215
+ * - `label` — operator-facing English label.
27216
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
27217
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
27218
+ * PTZ render ONLY enabled entries. Data-driven: the provider
27219
+ * flips it from config, never by editing code.
27220
+ */
27221
+ var NavigationActionEntrySchema = object({
27222
+ id: string(),
27223
+ kind: NavigationEntryKindSchema,
27224
+ label: string(),
27225
+ icon: string(),
27226
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
27227
+ soundId: number$1().int().optional(),
27228
+ /** Per-device feature flag — render this entry only when true. */
27229
+ enabled: boolean()
27230
+ });
27231
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
27232
+ var NavigationPointSchema = object({
27233
+ x: number$1(),
27234
+ y: number$1()
27235
+ });
27236
+ /**
27237
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
27238
+ * The cap reports which are enabled so the UI / PTZ render only the controls
27239
+ * that are turned on for THIS device. Data-driven: the provider derives these
27240
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
27241
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
27242
+ * that are not dictionary entries.
27243
+ *
27244
+ * - `move` / `stop` — the momentary drive joystick.
27245
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
27246
+ * map-coordinate plumbing is wired.
27247
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
27248
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
27249
+ * - `light` — the on/off fill-light toggle (works anytime).
27250
+ * - `lightMode` — the auto/manual selector + manual level slider (a
27251
+ * camera-service control; needs an active stream).
27252
+ */
27253
+ var NavigationFeaturesSchema = object({
27254
+ move: boolean(),
27255
+ stop: boolean(),
27256
+ goToPoint: boolean(),
27257
+ runAction: boolean(),
27258
+ playSound: boolean(),
27259
+ light: boolean(),
27260
+ lightMode: boolean()
27261
+ });
27262
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
27263
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
27264
+ /**
27265
+ * Live navigation state so the UI can reflect what the robot is doing:
27266
+ * - `mode` — coarse activity (idle / cleaning / following / …).
27267
+ * - `following` — person/pet follow is currently armed.
27268
+ * - `flash` — the on-camera fill light is on.
27269
+ * - `lightMode` — auto vs manual fill-light mode.
27270
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
27271
+ * `lightMode === 'manual'`.
27272
+ */
27273
+ var NavigationStatusSchema = object({
27274
+ mode: _enum([
27275
+ "idle",
27276
+ "cleaning",
27277
+ "spot",
27278
+ "following",
27279
+ "goto",
27280
+ "returning",
27281
+ "paused",
27282
+ "unknown"
27283
+ ]),
27284
+ following: boolean(),
27285
+ flash: boolean(),
27286
+ lightMode: NavigationLightModeSchema,
27287
+ lightLevel: number$1().min(40).max(100),
27288
+ /** Ms epoch when the slice was last updated. */
27289
+ lastChangedAt: number$1()
27290
+ });
27291
+ NavigationStatusSchema.extend({ lastFetchedAt: number$1() });
27292
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), array(NavigationActionEntrySchema)), method(object({
27293
+ deviceId: number$1(),
27294
+ actionId: NavigationActionIdSchema
27295
+ }), _void(), { kind: "mutation" }), method(object({
27296
+ deviceId: number$1(),
27297
+ soundId: number$1().int()
27298
+ }), _void(), { kind: "mutation" }), method(object({
27299
+ deviceId: number$1(),
27300
+ on: boolean()
27301
+ }), _void(), { kind: "mutation" }), method(object({
27302
+ deviceId: number$1(),
27303
+ mode: NavigationLightModeSchema,
27304
+ level: number$1().min(40).max(100).optional()
27305
+ }), _void(), { kind: "mutation" }), method(object({
27306
+ deviceId: number$1(),
27307
+ level: number$1().min(40).max(100)
27308
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), NavigationFeaturesSchema), object({
27309
+ deviceId: number$1(),
27310
+ status: NavigationStatusSchema
27311
+ });
27115
27312
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number$1().int().nonnegative() }), object({ success: literal(true) }), {
27116
27313
  kind: "mutation",
27117
27314
  auth: "admin"
@@ -32176,6 +32373,66 @@ Object.freeze({
32176
32373
  addonId: null,
32177
32374
  access: "create"
32178
32375
  },
32376
+ "navigation.getFeatures": {
32377
+ capName: "navigation",
32378
+ capScope: "device",
32379
+ addonId: null,
32380
+ access: "view"
32381
+ },
32382
+ "navigation.goToPoint": {
32383
+ capName: "navigation",
32384
+ capScope: "device",
32385
+ addonId: null,
32386
+ access: "create"
32387
+ },
32388
+ "navigation.listActions": {
32389
+ capName: "navigation",
32390
+ capScope: "device",
32391
+ addonId: null,
32392
+ access: "view"
32393
+ },
32394
+ "navigation.move": {
32395
+ capName: "navigation",
32396
+ capScope: "device",
32397
+ addonId: null,
32398
+ access: "create"
32399
+ },
32400
+ "navigation.playSound": {
32401
+ capName: "navigation",
32402
+ capScope: "device",
32403
+ addonId: null,
32404
+ access: "create"
32405
+ },
32406
+ "navigation.runAction": {
32407
+ capName: "navigation",
32408
+ capScope: "device",
32409
+ addonId: null,
32410
+ access: "create"
32411
+ },
32412
+ "navigation.setLightLevel": {
32413
+ capName: "navigation",
32414
+ capScope: "device",
32415
+ addonId: null,
32416
+ access: "create"
32417
+ },
32418
+ "navigation.setLightMode": {
32419
+ capName: "navigation",
32420
+ capScope: "device",
32421
+ addonId: null,
32422
+ access: "create"
32423
+ },
32424
+ "navigation.setLightOn": {
32425
+ capName: "navigation",
32426
+ capScope: "device",
32427
+ addonId: null,
32428
+ access: "create"
32429
+ },
32430
+ "navigation.stop": {
32431
+ capName: "navigation",
32432
+ capScope: "device",
32433
+ addonId: null,
32434
+ access: "create"
32435
+ },
32179
32436
  "networkAccess.getEndpoint": {
32180
32437
  capName: "network-access",
32181
32438
  capScope: "system",
@@ -36271,6 +36528,56 @@ Object.freeze({
36271
36528
  form: "single",
36272
36529
  optional: false
36273
36530
  }],
36531
+ "navigation.getFeatures": [{
36532
+ name: "deviceId",
36533
+ form: "single",
36534
+ optional: false
36535
+ }],
36536
+ "navigation.goToPoint": [{
36537
+ name: "deviceId",
36538
+ form: "single",
36539
+ optional: false
36540
+ }],
36541
+ "navigation.listActions": [{
36542
+ name: "deviceId",
36543
+ form: "single",
36544
+ optional: false
36545
+ }],
36546
+ "navigation.move": [{
36547
+ name: "deviceId",
36548
+ form: "single",
36549
+ optional: false
36550
+ }],
36551
+ "navigation.playSound": [{
36552
+ name: "deviceId",
36553
+ form: "single",
36554
+ optional: false
36555
+ }],
36556
+ "navigation.runAction": [{
36557
+ name: "deviceId",
36558
+ form: "single",
36559
+ optional: false
36560
+ }],
36561
+ "navigation.setLightLevel": [{
36562
+ name: "deviceId",
36563
+ form: "single",
36564
+ optional: false
36565
+ }],
36566
+ "navigation.setLightMode": [{
36567
+ name: "deviceId",
36568
+ form: "single",
36569
+ optional: false
36570
+ }],
36571
+ "navigation.setLightOn": [{
36572
+ name: "deviceId",
36573
+ form: "single",
36574
+ optional: false
36575
+ }],
36576
+ "navigation.stop": [{
36577
+ name: "deviceId",
36578
+ form: "single",
36579
+ optional: false
36580
+ }],
36274
36581
  "networkQuality.getDeviceStats": [{
36275
36582
  name: "deviceId",
36276
36583
  form: "single",
package/dist/addon.mjs CHANGED
@@ -27139,6 +27139,203 @@ DeviceType.Camera, method(object({ deviceId: number$1() }), PtzAutotrackStatusSc
27139
27139
  deviceId: number$1(),
27140
27140
  status: PtzAutotrackStatusSchema
27141
27141
  });
27142
+ /**
27143
+ * `navigation` — a device-scoped capability that natively expresses the FULL
27144
+ * navigation / action surface of a robot that DRIVES ITSELF and carries an
27145
+ * on-board camera (the Dreame robot-vacuum camera is the first provider).
27146
+ *
27147
+ * Why a NEW cap rather than overloading `ptz`:
27148
+ * - `ptz` moves a *gimbal* on a fixed camera (pan/tilt/zoom of the lens). A
27149
+ * robot vacuum has no gimbal — the whole chassis drives, turns and spins.
27150
+ * The two are different physical models: PTZ is absolute-position + presets,
27151
+ * navigation is momentary drive nudges + discrete robot ACTIONS
27152
+ * (dock / spot-clean / follow-pet / go-to-point / …).
27153
+ * - This cap is the SOURCE OF TRUTH. Two consumers adapt from it rather than
27154
+ * the reverse:
27155
+ * 1. a native CamStack navigation panel (data-driven from `listActions`
27156
+ * / `getOptions`), and
27157
+ * 2. the PTZ surface — a thin adapter mimics `ptz` from `navigation` so a
27158
+ * robot camera shows up in the existing PTZ control path without every
27159
+ * PTZ provider learning about robots. The mapping lives in the adapter,
27160
+ * not here (see the addon design note):
27161
+ * ptz.continuousMove({pan,tilt}) → navigation.move({pan,tilt})
27162
+ * ptz.stop() → navigation.stop()
27163
+ * ptz.goHome() → navigation.runAction('goHome')
27164
+ * ptz.getPresets() → navigation.listActions() (id→preset)
27165
+ * ptz.goToPreset(id) → navigation.runAction(id)
27166
+ *
27167
+ * ## Continuous drive
27168
+ *
27169
+ * `move` is MOMENTARY. Fluid navigation comes from the UI (or the PTZ adapter)
27170
+ * sending `move({pan,tilt})` REPEATEDLY at ~1 Hz while a direction is held, and
27171
+ * one `stop()` on release — exactly like the robot app's remote-drive joystick.
27172
+ * The provider forwards EACH `move` to one drive write; it must NOT debounce or
27173
+ * coalesce them. The UI owns the cadence.
27174
+ *
27175
+ * ## The action dictionary
27176
+ *
27177
+ * The discrete controls (dock / locate / spot-clean / follow / flash / sounds)
27178
+ * are a DATA-DRIVEN dictionary the cap exposes via `listActions()`. Each entry
27179
+ * carries `{ id, kind, label, icon }` (plus `soundId` for sound entries) so the
27180
+ * native panel AND the PTZ mimic render buttons WITHOUT hardcoding a
27181
+ * vendor-specific list. `kind: 'action'` entries are triggered with
27182
+ * `runAction({ actionId })`; `kind: 'sound'` entries with `playSound({ soundId })`
27183
+ * (the entry carries the `soundId` to pass). The general primitives — `move`,
27184
+ * `stop`, `goToPoint` — stay as first-class methods, not dictionary entries.
27185
+ *
27186
+ * NOTE (provider wiring): the first provider (Dreame) drives this with the RAW
27187
+ * `callAction(siid,aiid,in)` / `setProperty({siid,piid,value})` MIoT primitives
27188
+ * that the currently-published `@apocaliss92/nodedreame` already exposes on
27189
+ * every device handle. A future nodedreame publish adds a typed
27190
+ * `DreameCameraController` (drive / playPetSound / spotClean / findPet / …); the
27191
+ * provider can then swap the raw calls for the typed methods with no change to
27192
+ * THIS contract.
27193
+ */
27194
+ /**
27195
+ * A momentary drive nudge. The robot MOVES (no gimbal) for as long as the caller
27196
+ * keeps sending nudges (~1 Hz); an explicit `stop` (or letting the nudges lapse)
27197
+ * halts it.
27198
+ *
27199
+ * - `pan` — turn: negative = left, positive = right, 0 = straight.
27200
+ * - `tilt` — throttle: positive = forward, negative = spin / turn-around.
27201
+ * - `speed` — optional intensity hint [0, 1]; the provider may scale the drive
27202
+ * vector by it (drivers without proportional drive ignore it).
27203
+ *
27204
+ * `pan` / `tilt` are normalized [-1, 1]. Both optional so a caller can nudge one
27205
+ * axis alone; an all-undefined nudge is a no-op.
27206
+ */
27207
+ var NavigationMoveCommandSchema = object({
27208
+ pan: number$1().min(-1).max(1).optional(),
27209
+ tilt: number$1().min(-1).max(1).optional(),
27210
+ speed: number$1().min(0).max(1).optional()
27211
+ });
27212
+ /**
27213
+ * The enumerated discrete actions a navigation-capable robot can perform via
27214
+ * `runAction`. This is the CLOSED vocabulary; a given device advertises the
27215
+ * subset it supports through `listActions`. Sounds are NOT here — they go through
27216
+ * `playSound` (see the `sound` dictionary entries).
27217
+ */
27218
+ var NavigationActionIdSchema = _enum([
27219
+ "goHome",
27220
+ "locate",
27221
+ "spotClean",
27222
+ "findPet",
27223
+ "personFollow",
27224
+ "stop",
27225
+ "startClean",
27226
+ "pauseClean",
27227
+ "dockWash",
27228
+ "autoEmpty",
27229
+ "flashOn",
27230
+ "flashOff"
27231
+ ]);
27232
+ /** Whether a dictionary entry is a `runAction` action or a `playSound` sound. */
27233
+ var NavigationEntryKindSchema = _enum(["action", "sound"]);
27234
+ /**
27235
+ * One entry in the navigation action dictionary — the DATA-DRIVEN unit both the
27236
+ * native panel and the PTZ mimic render as a button.
27237
+ *
27238
+ * - `id` — stable id. For `kind:'action'` it is a {@link NavigationActionId}
27239
+ * (pass to `runAction`); for `kind:'sound'` it is a namespaced id
27240
+ * (`sound:meow`) whose `soundId` is passed to `playSound`.
27241
+ * - `icon` — icon HINT (lucide-style name; the UI maps it to its own set).
27242
+ * - `label` — operator-facing English label.
27243
+ * - `soundId` — wire sound id, present only on `kind:'sound'` entries.
27244
+ * - `enabled` — per-device FEATURE FLAG. `listActions` reports it so the UI /
27245
+ * PTZ render ONLY enabled entries. Data-driven: the provider
27246
+ * flips it from config, never by editing code.
27247
+ */
27248
+ var NavigationActionEntrySchema = object({
27249
+ id: string(),
27250
+ kind: NavigationEntryKindSchema,
27251
+ label: string(),
27252
+ icon: string(),
27253
+ /** Present only on `kind:'sound'` entries — the id to pass to `playSound`. */
27254
+ soundId: number$1().int().optional(),
27255
+ /** Per-device feature flag — render this entry only when true. */
27256
+ enabled: boolean()
27257
+ });
27258
+ /** Coordinates for `goToPoint` — a point on the robot's live map. */
27259
+ var NavigationPointSchema = object({
27260
+ x: number$1(),
27261
+ y: number$1()
27262
+ });
27263
+ /**
27264
+ * Per-device FEATURE-FLAG report for the general (non-dictionary) primitives.
27265
+ * The cap reports which are enabled so the UI / PTZ render only the controls
27266
+ * that are turned on for THIS device. Data-driven: the provider derives these
27267
+ * from config + probe, never hardcoded in the UI. The per-DICTIONARY-entry flags
27268
+ * live on {@link NavigationActionEntrySchema.enabled}; these gate the primitives
27269
+ * that are not dictionary entries.
27270
+ *
27271
+ * - `move` / `stop` — the momentary drive joystick.
27272
+ * - `goToPoint` — send-to-map-coordinate. Ships OFF on Dreame until the
27273
+ * map-coordinate plumbing is wired.
27274
+ * - `runAction` — the discrete action buttons (dictionary `kind:'action'`).
27275
+ * - `playSound` — the sound buttons (dictionary `kind:'sound'`).
27276
+ * - `light` — the on/off fill-light toggle (works anytime).
27277
+ * - `lightMode` — the auto/manual selector + manual level slider (a
27278
+ * camera-service control; needs an active stream).
27279
+ */
27280
+ var NavigationFeaturesSchema = object({
27281
+ move: boolean(),
27282
+ stop: boolean(),
27283
+ goToPoint: boolean(),
27284
+ runAction: boolean(),
27285
+ playSound: boolean(),
27286
+ light: boolean(),
27287
+ lightMode: boolean()
27288
+ });
27289
+ /** Light mode: `auto` lets the camera choose brightness; `manual` uses `level`. */
27290
+ var NavigationLightModeSchema = _enum(["auto", "manual"]);
27291
+ /**
27292
+ * Live navigation state so the UI can reflect what the robot is doing:
27293
+ * - `mode` — coarse activity (idle / cleaning / following / …).
27294
+ * - `following` — person/pet follow is currently armed.
27295
+ * - `flash` — the on-camera fill light is on.
27296
+ * - `lightMode` — auto vs manual fill-light mode.
27297
+ * - `lightLevel` — manual fill-light level (40..100); meaningful when
27298
+ * `lightMode === 'manual'`.
27299
+ */
27300
+ var NavigationStatusSchema = object({
27301
+ mode: _enum([
27302
+ "idle",
27303
+ "cleaning",
27304
+ "spot",
27305
+ "following",
27306
+ "goto",
27307
+ "returning",
27308
+ "paused",
27309
+ "unknown"
27310
+ ]),
27311
+ following: boolean(),
27312
+ flash: boolean(),
27313
+ lightMode: NavigationLightModeSchema,
27314
+ lightLevel: number$1().min(40).max(100),
27315
+ /** Ms epoch when the slice was last updated. */
27316
+ lastChangedAt: number$1()
27317
+ });
27318
+ NavigationStatusSchema.extend({ lastFetchedAt: number$1() });
27319
+ DeviceType.Camera, method(NavigationMoveCommandSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(NavigationPointSchema.extend({ deviceId: number$1() }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), array(NavigationActionEntrySchema)), method(object({
27320
+ deviceId: number$1(),
27321
+ actionId: NavigationActionIdSchema
27322
+ }), _void(), { kind: "mutation" }), method(object({
27323
+ deviceId: number$1(),
27324
+ soundId: number$1().int()
27325
+ }), _void(), { kind: "mutation" }), method(object({
27326
+ deviceId: number$1(),
27327
+ on: boolean()
27328
+ }), _void(), { kind: "mutation" }), method(object({
27329
+ deviceId: number$1(),
27330
+ mode: NavigationLightModeSchema,
27331
+ level: number$1().min(40).max(100).optional()
27332
+ }), _void(), { kind: "mutation" }), method(object({
27333
+ deviceId: number$1(),
27334
+ level: number$1().min(40).max(100)
27335
+ }), _void(), { kind: "mutation" }), method(object({ deviceId: number$1() }), NavigationFeaturesSchema), object({
27336
+ deviceId: number$1(),
27337
+ status: NavigationStatusSchema
27338
+ });
27142
27339
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number$1().int().nonnegative() }), object({ success: literal(true) }), {
27143
27340
  kind: "mutation",
27144
27341
  auth: "admin"
@@ -32203,6 +32400,66 @@ Object.freeze({
32203
32400
  addonId: null,
32204
32401
  access: "create"
32205
32402
  },
32403
+ "navigation.getFeatures": {
32404
+ capName: "navigation",
32405
+ capScope: "device",
32406
+ addonId: null,
32407
+ access: "view"
32408
+ },
32409
+ "navigation.goToPoint": {
32410
+ capName: "navigation",
32411
+ capScope: "device",
32412
+ addonId: null,
32413
+ access: "create"
32414
+ },
32415
+ "navigation.listActions": {
32416
+ capName: "navigation",
32417
+ capScope: "device",
32418
+ addonId: null,
32419
+ access: "view"
32420
+ },
32421
+ "navigation.move": {
32422
+ capName: "navigation",
32423
+ capScope: "device",
32424
+ addonId: null,
32425
+ access: "create"
32426
+ },
32427
+ "navigation.playSound": {
32428
+ capName: "navigation",
32429
+ capScope: "device",
32430
+ addonId: null,
32431
+ access: "create"
32432
+ },
32433
+ "navigation.runAction": {
32434
+ capName: "navigation",
32435
+ capScope: "device",
32436
+ addonId: null,
32437
+ access: "create"
32438
+ },
32439
+ "navigation.setLightLevel": {
32440
+ capName: "navigation",
32441
+ capScope: "device",
32442
+ addonId: null,
32443
+ access: "create"
32444
+ },
32445
+ "navigation.setLightMode": {
32446
+ capName: "navigation",
32447
+ capScope: "device",
32448
+ addonId: null,
32449
+ access: "create"
32450
+ },
32451
+ "navigation.setLightOn": {
32452
+ capName: "navigation",
32453
+ capScope: "device",
32454
+ addonId: null,
32455
+ access: "create"
32456
+ },
32457
+ "navigation.stop": {
32458
+ capName: "navigation",
32459
+ capScope: "device",
32460
+ addonId: null,
32461
+ access: "create"
32462
+ },
32206
32463
  "networkAccess.getEndpoint": {
32207
32464
  capName: "network-access",
32208
32465
  capScope: "system",
@@ -36298,6 +36555,56 @@ Object.freeze({
36298
36555
  form: "single",
36299
36556
  optional: false
36300
36557
  }],
36558
+ "navigation.getFeatures": [{
36559
+ name: "deviceId",
36560
+ form: "single",
36561
+ optional: false
36562
+ }],
36563
+ "navigation.goToPoint": [{
36564
+ name: "deviceId",
36565
+ form: "single",
36566
+ optional: false
36567
+ }],
36568
+ "navigation.listActions": [{
36569
+ name: "deviceId",
36570
+ form: "single",
36571
+ optional: false
36572
+ }],
36573
+ "navigation.move": [{
36574
+ name: "deviceId",
36575
+ form: "single",
36576
+ optional: false
36577
+ }],
36578
+ "navigation.playSound": [{
36579
+ name: "deviceId",
36580
+ form: "single",
36581
+ optional: false
36582
+ }],
36583
+ "navigation.runAction": [{
36584
+ name: "deviceId",
36585
+ form: "single",
36586
+ optional: false
36587
+ }],
36588
+ "navigation.setLightLevel": [{
36589
+ name: "deviceId",
36590
+ form: "single",
36591
+ optional: false
36592
+ }],
36593
+ "navigation.setLightMode": [{
36594
+ name: "deviceId",
36595
+ form: "single",
36596
+ optional: false
36597
+ }],
36598
+ "navigation.setLightOn": [{
36599
+ name: "deviceId",
36600
+ form: "single",
36601
+ optional: false
36602
+ }],
36603
+ "navigation.stop": [{
36604
+ name: "deviceId",
36605
+ form: "single",
36606
+ optional: false
36607
+ }],
36301
36608
  "networkQuality.getDeviceStats": [{
36302
36609
  name: "deviceId",
36303
36610
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-ai",
3
- "version": "0.4.72",
3
+ "version": "0.4.73",
4
4
  "description": "AI addon for CamStack — the `llm` collection provider (cloud, LAN, and camstack-managed local llama.cpp profiles) plus the per-node `llm-runtime` managed executor.",
5
5
  "keywords": [
6
6
  "camstack",