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
base— Always rendered, on every channelvoice— Appended tobaseon voice channels, ignored on texttext— Appended tobaseon text channels (web, WhatsApp, SMS), ignored on voice
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[]
string | ((request: LuaRequest) => string | Promise<string>)
The LLM your agent uses. Either a static Static model:Dynamic resolver — receives the full request with all platform APIs available (See: Model Selection
'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.
User, Baskets, Products, etc.):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
Supported fields:
AI.generate({ temperature }). Undefined leaves provider defaults in
place.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 yourLuaAgent 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):Related APIs
LuaSkill
Tool collections
LuaTool
Individual tools
LuaWebhook
HTTP endpoints
LuaJob
Scheduled tasks
LuaMCPServer
External MCP tools

