Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Device Definition API gives you two helpers for declaring how your agent talks to a physical or virtual device:
  • defineDevice(config) — declares a device, its commands, and (optionally) its built-in triggers.
  • defineDeviceTrigger(config) — declares a standalone trigger primitive (versioned, pushed independently).
import { defineDevice, defineDeviceTrigger } from 'lua-cli';
import { z } from 'zod';
For the device-side client library (the code that runs on the device itself — Node, MQTT, MicroPython), see Device Client and the Devices tab.

defineDevice(config)

Declares a device. Devices have commands (agent → device) and optionally triggers (device → agent).
import { defineDevice } from 'lua-cli';
import { z } from 'zod';

export const labelPrinter = defineDevice({
  name: 'label-printer',
  description: 'Warehouse label printer (Zebra GK420d)',
  commands: {
    print: {
      description: 'Print a shipping label',
      schema: z.object({
        orderId: z.string(),
        labelData: z.object({
          address: z.string(),
          tracking: z.string(),
        }),
      }),
    },
    eject: {
      description: 'Eject the current label',
      schema: z.object({}),
    },
  },
  triggers: {
    paperLow: {
      description: 'Fires when paper drops below threshold',
      payloadSchema: z.object({ level: z.number() }),
      execute: async (payload, { agent, device }) => {
        await agent.chat(`Printer ${device.name} paper low: ${payload.level}%`);
      },
    },
  },
});

Configuration — LuaDeviceConfig

name
string
required
Unique device name. Used in lua devices and addressing from agent code.
description
string
Human-readable description shown in the admin dashboard.
group
string
Optional group label for organizing devices (e.g. 'printers', 'sensors'). lua devices list --group <name> filters by this.
commands
Record<string, DeviceCommandConfig>
required
Map of command name → command config. Each command is a callable the agent can invoke on the device.
triggers
Record<string, DeviceTriggerConfig>
Map of trigger name → trigger config. Built-in triggers tied to this device. For triggers shared across devices, use defineDeviceTrigger instead.

Command Shape — DeviceCommandConfig

description
string
required
What this command does. Used by the agent’s LLM to decide when to invoke.
schema
ZodSchema
required
Zod schema for the command’s input. Validated before the command leaves the agent.
timeout
number
Per-command timeout in milliseconds. Defaults to the device-wide timeout (30000).

Trigger Shape — DeviceTriggerConfig

description
string
required
What this trigger represents. Used in trigger discovery and admin UI.
payloadSchema
ZodSchema
required
Zod schema for the trigger payload. Validated when the device fires the trigger.
execute
(payload, ctx) => Promise<void>
required
Handler invoked when the trigger fires. Receives the validated payload and a context with agent (for invoking the agent) and device (the device that fired).

defineDeviceTrigger(config)

Declares a standalone device trigger as a first-class primitive. Use this when a trigger isn’t bound to a single device — for example, a trigger that any device in a group can fire, or a trigger that’s pushed/versioned independently from its associated device.
import { defineDeviceTrigger } from 'lua-cli';
import { z } from 'zod';

export const paperLowAlert = defineDeviceTrigger({
  name: 'paper-low-alert',
  description: 'Generic paper-low handler for any printer',
  payloadSchema: z.object({
    deviceName: z.string(),
    level: z.number(),
  }),
  execute: async (payload, { agent }) => {
    await agent.chat(`Paper low on ${payload.deviceName}: ${payload.level}%`);
  },
});
Standalone triggers are pushed via lua push device-trigger (or as part of lua push all) and managed through the standard CLI surfaces.

Configuration — LuaDeviceTriggerConfig

name
string
required
Unique trigger name. Allowed characters: a-z, 0-9, _, -. Must start with a letter.
description
string
required
What this trigger represents.
payloadSchema
ZodSchema
required
Zod schema for the trigger payload.
execute
(payload, ctx) => Promise<void>
required
Handler invoked when the trigger fires.

Wiring Up to an Agent

import { LuaAgent } from 'lua-cli';
import { labelPrinter } from './devices/label-printer';
import { paperLowAlert } from './triggers/paper-low-alert';

export const agent = new LuaAgent({
  name: 'warehouse-agent',
  devices: [labelPrinter],
  deviceTriggers: [paperLowAlert],
  // ...
});

Invoking Commands from Tools

Inside a skill tool, address a device by name and call its command:
class PrintLabelTool extends LuaTool {
  name = 'printLabel';
  description = 'Print a shipping label';
  inputSchema = z.object({ orderId: z.string() });

  async execute({ orderId }, ctx) {
    const order = await Data.get('orders', orderId);
    await ctx.devices['label-printer'].commands.print({
      orderId,
      labelData: { address: order.shipping, tracking: order.tracking },
    });
    return { printed: true };
  }
}

Local Testing

Use lua devices test and lua devices test-trigger to exercise commands and triggers without involving real hardware:
lua devices test --device-name label-printer
lua devices test-trigger --device-name label-printer --payload '{"level":15}'