Skip to main content

Overview

LuaAgent is the recommended way to configure your AI agent in modern lua-cli. It provides a single, intuitive configuration object that combines skills, webhooks, jobs, and message processors.
LuaAgent replaces the need to export individual skills, webhooks, and jobs separately.

Why LuaAgent?

Single Source of Truth

All agent components in one configuration object

Auto-Sync

CLI auto-manages lua.skill.yaml (do not edit manually)

Better IDE Support

Improved autocomplete and type safety

Clear Organization

Organized, readable agent configuration

Constructor

new LuaAgent(config)

Creates a new agent configuration.
LuaAgentConfig
required
Agent configuration object

Configuration Parameters

Required Fields

string
required
Agent identifier used for organization and loggingExamples: 'customer-support-agent', 'sales-assistant'
string | { base?: string; voice?: string; text?: string }
required
Defines the agent’s personality, behavior, tone, and capabilitiesString form (recommended):
  • Who the agent is
  • What role they play
  • How they should communicate
  • What they can and cannot do
  • Any specific behaviors or rules
Object form (channel-aware): Only use when you need measurably different behavior on voice vs text channels.
  • base — Always rendered, on every channel
  • voice — Appended to base on voice channels, ignored on text
  • text — Appended to base on text channels (web, WhatsApp, SMS), ignored on voice
See Channel-aware Prompts for details.

Optional Fields

LuaSkill[]
Array of skills (tool collections) the agent can useDefault: []
LuaWebhook[]
HTTP endpoints that can receive external eventsDefault: []
LuaJob[]
Scheduled tasks that run automaticallyDefault: []
PreProcessor[]
Functions that process messages before they reach the agentDefault: []
PostProcessor[]
Functions that process agent responses before sending to usersDefault: []
LuaMCPServer[]
MCP (Model Context Protocol) servers providing external toolsDefault: []See: LuaMCPServer API
string | ((request: LuaRequest) => string | Promise<string>)
The LLM your agent uses. Either a static 'provider/model' string or a resolver function that selects the model dynamically per request.Format: 'provider/model' — e.g. 'google/gemini-2.5-flash', 'openai/gpt-4o'Default: 'google/gemini-2.5-flash'
Lua manages the API credentials — you don’t need to configure any API keys. Support for user-provided API keys is coming in a future release.
Static model:
Dynamic resolver — receives the full request with all platform APIs available (User, Baskets, Products, etc.):
See: Model Selection
AgentModelSettings
Per-call sampling settings forwarded to the model on every chat turn. Set them once on the agent instead of overriding them in every skill via AI.generate({ temperature }). Undefined leaves provider defaults in place.
Supported fields:Obviously-broken values (non-finite numbers, temperature outside 0..2, topP outside 0..1, non-positive maxOutputTokens, non-string stopSequences, an unrecognized reasoning.effort, or a non-boolean reasoning.show) are rejected at construction time. Provider-specific range checks are deferred to the provider.reasoning — per-agent default reasoning effortUnlike the other fields, reasoning isn’t a raw sampling parameter — it’s a normalized setting Lua translates into each provider’s own reasoning/thinking dialect, so the same config works whether the resolved model is Claude, GPT, Gemini, or another reasoning-capable model.
This is a default for the agent — a per-request reasoning override on the chat request always takes precedence over it, field by field (setting only effort on a request doesn’t clear an agent-level show: false). If neither the request nor the agent sets an effort, Lua’s platform default applies: adaptive reasoning where the resolved model supports it (Claude’s newest generations, Gemini 2.5’s dynamic thinking budget), and an explicit low effort otherwise — favoring lower cost and latency on turns that don’t ask for deeper thinking. A few models deviate from that low default: GPT’s top-tier reasoning variant has a medium floor (it doesn’t accept anything lower), DeepSeek’s reasoning model has no tier below high, and Qwen’s reasoning is on/off only (no effort tiers).reasoning only affects reasoning behavior — it is not forwarded as a raw modelSettings field to the underlying call, so it never collides with provider-specific sampling parameters.

Basic Example

Complete Example

Persona Best Practices

✅ Good Persona

❌ Bad Persona

Persona Storage

Persona is stored in your LuaAgent code definition (in src/index.ts). The lua.skill.yaml file is state-only and tracks IDs and versions, not persona content. When you edit persona using lua persona, it updates the persona field in your LuaAgent code directly.

Multiple Skills Example

With All Components

Dynamic Configuration

Migration from v2.x

Before (v2.x):
After:

LuaSkill

Tool collections

LuaTool

Individual tools

LuaWebhook

HTTP endpoints

LuaJob

Scheduled tasks

LuaMCPServer

External MCP tools

See Also