The Lua API provides access to request-level runtime information. Use it in your tools, tool conditions, preprocessors, and postprocessors to access context about the current request.
import { Lua } from 'lua-cli';// Access the current channelconst channel = Lua.request.channel;if (channel === 'whatsapp') { // WhatsApp-specific logic}
The webhook object contains information about the incoming webhook request from channel integrations. This provides access to the original data sent by the channel provider (WhatsApp, Slack, Teams, etc.).
Lua.request.webhook: { payload: any } | undefined
Type:{ payload: any } | undefinedThe webhook object is only available when the request originated from a webhook-based channel. For direct API calls or the web chat widget, this will be undefined.
import { Lua } from 'lua-cli';const webhook = Lua.request.webhook;if (Lua.request.channel === 'email' && webhook) { const { messageId, // bare ID, no <angle brackets> inReplyTo, // bare ID, or null references, // array of bare IDs subject, from, // [{ address, name }] to, cc, date, // ISO 8601 string headerLines, // [{ key, line }] — full ordered RFC 5322 header list } = webhook.payload; const isReply = !!inReplyTo; const threadRoot = references?.[0] ?? messageId; return { messageId, isReply, threadRoot, subject };}
The email channel’s payload differs from JSON-over-HTTP channels (WhatsApp, Slack, etc.). Email arrives over SMTP as RFC 5322 MIME — there is no JSON envelope from a provider to forward. Lua parses the message and exposes it as a JMAP-aligned object: typed common headers plus a headerLines array preserving the full RFC 5322 header order.
If your email channel is backed by an AgentMail inbox, webhook.payload follows AgentMail’s native event shape (message_id, thread_id, inbox_id, …) rather than the JMAP shape above. Branch on the presence of messageId (Lua-native) vs message_id (AgentMail) until the shapes are normalized.
Use channel for minor adjustments, not completely different flows:
// ✅ Good - Minor adjustmentsconst maxLength = channel === 'whatsapp' ? 4096 : 10000;// ❌ Avoid - Completely different tools per channel// Instead, use tool conditions to show/hide tools
✅ Use Tool Conditions for Availability
For channel-specific tools, use the condition function: