Build sessions: safer endings, pasted keys and pushes that say what they did
Released: October 30, 2026 Available in lua-cli 3.64.0 and later.โจ New Features
Ending a session with a release waiting
Ending a session with a release waiting
lua build-session end deals with an open release first. Waiting for your decision, it prints the card and asks: Keep working (the default), Deny it and end the session, or Approve it (it goes live, then the session ends). The menu starts on Keep working and does not wrap around. A release still being prepared can be cancelled or kept, and one already going live is waited for. See end.A key pasted into a message stays out of the session
A key pasted into a message stays out of the session
secret <id> --from-pasted (or /secret <id> in the chat) saves it with nothing to type. If it was not a key, not-a-key <bsp_id> (chat: /notakey) sends it to Claude as text. See A key pasted into a message.Release and action cards in plain words
Release and action cards in plain words
Web apps can say what their App Viewers may do
Web apps can say what their App Viewers may do
defineWebApp({ viewers: { write, chat, mode } }) says what the people who sign in by phone or email to use only your app may do. write lets them call the appโs POST, PUT, PATCH and DELETE routes, chat lets them use the agent pane, and mode says whether an admin invites them ('people', the default) or the appโs own code adds and removes them ('app'). lua compile checks it and lua push sends it with the version. Lua applies it when App Viewers use the app.auth.accessLevel can now be 'use'. Your write routes then run with empty roles and scopes, so check in each one that the row belongs to auth.userId, and answer 404 when it does not.Apps add and remove their own App Viewers
Apps add and remove their own App Viewers
viewers: { mode: 'app' }, your appโs code manages who may use it:POST, PUT, PATCH or DELETE route, as the signed-in person, who needs full access to the app. Removing also works in a job or webhook, and only removes people your app added. Each person comes back with an outcome (added, alreadyMember, invalid_number, excluded, cap_reached and so on); an AppViewersError rejects the whole call when App mode is off or the caller lacks full access. 1 to 20 people a call. In lua test and lua dev both throw app_viewers_unavailable.Know when a turn comes from an app's agent pane
Know when a turn comes from an app's agent pane
Lua.request.appAccess is { appId, accessLevel } on a turn sent from a web appโs agent pane: 'full' for someone who can read the agent, 'use' for an App Viewer. Tools and pre/postprocessors use it to tell a pane turn, and an App Viewerโs, from a Lua Workspace or WhatsApp turn. It is absent on every other turn and in lua test.Your app's logo on its sign-in page
Your app's logo on its sign-in page
defineWebApp({ branding: { logo } }) (./src/logo.svg, or /logo.png from Viteโs public/) and lua push ships it, so the sign-in page shows it. PNG, JPEG, WebP or a simple SVG (shapes, gradients, masks; no scripts, styles, images or text), at most 256 KB. A logo that cannot be used is a warning, never an error: the sign-in page then shows the appโs initial.๐ง Improvements
A release that only updates code says so
A release that only updates code says so
Backups keep what a project needs
Backups keep what a project needs
lua push and push backup now keep your lockfile (up to 8 MB), tests, type definitions and project config folders such as .github/ and .vscode/, and never .env or credential files. lua push lists every file it left out. Set LUA_SOURCE_CAPTURE_POLICY=legacy to keep the old rule. See Backups and restore.Build sessions from scripts and the terminal
Build sessions from scripts and the terminal
- Denying a release from the terminal works with an API key too.
endandkillwithout--sessionno longer act on another terminalโs session: with two or more sessions open and no terminal, they stop and list them.startmakes one session, and says plainly when your organization is at its session limit.- A push inside a build session says the work is staged in the session and goes live when the session is released.
lua featuresandlua models setinside a build session are staged with it: the release card lists the change, and it goes live only when you approve. The card also names changed tools nobody tested.lua deploy personasays the deploy is recorded as a new agent version on an agent under versioning.
๐ Bug Fixes
Build session fixes
Build session fixes
sendafter a session slept or restarted no longer prints the previous turn again.- A push refused because a build session holds the agent stops once, says nothing was pushed, and names whose session it is.
- With several organizations, the error lists each with its id, and
--orgworks together with--agent. push agentinside a build session no longer prints โPersona version undefined createdโ.
Commands that edit src/index.ts keep it compiling
Commands that edit src/index.ts keep it compiling
lua models set could write a double comma into your agent config when it had a comment in it, and the agent then failed to compile. Every command that edits src/index.ts (lua models, lua init, lua sync, lua persona, lua apps new and lua apps delete) now checks the edited file still parses. If it would not, the file is left unchanged and the command tells you what to add by hand.Live build sessions from the terminal
Released: October 25, 2026 Available in lua-cli 3.59.0 and later.โจ New Features
lua build-session: build an agent with Claude from your terminal
lua build-session: build an agent with Claude from your terminal
buildSessions.enabled feature has opted out; there, the commands fail with build_sessions_disabled. lua --help lists build-session only when LUA_BUILD_SESSIONS_ENABLED=true is set in your environment, and the commands work either way. See lua build-session.Interactive chat with slash commands
Interactive chat with slash commands
lua build-session, start, chat and resume open a chat once the session is ready. Replies render as Markdown. A message typed during a turn is queued. Ctrl-C stops a turn; Ctrl-C twice at an empty prompt, or Ctrl-D, leaves the chat and the session keeps running./help lists the slash commands: /file, /paste, /interrupt, /try, /release, /status, /diff, /end, /approvals, /approve, /deny, /secret, /files, /save, /sessions, /switch, /new and /detach. See Slash commands.Pick an organization and agent
Pick an organization and agent
--agent, a terminal lists your organizations, then that organizationโs agents, with the projectโs agent first and any session you already have on each. The last entry starts a fleet session on the supervisor agent you pick. See Pick an organization and agent.Several sessions, approvals and files
Several sessions, approvals and files
list shows your sessions across every organization and agent, and use, resume, status, attach, stop, end / remove and kill work on any of them. The CLI remembers the current session; LUA_BUILD_SESSION_ID overrides it.approvals lists what is waiting on you across your open sessions, and approve, deny and secret answer it. A secret is typed hidden, never passed as an argument. Approving a release from the CLI needs a person signed in with lua auth; an API key needs the organizationโs buildSessions.cliReleaseApprove setting.Drop a file on the terminal, or paste its path, to send it with your message. files lists the sessionโs files, download [id] or download --all saves them, and chat --auto-save <dir> saves each file Claude shares as it arrives.Scripts and exit code 13
Scripts and exit code 13
send <text> sends one message and prints its turn, and --json prints one JSON object per line:credits_exhausted and a link to top up, and the CLI exits 13, a new exit code. See Errors and exit codes.Files and page scripts in the browser, and saved logins everywhere
Released: October 25, 2026 Available in lua-cli 3.58.0 and later.โจ New Features
Downloads, PDFs and uploads in the browser
Downloads, PDFs and uploads in the browser
maxDownloadMb, the largest file in megabytes. Your planโs limit caps it.scanning until the malware scan marks it clean. allowedMimeTypes is checked against the fileโs contents, not its name. An upload accepts only the personโs own files in the same organization, once they are clean. With files on, the agent can also download, save PDFs and upload a file the person just sent in chat. For an older file, it asks the person to send it again. See Files.Page scripts with Browser.eval
Page scripts with Browser.eval
allowScripts: true together with allowedDomains lets your code run a script in the page. Lua logs each run without its text, and neither the agent in chat nor Browser.execute can run scripts. See Page scripts.New guide and LuaBrowser reference
New guide and LuaBrowser reference
๐ง Improvements
Saved logins are on everywhere
Saved logins are on everywhere
Browser.login, job grants and lua browser run --login are available on every workspace. After a signed-in run, the next run picks up the same sign-in without signing in again. See Saved logins.Signed-in browser runs from the terminal, and template taglines
Released: October 23, 2026 Available in lua-cli 3.57.0 and later.โจ New Features
lua browser run --login
lua browser run --login
scaledown/classify-1 takes your usual state and one image
scaledown/classify-1 takes your usual state and one image
decision_rejected before the call. See Other decision models.A one-line tagline for your template
A one-line tagline for your template
lua marketplace template create --tagline sets it too. template draft brings back a tagline Lua staff edited on the listing, and template publish warns before replacing a different one. See tagline.A per-turn note from a preprocessor, and a context reset
Released: October 19, 2026 Available in lua-cli 3.56.0 and later.โจ New Features
metadata.turnContext from a preprocessor
metadata.turnContext from a preprocessor
Threads.resetContext()
Threads.resetContext()
skipped when the agentโs contextReset feature is off, outside a 1:1 chat turn, with observational memory off, when nothing older is left, or in a local lua test run. Turning on contextReset also resets the context once a day, on the first turn after 04:00 in the personโs timezone, so the agent no longer sees earlier days. Give the agent what it still needs after a reset from your own data, for example with turnContext.๐ง Improvements
Older web apps get a nudge
Older web apps get a nudge
lua push webapp and lua apps dev warn when an appโs pages use @lua-ai-global/ui older than 0.3 and point to lua apps upgrade <name>. The push is not blocked. See lua apps upgrade.Chat in the appโs top bar, and web apps on the new Lua design
Released: October 16, 2026 Available in lua-cli 3.55.0 and later.โจ New Features
The agent pane belongs to the platform
The agent pane belongs to the platform
<AgentPaneLayout> get it too, with their own pane hidden, so no app has to be rebuilt or pushed again. The admin console shows no pane for apps for now. See Talk to the agent from your app.Drive the pane from the page with lua.pane
Drive the pane from the page with lua.pane
@lua-ai-global/app-client 0.0.5 and later can open, close and ask the pane, and set what the agent gets with every message sent from it (at most 4 KB):lua apps new no longer bundles the pane
lua apps new no longer bundles the pane
@lua-ai-global/app-chat, the <AgentPaneLayout> wrapper in web/src/main.tsx and the paneโs styles in web/src/index.css. <AgentPaneLayout>, <AgentPane> and useAgentPane are deprecated.lua apps upgrade removes the bundled pane
lua apps upgrade removes the bundled pane
<AgentPaneLayout> gives way to what it wraps (a context prop becomes lua.pane.setContext), useAgentPane() becomes lua.pane, and @lua-ai-global/app-chat and its styles go once nothing imports them. A file it cannot rewrite is left as it is, with the steps printed.Web apps on the new Lua design
Web apps on the new Lua design
lua apps new builds the pages on @lua-ai-global/ui 0.3, the design Lua Workspace uses: flat surfaces, a 6px radius, denser controls, and Inter. lua apps upgrade <name> raises an existing app to it. 0.3 keeps every component and variant name of 0.2, so check the pages visually with lua apps dev before you push. See Look and theme.๐ง Improvements
lua apps dev says where the pane is
lua apps dev says where the pane is
lua.chat still works locally. For pages that still bundle <AgentPaneLayout>, it points to lua apps upgrade <name>.Apps on ui 0.2 get the new design's look
Apps on ui 0.2 get the new design's look
@lua-ai-global/ui 0.2 get the new designโs colours and shapes where Lua can apply them, until they are upgraded and pushed.Tool labels in the chat, and lua apps upgrade
Released: October 15, 2026 Available in lua-cli 3.54.0 and later.โจ New Features
Tool labels
Tool labels
label โ one text, or { running, done } with {argName} placeholders โ that the chat shows while the tool runs and when itโs done, instead of the toolโs name.lua apps upgrade
lua apps upgrade
lua apps new up to the current template, so it gets the agent pane without editing by hand. It shows the changes and asks first, then runs npm install in web/. A file it does not recognise, or one you changed, is left alone, and the command says what to do instead.--force applies without asking and --skip-install skips the install.Set a secret from stdin with lua env --stdin
Set a secret from stdin with lua env --stdin
View-only access in web app routes
View-only access in web app routes
auth.accessLevel is 'full' or 'view_only'. Someone a view was shared with view-only reaches only your GET routes, so GET routes must only read; other methods answer 403 VIEW_ONLY before your handler runs.Templates can ship views
Templates can ship views
๐ง Improvements
lua push webapp says why a new web app was refused
lua push webapp says why a new web app was refused
standard is used, instead of a generic error.No second agent pane
No second agent pane
๐ Bug Fixes
Event deliveries no longer fail webhook query or header schemas
Event deliveries no longer fail webhook query or header schemas
bodySchema is checked for them. Recompile and push the webhook to pick this up.lua test prints errors and circular objects
lua test prints errors and circular objects
Error used to print {}, and an object that refers to itself broke the log line; they now print the errorโs message and stack, and [Circular].Chat with your agent inside your app
Released: October 13, 2026 Available in lua-cli 3.53.0 and later.โจ New Features
Chat with your agent inside your app
Chat with your agent inside your app
lua apps new scaffolds it; an older app installs the package and wraps itself in the layout:useAgentPane().ask, refetch after every reply, or build its own chat with lua.chat. defineWebApp({ agentPane: false }) turns the pane off. See Talk to the agent from your app.Test the pane with lua apps dev
Test the pane with lua apps dev
--chat-env production, on a conversation kept apart from your real one. Restart lua apps dev after changing a skill.lua apps dev.Templates join shared Data collections, and the web app agent pane
Released: October 12, 2026 Available in lua-cli 3.52.0 and later.โจ New Features
Turn off a web app's agent pane
Turn off a web app's agent pane
defineWebApp({ agentPane: false }) turns it off. The setting travels with each pushed version, so the change takes effect once that version is deployed.๐ Bug Fixes
Preview a web app before it is live, and web app titles
Released: October 12, 2026 Available in lua-cli 3.51.0 and later.โจ New Features
Preview a web app version before it is live
Preview a web app version before it is live
lua apps preview <name> opens a version you pushed in Lua Workspace, on its own address, under a Preview banner, so you can click through it before anyone else sees it.Data, but their writes go to a copy that is deleted when the preview ends. Emails and messages are recorded instead of sent, and fetch calls fail with TEST_EGRESS_BLOCKED. Anyone who can edit the agent can open the link, for 24 hours by default. See lua apps preview.A display title for a web app
A display title for a web app
defineWebApp({ title: 'Engineering Fleet' }) sets the name people see in Lua Workspaceโs app header and app lists, up to 80 characters. name stays the appโs identifier and URL. See Define the app.๐ Bug Fixes
lua apps delete and lua apps preview exit by the kind of refusal
lua apps delete and lua apps preview exit by the kind of refusal
10, a missing app or preview 3, a refused credential 9 and an unavailable platform 11, like every other command; they used to exit 1. lua apps delete still exits 1 for a wrong, expired or used code, an account with no verified email, or a code email that could not be sent.Shared Data collections, web-app approvals and supervision secrets
Released: October 11, 2026 Available in lua-cli 3.50.0 and later.โจ New Features
Decide approvals from a web app
Decide approvals from a web app
Hand a supervised agent a secret
Hand a supervised agent a secret
Agents.secrets(id).put(collection, key, value) writes one row into the targetโs own Data from the supervisorโs code, so a credential never passes through a model. It needs act and the collection in the grantโs new secretWriteCollections, and answers with a fingerprint, never the value. See Agents.Filter and page a supervised agent's versions
Filter and page a supervised agent's versions
Agents.versions(id).list({ status, offset }) filters by active, staged, superseded or deleted and pages past the newest 50.๐ง Improvements
Free version slots on a supervised agent
Free version slots on a supervised agent
Agents.versions(id).delete(version) also removes a staged version that was never active, is over 24 hours old and is not the newest staged version.A web app's page no longer decides workflow approvals directly
A web app's page no longer decides workflow approvals directly
403 DECISION_ORIGIN_DENIED. Decide through a route with Workflows.viewer.๐ Bug Fixes
Browser command types match what the browser engine accepts
Browser command types match what the browser engine accepts
Browser.find actions are click, fill, hover, check and text; Browser.wait takes state: 'visible' only; Browser.keyboard actions are type and inserttext. The removed values never worked. Use Browser.press for single keys and key chords.Decisions: any decision model by id
Released: October 11, 2026 Available in lua-cli 3.49.2 and later.โจ New Features
Run a decision on any decision model
Run a decision on any decision model
model to a vendor/model id and the decision runs on that model, with the same request and answer shape as Jev and OpenAI. The result reports provider: 'openrouter' and the exact model version that answered.auto never picks one of these models, and fallback names Jev or OpenAI only.lua decisions run --model
lua decisions run --model
--provider accepts openrouter.๐ง Improvements
Clear errors for a wrong model
Clear errors for a wrong model
provider: 'openrouter' without a model, or a Jev or OpenAI id on it, fails with decision_invalid and a message that names the provider to use. For a LuaDecision, both are compile errors, so lua compile and lua push stop before anything is written. An unknown id, or a model Lua does not serve because its vendor keeps request data, fails with decision_rejected and the vendorโs message.lua browser read and lua browser run check their flags locally
lua browser read and lua browser run check their flags locally
http:// or https://, --max-steps over 60, --max-cost outside 0.01 to 10 USD, and -e staging fail with the allowed range before any request is sent.Clean piped output
Clean piped output
lua browser progress lines are written only when the terminal is interactive, and lua browser read prints a Matches: line with the number of selector matches. lua logs --type browser labels the caller โCalled byโ.๐ Bug Fixes
A 403 from the edge firewall is reported as EDGE_BLOCKED
A 403 from the edge firewall is reported as EDGE_BLOCKED
A LuaBrowser setting out of range fails lua compile with its allowed range
A LuaBrowser setting out of range fails lua compile with its allowed range
Decisions: one answer across the platform and safer versions
Released: October 10, 2026 Available in lua-cli 3.49.1 and later.๐ง Improvements
A model picks its provider
A model picks its provider
provider is not set, a model of one provider picks that provider. A model of no provider fails with decision_invalid.Decisions.run results name the decision
Decisions.run results name the decision
Decisions.run carries decisionName and decisionVersion.Questions are at most 100,000 characters
Questions are at most 100,000 characters
decision_invalid, and writing a larger definition answers 400.lua version status shows the live version
lua version status shows the live version
live 1.5.0, agent version pins 2.0.7.lua decisions versions shows deleted decisions
lua decisions versions shows deleted decisions
lua decisions versions <name> lists the versions of a deleted decision. lua decisions publish <name> <version> turns it back on.Clear compile errors for decisions
Clear compile errors for decisions
decisions: [...] must be written as new LuaDecision({...}) or defineDecision({...}) with literal questions. Namespace imports work, as in decisions: [shared.triage]. A decision built by a helper function fails the compile with a message that names the export. Two decisions with the same name fail it too, and the message names both files.Undoing a publish
Undoing a publish
lua decisions publish, publish another version or promote a different agent version.Log rows record what was asked
Log rows record what was asked
runId when the call has none.Log rows name the execution
Log rows name the execution
Error messages start with the code
Error messages start with the code
DecisionError.message starts with the code, as in decision_timeout: openai did not answer in time. The text a model or a log shows carries the code.A workflow can sit beside a decision
A workflow can sit beside a decision
LuaDecision in the same module. Decisions.odds, Decisions.choice and Decisions.score work at module top level. Decisions.ask and Decisions.run do not, and calling them there fails the compile.lua test --json reports decision errors
lua test --json reports decision errors
lua test --json reports the decision code and decisionId, with the same exit codes as lua decisions run.lua test traffic is marked
lua test traffic is marked
lua test are logged with channel lua-test and the primitive under test, so lua logs tells them apart from real traffic. They are still billed.๐ Bug Fixes
A promote never puts a dashboard draft live
A promote never puts a dashboard draft live
lua version create pins, for each decision, the newest version pushed from code or the current version, whichever is newer. A draft saved in the dashboard without publishing is never pinned.A rollback survives the next version
A rollback survives the next version
lua decisions publish <name> <older version>, the next lua version create pins that version, unless you pushed a newer version from code after the publish. Then the newer push is pinned.A promote takes unpinned decisions offline
A promote takes unpinned decisions offline
Decisions.run throws decision_not_found for it, and it shows no current version until you promote an agent version that pins it or publish one of its versions again. A decision that was pushed but never made current is not affected.A deleted decision takes no new versions
A deleted decision takes no new versions
decision_inactive. Publishing one of its versions turns it back on.lua push follows the server
lua push follows the server
lua.skill.yaml was deleted or renamed on the server, lua push says so in one line. It then pushes to the active decision with the name in your code, creates one when there is none, and updates lua.skill.yaml.The first push writes version 1.0.1
The first push writes version 1.0.1
A webhook answers the decision's own status
A webhook answers the decision's own status
Decisions.run or Decisions.ask fails in a webhook, the webhook answers with the decisionโs status and code instead of a 500: 400 decision_invalid, 404 decision_not_found, 422 decision_rejected, or 503 for a timeout or outage. The body is { code, message, decisionId }.A caller that goes away cancels the call
A caller that goes away cancels the call
decision_cancelled, and nothing is charged.lua test preprocessor matches live
lua test preprocessor matches live
proceed with a warning, the same as live. Live, a pre-processor that throws lets the message through. To block on a failure, wrap Decisions.ask in try/catch and return block yourself.Every billed decision appears in usage
Every billed decision appears in usage
A publish reaches every call at once
A publish reaches every call at once
Tools beside a workflow load
Tools beside a workflow load
Browser: read pages and run tasks from any agent code
Released: October 9, 2026 Available in lua-cli 3.49.0 and later.โจ New Features
Browser.read reads a JavaScript page in one call
Browser.read reads a JavaScript page in one call
blocked: true with guidance, and failures throw a BrowserError with a typed code. See Browser.Browser.execute gives the browser a task in plain words
Browser.execute gives the browser a task in plain words
The browser works in jobs, webhooks, triggers, processors and workflow steps
The browser works in jobs, webhooks, triggers, processors and workflow steps
Browser.* is no longer limited to tools. Server-triggered code runs on the Lua cloud browser, so a job can check a JavaScript page every hour.Named browsers with LuaBrowser
Named browsers with LuaBrowser
browsers: [...], and pick it with { browser: 'name' } on any Browser call. Push it with lua push browser; list and delete it with lua browsers.lua browser read and lua browser run
lua browser read and lua browser run
run prints each step as it happens, and Ctrl-C cancels it on the server. See lua browser.lua logs --type browser
lua logs --type browser
lua deploy webapp
lua deploy webapp
--set-version.๐ง Improvements
Browser session limits are enforced
Browser session limits are enforced
maxSessionMinutes (default 10, at most 60) and the new idleTimeoutSeconds (default 120, at most 900) apply to Lua cloud browser sessions. A LuaBrowser value over a limit fails lua compile.Pages behind a bot check are retried
Pages behind a bot check are retried
fallback: 'browser-use', a page the Lua cloud browser canโt get past (captcha, bot block, empty page) is retried once on a Browser-Use browser. fallback: 'none' keeps every page on Lua infrastructure.Smaller fixes
Smaller fixes
Browser global is fully typed, including Browser.execute, and under lua test every Browser method fails with a clear BROWSER_UNAVAILABLE error. Workflows keep concurrencyKey through lua workflows export and lua push. DecisionError.decisionId is on the public type.Decisions: typed answers with probabilities
Released: October 7, 2026 Available in lua-cli 3.48.0 and later.โจ New Features
Decisions.ask returns typed answers instead of text
Decisions.ask returns typed answers instead of text
Decisions.odds returns the probability that a statement holds, Decisions.choice returns a pick typed to your options, and Decisions.score returns a level along your scale, each with its confidence and the full probability map. No prompt to write and nothing to parse.minConfidence (default 0.7) carry uncertain: true. Works in tools, jobs, webhooks, triggers, processors, workflow code steps and lua test. See Decisions.LuaDecision declares a named decision on your agent
LuaDecision declares a named decision on your agent
decisions: [triage], and call Decisions.run('triage', state) anywhere in the agentโs code. lua push stages a new version, and lua version promote makes it current. The dashboardโs Decisions section edits and publishes versions without a deploy, and an earlier version can be made current again. See LuaDecision.lua decisions lists, tries and rolls back named decisions
lua decisions lists, tries and rolls back named decisions
publish makes a version current at once, and delete turns a decision off and keeps its versions. --json gives machine-readable output.A fixed price per decision
A fixed price per decision
lua logs --type decisions
lua logs --type decisions
๐ง Improvements
timeoutMs covers the whole call
timeoutMs covers the whole call
Limits on images, names and labels
Limits on images, names and labels
decision_invalid and the message names the total. Question names and option labels are at most 64 characters, and any name works, including constructor or toString.A state too large for Jev goes to OpenAI
A state too large for Jev goes to OpenAI
provider: 'auto', a larger state falls back to OpenAI and is charged at OpenAIโs price. Pinned to Jev, it fails with decision_rejected and Jevโs own message.Checks before anything is sent
Checks before anything is sent
"", a blank string, [] or {}) fails with decision_invalid, and the call is never sent or billed. Decisions.odds, Decisions.choice and Decisions.score throw decision_invalid for empty instructions, instructions over 4,000 characters, fewer than 2 or more than 64 options, fewer than 2 or more than 10 levels, or criteria that is not an object.Cache hits report no tokens
Cache hits report no tokens
usage.inputTokens: 0. Identical cacheable calls made at the same time share one provider call, and the calls that joined it come back with cached: true.Every error carries decisionId
Every error carries decisionId
DecisionError.decisionId is the id of the callโs log row, so you can find a failed call.Clearer errors
Clearer errors
decision_rejected (422), not as an outage. Under lua test and through the HTTP API, decision_timeout, decision_unavailable and decision_disabled (all 503) arrive with their own code, message and provider, the same as in deployed code.Definition conflicts answer 409
Definition conflicts answer 409
My work lists, and a cap on message batching
Released: October 6, 2026 Available in lua-cli 3.47.0 and later.โจ New Features
user.setWorkItems() and user.clearWorkItems()
user.setWorkItems() and user.clearWorkItems()
user.data. Keep action a request to show or open, never a decision. See setWorkItems().batching.maxWaitMs on LuaAgent
batching.maxWaitMs on LuaAgent
Custom MCP servers from the Tools page
Released: October 6, 2026 Adding and managing these servers needs no CLI update;lua mcp list and lua integrations show them from lua-cli 3.46.0.
โจ New Features
Add any remote MCP server from the Tools page or the admin dashboard
Add any remote MCP server from the Tools page or the admin dashboard
https:// address and Lua detects how it signs in: no sign-in, headers such as an API key, or OAuth, with your own OAuth app when the provider needs one. Lua tests the connection and lists the serverโs tools, so you can allow them all or choose them one by one. Nothing is saved until the test passes; a failed test shows the step it reached, a plain message, and a Ref to quote to support.On a private agent the server is yours, is added to all your private agents, and serves only you. On a shared agent it belongs to the agent, after you confirm, and serves everyone who uses it. The address and header values are encrypted and write-only, and private, internal, and cloud-metadata addresses are refused. See Add a custom MCP server.lua mcp list shows who manages each server
Released: October 6, 2026
Available in lua-cli 3.46.0 and later.
โจ New Features
lua mcp list shows who manages each server
lua mcp list shows who manages each server
lua mcp list groups the agentโs servers by who manages them and labels each one: From your project (lua-cli), From integrations (Tools page), and Custom servers (Tools page). A custom server shows its host only, never its address, and server headers are listed by name only, never their values.lua mcp activate, deactivate, and delete change only servers from your project; on any other server they stop before changing anything and say where to manage it. lua integrations list labels custom servers with their host, state, and how many of their tools are on, and lua integrations update wonโt change them.Register a job on a supervised agent (experimental)
Register a job on a supervised agent (experimental)
Agents.jobs(agentId).register({ versionId, jobId }) registers a job from a staged version on an agent you supervise, with the matching supervision grant. It is always refused under lua test and lua dev.๐ง Improvements
Stopping a local workflow run stops its agent calls
Stopping a local workflow run stops its agent calls
Trigger history shows archived-organization skips
Trigger history shows archived-organization skips
SKIPPED (organization archived).๐ Bug Fixes
A renamed skill no longer reuses its old sandbox entry
A renamed skill no longer reuses its old sandbox entry
Build web apps for your agent with Lua Apps
Released: October 5, 2026 Available in lua-cli 3.42.0 and later.โจ New Features
Web apps on your agent
Web apps on your agent
@lua-ai-global/ui, and typed routes that run on Lua as the signed-in person, with Data, env(), and fetch.webApps on your LuaAgent. The page calls the route with lua.api('POST', '/tickets', { title }) from @lua-ai-global/app-client. See About web apps and Write routes and pages.lua apps new and lua apps dev
lua apps new and lua apps dev
lua apps new <name> scaffolds src/apps/<name>/ with app.ts and a web/ page project, lists the app on your agent, and keeps the page project out of the agentโs TypeScript build. It never overwrites an existing app. lua apps dev <name> runs it locally: the page on the appโs own Vite with hot reload, the routes in the local sandbox as you, against live Data and env().lua test webapp and lua push webapp
lua test webapp and lua push webapp
lua test webapp calls one route the way the platform would, with you as auth. lua push webapp builds the page with the appโs Vite and stages a web-app version; it goes live with the agent version that pins it, and promoting an earlier agent version rolls it back. Bare lua push and lua push all include web apps.Open an app by URL
Open an app by URL
https://workspace.heylua.ai/apps/<agentId>/<appName>, and the admin console lists an agentโs apps at https://admin.heylua.ai/admin/agents/<agentId>/apps. There is no menu entry yet. Anyone who can read the agent can open its apps. Each app runs on its own origin, and the shell hands it a session: the page never sees a password or the shellโs token. Admins can switch an app off and on from the admin console.See Build and open your first web app.The @lua-ai-global/app-client package
The @lua-ai-global/app-client package
lua.api<T>(method, path, body?), lua.onInit() for the shellโs theme, lua.theme, lua.appName, and LuaApiError. Apps scaffolded with lua-cli 3.42 to 3.45 have a copy in web/src/lua/client.ts. To switch, run npm install @lua-ai-global/app-client in web/, import from the package, and delete the file. See Switch to the client package.Merge two users who are the same person
Released: October 5, 2026 Platform change shipped on October 5, 2026.lua webhooks subscribe accepts user.merged and user.unmerged in lua-cli 3.46.0 and later; 3.45.0 and older refuse them.
โจ New Features
Lua can merge two users who are the same person
Lua can merge two users who are the same person
User.get(absorbedUserId) returns the kept user, so ids in your records still resolve. User ids inside your own data, such as Data entries or your CRM, are not rewritten. Staff can undo a merge; undo moves back exactly what the merge moved, and anything written after the merge stays with the kept user.See When two users merge.user.merged and user.unmerged webhook events
user.merged and user.unmerged webhook events
user.merged once to each agent the absorbed user had talked to, with mergeId, absorbedUserId, keptUserId, knewKept (true when this agent also knew the kept user), and at in event.body. user.unmerged carries the same fields when staff undo the merge. event.execution.eventId is the merge id, or <mergeId>-undo for user.unmerged, so key your handler on it.See Webhooks.Device credentials from the CLI, and lua devices for every device
Released: October 5, 2026
Available in lua-cli 3.45.0 and later.
โจ New Features
lua devices credential issues a device credential
lua devices credential issues a device credential
--operations defaults to commands,triggers; assets.upload allows CDN uploads. --out writes LUA_AGENT_ID, LUA_DEVICE_NAME, and LUA_DEVICE_CREDENTIAL to a mode-600 file and refuses to overwrite it without --force; without --out the secret is printed once. An API-key sign-in is refused: run lua auth configure and choose Email. Aliases: credentials, key.lua devices test --command and test-trigger --trigger
lua devices test --command and test-trigger --trigger
lua devices test --command <name> sends one command without a prompt, so it runs under --ci, and prints the deviceโs own error, for example returned an error: Unknown command: nope. lua devices test-trigger --trigger <name> now fires the trigger through the live pipeline, so the handler really runs; read it with lua logs --type device-trigger.๐ Bug Fixes
lua devices list shows every device
lua devices list shows every device
list showed only defineDevice declarations, so a self-describing device printed โNo devices registeredโ while online. It now lists declared devices and devices that have connected, with online, offline, or disabled and a declared tag.Clearer status, enable, and remove
Clearer status, enable, and remove
status says when a name has never connected to the agent, and how to re-enable a disabled device. enable notes that the device is offline until its client reconnects. remove refuses an unknown name (not_found, exit 3) instead of reporting it removed.Generate images from code with AI.image
Released: October 4, 2026
Available in lua-cli 3.44.0 and later.
โจ New Features
AI.image generates an image from a prompt
AI.image generates an image from a prompt
AI.image is the image sibling of AI.generate: describe an image and get back its hosted URL, ready to embed in a deck, a message, or anywhere a URL works. Like AI.generate, it runs outside the agentโs chat pipeline and is available in tools, jobs, webhooks, triggers, processors, and workflow code steps. The image is produced server-side, stored on the CDN, and billed to the agentโs organization (refused before any image is produced if the account is out of balance).model (a provider-prefixed image model like openai/gpt-image-2; defaults to the platform image model), size, quality (low | medium | high), and outputFormat (png | jpeg | webp). See AI reference.Pin a persona version on an agent version
Released: October 2, 2026 Available in lua-cli 3.43.0 and later.โจ New Features
lua version create --persona-version
lua version create --persona-version
๐ Bug Fixes
lua auth configure and lua deploy honour --ci
lua auth configure and lua deploy honour --ci
No empty diagnose hint after a failed push
No empty diagnose hint after a failed push
lua push all no longer prints a lua logs hint under a component that failed to push, because a failed push writes no logs.New workflow deploy warning
New workflow deploy warning
forbid to allow warns with concurrency-policy-relaxed.Slack: post from code, jobs, workflows and the model
Released: September 29, 2026 Platform changes shipped on September 29, 2026. The'slack' channel type arrives in the next lua-cli release; lua-cli 3.41.0 and older donโt include it in ChannelSendChannel.
โจ New Features
Channels.send posts to Slack
Channels.send posts to Slack
Channels.send accepts channel: 'slack', its eighth channel. Every post goes through the agentโs own connected Slack bot, never a Lua bot:to.conversationId takes Lua.request.conversation.externalId from a Slack channel-thread or group-DM turn, a channel id (Cโฆ, a new top-level message), Cโฆ:threadTs (a reply in that thread), a member id (Uโฆ, their DM with the bot) or a DM channel (Dโฆ). to.userId finds the Lua user in the botโs workspace by their email address. The bot must be in the channel (/invite @your-bot). An agent with more than one Slack connection passes options.channelIdentifier unless the conversation key names the bot.A post into a thread where the bot was already mentioned is recorded there, so the next mention knows what the agent posted, and a DM is recorded in the conversation of its own thread. Posts made by calling Slackโs API directly are not recorded. A Slack rate limit answers 503 VENDOR_UNAVAILABLE with retryAfterSeconds instead of waiting. user.send() still never picks Slack.See Post from code.Workflow replies to Slack
Workflow replies to Slack
replyTo: { channel: 'slack', threadId } now posts its result through the agentโs own Slack bot; it used to be unusable. threadId is any Slack conversationId, usually Cโฆ:threadTs. A redelivery never posts twice, and attachments go out as links.See Workflows REST.sendSlackMessage for the model
sendSlackMessage for the model
outboundChannels feature on, an agent with a connected Slack bot gets sendSlackMessage. With recipientScope: 'current_user' it only DMs the person the agent is talking to; an agent with several Slack bots names which one sends. With anyone it posts to a channel, a thread or a person, and listSlackChannels lists the channels the bot is in. The normal reply already goes to the current Slack thread or DM, so the tool is for a different place or person.See Features.Agent supervision, invokedBy, schedule health and Job-tier plugins
Released: September 28, 2026 Platform changes shipped on September 26 to 28, 2026. Declaringhealth and plugins in a lua-cli project needs the next CLI release; an older CLI drops both without an error.
โจ New Features
Supervise another agent
Supervise another agent
Agents.list, Agents.logs, Agents.runs, Agents.data, Agents.versions, Agents.persona(id).versions, Agents.source and Agents.env(id).keys. Logs come without message bodies unless the grant holds observe-content, runs as metadata only, Data only from the collections the grant names, and environment variables as names only. Every call the grant allows or refuses is recorded in the targetโs own logs (log source supervision). Supervised preview and release are not generally available.See Supervise another agent.Lua.request.invokedBy
Lua.request.invokedBy
Agents.invoke carries Lua.request.invokedBy = { agentId, supervisor, scopes, delegatedUserId? }, verified by the platform. supervisor is true only when an org admin granted the caller act supervision on this agent, so a tool can accept writes from a supervisor and refuse everyone else. A delegated user never grants owner rights.See Lua and Accept changes from a supervisor.Schedule health
Schedule health
LuaJob can declare how it should behave:lua workflows schedules list has a Health column, lua jobs view a Health line, and every transition is a log line a drain can route.See Watch schedule health.Job-tier coding steps can stage agent changes
Job-tier coding steps can stage agent changes
plugins: ['lua-agent-builder'] on a tier: 'job' agent step lets the coding turn restore its agentโs source, compile, push staged versions, back up and create an agent version. It can never promote, deploy, activate, write webhooks or triggers, or read environment variables, and it works only in a run a person started. A person reviews and promotes the result.See Stage agent changes from a coding step.Safe promotion
Safe promotion
POST /developer/agents/:agentId/versions/:version/promote accepts { "expectActive": <n | null> } and refuses a stale one with 409 PROMOTE_CONFLICT, writing nothing; POST /developer/agents/:agentId/persona/version/:version does the same with 409 PERSONA_ACTIVATE_CONFLICT. Each promoted version records promotedBy.See Promote safely.๐ง Improvements
Another agent can no longer override your agent's persona or model
Another agent can no longer override your agent's persona or model
threadId, runtimeContext, webhookPayload and the reasoning effort reach the target; systemPrompt, model, clientContext and every other field are dropped, and the target runs with its own persona, model and tools. A self-invoke is unchanged.See What reaches another agent.Agents.invoke stays inside the organization
Agents.invoke stays inside the organization
cross_org_invoke_denied, on every path that can invoke an agent, and a userId who is not a member of the callerโs organization is refused with delegated_user_not_in_org.๐ Bug Fixes
Data options object and Data.collections() in deployed agents
Data options object and Data.collections() in deployed agents
Data.create(collection, data, { searchText, index }) and the same object on Data.update with searchText must be a string, and had no Data.collections(). Both forms and collections() now work in deployed agents as they did in lua test.See Data.CLI fixes
Released: September 28, 2026 Available in lua-cli 3.40.0 and later.๐ Bug Fixes
lua skills production <action> runs the action
lua skills production <action> runs the action
lua persona sandbox versions lists persona versions without a prompt, and any other unsupported sandbox or production action exits 2 with a usage error instead of waiting on a prompt under --ci.Webhook commands print the public URL
Webhook commands print the public URL
lua webhooks view, lua webhooks deploy and lua deploy webhook print https://webhook.heylua.ai/<agentId>/<name>.lua push and lua sync only move a version forward
lua push and lua sync only move a version forward
version in lua.skill.yaml that you raised by hand, or one staged by an earlier push and not yet deployed, is no longer reset to the active version.lua deploy says what a skill or persona deploy did
lua deploy says what a skill or persona deploy did
lua version promote resets it, instead of claiming an agent version was created.The first lua chat after adding a skill or processor includes it
The first lua chat after adding a skill or processor includes it
lua integrations connect --ci no longer prompts
lua integrations connect --ci no longer prompts
--account-label after OAuth is refused up front, and a missing --scope defaults to agent. lua integrations disconnect --scope user takes --forget, so it runs under --ci too.Script-safe output
Script-safe output
lua skills versions --ci --json prints skill-version ids, lua marketplace skill publish --ci takes --version <semver>, lua preprocessors view --ci and lua postprocessors view --ci print the priority, and lua skills view, deploy and delete refuse --json instead of ignoring it.v3.39.4
Released: September 25, 2026๐ Bug Fixes
lua push stages the persona instead of serving it
lua push stages the persona instead of serving it
lua push agent and lua push all no longer change the persona your agent serves. The pushed version is created as staged, the push prints Persona v<n> staged โ NOT activated, and the persona goes live only when you deploy it:--auto-deploy on lua push agent runs that deploy for you; lua persona production versions marks the pushed version [STAGED] until then, and lua sync --check keeps reporting persona drift until the staged version is activated, because drift is measured against the served version. lua version promote still does not change the served persona. Together with 3.39.1 (workflows and agent versions) a plain lua push now changes nothing an agent serves apart from the model and model settings in the agent configuration. Older CLIs against the current platform stage as well; this release makes the CLI say so.v3.39.3
Released: September 24, 2026โจ New Features
lua logs export --include-content
lua logs export --include-content
user_message and agent_response bodies. Like lua drains create --include-content, it asks you to acknowledge that end-user content will leave the platform; pass --yes to acknowledge non-interactively.๐ Bug Fixes
The export content flag reports the right permission
The export content flag reports the right permission
403 on --include-content was always shown as a missing logs:read scope. It now says that exporting content needs logs:manage.A field named lua_fields_clamped.count is refused
A field named lua_fields_clamped.count is refused
log already refused in your code.v3.39.2
Released: September 24, 2026๐ Bug Fixes
Selecting user_message or agent_response no longer turns message bodies on by itself
Selecting user_message or agent_response no longer turns message bodies on by itself
lua drains create --sources user_message,โฆ without --include-content created the drain with content included, so end-user message bodies were delivered although you had not asked for them, and lua drains update did the same when a content source was added. Content is now on only when you pass --include-content and acknowledge it; records from a selected content source without it arrive with lua.content.withheld: true.If you created a drain with those sources on 3.38.0โ3.39.1 without --include-content, run lua drains get <id> and check includeContent; turn it off with lua drains update <id> --no-include-content if you did not intend it.v3.39.1
Released: September 24, 2026๐ Bug Fixes
lua push no longer activates anything
lua push no longer activates anything
lua push could leave your agent on a new active version without a promote. A push now stages only. Workflows that need activating are listed at the end of the push with the command that activates them, and nothing changes what your agent serves until you run it.lua chat no longer rewrites lua.skill.yaml
lua chat no longer rewrites lua.skill.yaml
1.0.1 came back pinned at whatever was deployed. Chat now links ids only and leaves the versions you wrote alone.v3.39.0
Released: September 24, 2026โจ New Features
Structured fields on a log line
Structured fields on a log line
log.debug, log.info, log.warn and log.error write a log entry with fields beside the message rather than serialized into it.eventName, and the level sets the severity exactly as the matching console method does. lua logs prints the fields as a compact key=value line under the message, and lua logs --json carries them under metadata.fields.Up to 32 keys per call, counting the .count companion a string array adds; keys match ^[a-z][a-z0-9_]{0,63}$, and a key that looks like a credential, or the reserved lua_fields_clamped, is refused; values are a string, number, boolean or string array; 1 KiB per value and 8 KiB per call. A structural mistake โ a bad key, a nested object, an unsupported type โ throws LuaLogFieldsError at the call, so it fails the first time the line runs under lua test. An over-long value is clamped rather than breaking a working tool, and the call carries lua_fields_clamped: true to say so.Available in tools, conditions, skills, webhooks, triggers, jobs, processors, MCP servers and device handlers โ including a tool called as a step of a workflow, which runs the same bundle it runs standalone. Workflow script code keeps ctx.log, unchanged. console.log, console.info, console.warn and console.error are unchanged too โ an object passed to one is still serialized into the message text, and console.log is still a debug entry.See log.Your fields arrive at a log drain as searchable attributes
Your fields arrive at a log drain as searchable attributes
app.<key> attribute on the record, beside the platformโs own, with lua.log.structured: true to select the lines your code described rather than the ones it merely printed.app. is yours โ the platform writes one reserved key of its own there, app.lua_fields_clamped, when a value was cut to fit โ so there is nothing to parse at the destination, and no new source or eventName to select: a drain already carrying skill receives them. A string array arrives joined with , plus a companion app.<key>.count, because a recordโs attribute values are strings, numbers and booleans in the published logs/1.0 schema. A record too large for its destination sheds app.* values largest first and carries lua.app_fields.dropped with the number shed.Per destination: Better Stack lifts your fields to the top level alongside the resource ids, where it indexes them; New Relic keeps every platform attribute ahead of yours under its 255-attribute ceiling, so an overflow loses your fields rather than one you were already querying; Loki keeps them in the JSON line and never as a stream label.A drainโs redact list drops them by their prefixed key ("app.query"), sharing the same 32-key budget, and the scrubber masks credential shapes in them as it does in any other string โ numbers and booleans are not scanned, so keep anything sensitive in a string. Fields are drain bytes and are metered as such; there is no new meter, metric or quota.Rolling out per deployment: until it is enabled, a log.* record is delivered exactly as the same line written with console.* would be. Ask [email protected] to have it enabled.See Emit your own fields.lua logs export โ a whole window of logs, as files you keep
lua logs export โ a whole window of logs, as files you keep
--no-wait starts it and prints the job id to poll later.Download links expire 24 hours after the export finishes and the files are removed after 7 days. Message bodies are included only for an export started by a key holding logs:manage. This replaces the 10,000-row CSV download, which is deprecated for one release.See lua logs export.Object-storage drains, five more destination presets, and a bucket ownership check
Object-storage drains, five more destination presets, and a bucket ownership check
lua drains create --type s3 writes to an S3-compatible bucket on AWS, Cloudflare R2 or Google Cloud Storage, and splunk, loki, axiom, newrelic and sumologic join the presets.--credentials-from-env KEY_ID_VAR=SECRET_VAR, or assume a role with --role-arn and --external-id. A bucket drain proves you own the bucket by writing a _lua-verify-<token> object under its prefix โ lua drains verify finishes on its own when the role can read it back, and lua drains confirm settles the challenge when the grant is write-only, which is the grant we recommend.Each destination type is opened separately per deployment; one that is closed answers 422 DRAIN_TYPE_UNAVAILABLE with the live list. See lua drains.lua drains replay, and addressing a drain by name
lua drains replay, and addressing a drain by name
4xx that is not 408 or 429 โ drops a whole batch. replay puts its records back in the queue, for as long as they are inside the six-hour delivery horizon.lua drains status and lua drains deliveries โ now take a drainโs exact name as well as its id, and print the mapping they resolved so the id is in front of you for the next command. The verbs that change something stay id-only. A name that matches nothing is refused locally, before anything is asked of the platform.See Replaying a lost batch and Addressing a drain.Six more drain sources
Six more drain sources
delivery, trigger-execution, job-execution, workflow-run, voice-call and workflow-audit are selectable, bringing --sources to twenty-five. The first four are on for a new drain; an existing drainโs source list is never re-derived, so nothing you have already configured changes.See Sources.lua logs --channel
lua logs --channel
lua logs.๐ Bug Fixes
A trigger written as a class compiles again
A trigger written as a class compiles again
class X extends LuaTrigger failed lua compile with Trigger `tool.name` must be a static string literal even when it declared no tool at all: the optional slots the base class declares were being read as the subclassโs own. Every subclassed trigger was affected; defineTrigger({ โฆ }) and new LuaTrigger({ โฆ }) never were.verify, filter and transform of a class-based trigger are now read from the class and enforced on the platform like any other triggerโs. See LuaTrigger.lua chat -e production is logged as production
lua chat -e production is logged as production
sandbox environment โ so lua chat -e production, against the promoted agent, wrote log rows labelled sandbox. A log drain scoped to production, or a lua logs --environment production filter, saw nothing from that testing and looked broken.production and a production-scoped drain receives them. It may not be enabled on your deployment yet; where it is not, -e production is recorded as sandbox, exactly as before.A -e sandbox session declares nothing, and neither does an --agent-version preview โ a snapshot that was never promoted is sandbox by every definition the platform uses. The declaration only ever raises a row, so nothing a caller sends can move a real production turn out of a drain that selects it. runtime rows are written from outside the turnโs context and stay sandbox, so a drain selecting production alone sees a real part of the turn rather than all of it.See lua chat and Ship logs to your stack.A class-based webhook or job with no execute is refused at build time
A class-based webhook or job with no execute is refused at build time
execute as a handler the subclass had declared, so a webhook or job with no handler passed lua compile and only failed when the platform loaded it. It now fails the build:LuaWebhook or LuaJob itself does not. In the same correction, a subclassed webhook that sets no secret is unsigned rather than being refused for a secret that โmust be a string literalโ. See LuaWebhook and LuaJob.lua test fails when your handler throws
lua test fails when your handler throws
lua test skill, lua test webhook, lua test job and the processor tests printed execution successful! and exited 0 when the primitive threw, so a CI step that ran one passed on a handler that was broken.--json prints the { success: false, error: โฆ } envelope on stdout instead of nothing. A primitive that deliberately returns an error value without throwing is unaffected โ it still reports success.lua push all and lua deploy all report failure to CI
lua push all and lua deploy all report failure to CI
0, so a scripted push or deploy passed on a partial result. Both now exit non-zero when any component fails or is skipped.lua deploy all also counts a component with no versions on the server as a failure โ naming the id, and saying to push it first or to remove a stale id from lua.skill.yaml โ instead of stepping over it silently and reporting a run that deployed nothing.A workflow module that calls Math at its top level compiles again
A workflow module that calls Math at its top level compiles again
Math.ceil, Math.max or Math.floor while it was being loaded failed lua push:Math is now complete in the compilerโs sandbox. Math.random remains unavailable there, because a workflowโs shape has to read the same every time it is compiled; Math inside a stepโs own code was never affected.v3.38.0
Released: September 22, 2026โจ New Features
Log drains โ ship agent logs to your own stack
Log drains โ ship agent logs to your own stack
records[].id as the deduplication key, batched at 500 records or 1 MiB, retried with full jitter to a 60-second cap, dropped after a six-hour horizon, and auto-paused after 24 hours without a success. A healthy drain heartbeats every five minutes, so silence is never ambiguous, and it reports its own drops in band with a lua.drain.dropped record that bounds the gap.Deliveries to your own HTTPS endpoint are signed with HMAC-SHA256 over the uncompressed body, with a five-minute skew window and overlapping secrets during a rotation.See Ship logs to your stack, Delivery guarantees and Verify signatures.A published event schema at logs/1.0
A published event schema at logs/1.0
https://docs.heylua.ai/schemas/logs/1.0, following the OpenTelemetry log data model and the GenAI semantic conventions โ so service.name, deployment.environment.name, gen_ai.tool.name and severityNumber mean what your existing tooling already expects.Changes within 1.0 are additive only: new attributes and new eventName values may appear at any time. A rename, a retype or a removal bumps the URL instead.See Event schema.lua drains
lua drains
list, status, deliveries, create, update, delete, test, verify, pause, resume and rotate-secret, each with --json.--sources, --min-severity, --agents, --environments, --format json|ndjson and --sampling debug=<n>.Header values are prompted, or read from the environment with --header-from-env; they are never passed as flags, where a shell history or a CI log would keep them. The HMAC signing secret is not an input at all โ the platform mints it and prints it once, at create and again at rotate-secret.test and verify wait for the delivery itself rather than reporting success off the acknowledgement: the platform does the sending, so each polls for the outcome and, when nothing lands in time, exits 1 naming the command that will show it once it does. lua drains status exits 2 when any drain is failing, after printing, so it works as a CI guard. --org <id> picks the organization on every verb; without it the projectโs organization is used, or the credentialโs when it reaches exactly one.See lua drains and Log drains REST.Message bodies stay off until you turn them on
Message bodies stay off until you turn them on
user_message and agent_response sources carry what end users said and what the agent replied, so a drain sends the bodies only when you ask for them.--include-content prints an acknowledgement of what turning it on means โ the same words the dashboard shows โ and then requires a confirmation; --yes gives that confirmation non-interactively, and without either the command prints the acknowledgement and changes nothing.--no-include-content turns the bodies off again and leaves --sources exactly as they are, so the records keep arriving, marked as withheld, and you still see that a turn happened, on what channel and for which end user, without the words. Turning content off and naming a content source in the same update is refused: send the sources first, then --no-include-content.See lua drains.lua logs --since, --until, --environment and --follow
lua logs --since, --until, --environment and --follow
--since and --until take an ISO 8601 instant or a relative 15m, 2h, 7d, and are inclusive at both ends; a relative window is resolved by the platformโs clock, so a skewed machine cannot shift the window it asked for. --follow polls about every two seconds, ends at --until, is refused together with --page, and under --json prints one complete { logs, nextCursor, pagination } envelope per poll, so a reader can consume it a document at a time.--type now accepts all eighteen log sources, adding trigger, model-resolver, workflow, workflow-step and workflow-script. --type calls reads voice call records and ignores all four of the new flags.See lua logs and Read logs and debug an agent.Cursor paging on lua logs
Cursor paging on lua logs
nextCursor โ null once the window is exhausted โ so a script can page a moving log without skipping or repeating an entry, which page numbers cannot do while new entries keep arriving at the top.Above 10,000 matches the total is capped: pagination.totalCount reports 10000 with totalCountExact: false, and the page footer says so rather than quoting a page count derived from the cap.--page still works and is deprecated in favour of the cursor.See lua logs.Monitor packs for Datadog, Grafana and the OpenTelemetry Collector
Monitor packs for Datadog, Grafana and the OpenTelemetry Collector
What the channel lets the agent see in a conversation
What the channel lets the agent see in a conversation
Lua.request.conversation.access says whether the agent can read every message in this conversation, who its members are and the files shared in it, and names the provider permissions this conversation has not granted.In Microsoft Teams those permissions are granted per chat by whoever adds the app, while file access is a tenant-wide grant โ so a skill can branch on what it is allowed to see instead of inferring it from an empty result. The block is absent when the platform cannot determine it.See Lua and Teams permissions.๐ง Improvements
logs:read and logs:manage
logs:read and logs:manage
logs:read, and log drains need logs:manage. logs:manage is sensitive โ it carries destination credentials โ so a wildcard grant does not satisfy it and a key holds it only when it was granted by exact name.The scope each log route used before (knowledge:read on an agentโs logs, automations:read on a skillโs logs, analytics:read on the organizationโs logs and their CSV export) is accepted for two more releases. A request authorized that way still succeeds and answers with Deprecation: true, a Sunset date and a Warning header naming the scope it was authorized by, so a client can find out before the change bites.logs:read is not sensitive, so a key that already holds *:read has it and needs nothing re-minted. Only keys carrying knowledge:read, automations:read or analytics:read by exact name have to change.See Log drains REST and About credentials.The REST page parameter on the log routes is deprecated
The REST page parameter on the log routes is deprecated
nextCursor now, and paging with cursor reads a moving log without skipping or repeating an entry โ which page numbers cannot do while new entries keep arriving at the top.page query parameter still works and is deprecated. A request that passes it explicitly answers with a Deprecation header and a Link: <โฆ?cursor=โฆ>; rel="next" pointing at the cursor form, so a client finds out before the parameter goes. This is the REST parameter; the CLIโs lua logs --page is deprecated alongside it and still works, with the cursor the form to prefer.See Log drains REST.Stated log retention
Stated log retention
๐ Bug Fixes
lua logs --type accepts five sources it used to refuse
lua logs --type accepts five sources it used to refuse
trigger, model-resolver, workflow, workflow-step and workflow-script are valid log sources, but the CLI rejected them with a Valid values hint that did not list them. The accepted list is now the platformโs own, so a source the platform adds is a --type the CLI takes.In the other direction, mastra is gone from the help text: it was advertised there but was never an accepted value.lua workflows recompose prints the right figures
lua workflows recompose prints the right figures
(new).It now prints the number of steps rewritten and the version that was published โ and, when a later version supersedes it, names the version that actually holds the pin. --json output is unchanged and was always correct.lua workflows clear-gate no longer offers a success it could never reach
lua workflows clear-gate no longer offers a success it could never reach
clear-gate failed (NOT_GATED), exit 1 โ which is the documented contract. The CLIโs unreachable โnothing to clearโ exit-0 path is removed rather than made reachable.A run parked on a quota slot is no longer labelled as waiting for consent
A run parked on a quota slot is no longer labelled as waiting for consent
lua workflows watch and lua workflows logs printed โconsentโ for every park but two, including a run queued behind the concurrency quota โ so an operator was pointed at an approval nobody could give.Each park now reads as what it is, and a quota park says it clears on its own as a slot frees, oldest-gated run first. Exit codes are unchanged.NO_COLOR turns colour off everywhere
NO_COLOR turns colour off everywhere
NO_COLOR. lua logs, lua models, lua status, the sync and drift views and the setup prompts printed ANSI styling anyway; they now all follow the variable, so a CI log stays readable.Separately, LUA_WEBHOOK_URL is removed. It was defined but no command ever read it.See Environment variables.--skip-env-check says what it does
--skip-env-check says what it does
lua marketplace template --help still advertised --skip-env-check as skipping env-contract validation, which it has not done since the check moved to the platform. The option line now reads as the deprecated no-op it is. The flag is still accepted, so existing scripts keep working.๐ Notes
Known issues
Known issues
- None. The three issues listed under v3.36.0 โ the
recomposesuccess line,clear-gateon a run that is not gated, and a quota park labelled as consent โ are all fixed in this release.
v3.37.0
Released: September 20, 2026โจ New Features
See the model behind a Job step's cost, before you're charged for it
See the model behind a Job step's cost, before you're charged for it
lua workflows status --steps now shows the model a Job-tier step ran on, how it was chosen โ the stepโs own pin, the platform default, or your organizationโs default โ and its cost multiplier. lua workflows logs shows the same when a step claims.lua push workflow and lua workflows deploy flag a Job step with no pinned model with a job-model-default advisory, naming the model it will run on before the first charge.See What a Job step costs.lua workflows status prints a Tokens line, and --steps gains token columns
lua workflows status prints a Tokens line, and --steps gains token columns
Tokens: line under Budget: โ for example 4,812 uncached in ยท 261,004 cache read ยท 1,024 cache write ยท 3,190 out โ and the --steps table gains Uncached, Cached and Output columns.A figure the run recorded nothing for is left out rather than printed as zero.See Operate workflow runs.The Budget line reads the run's own plan, and a run that finishes past its cap says so
The Budget line reads the run's own plan, and a run that finishes past its cap says so
Budget: now follows the runโs own pricing instead of guessing from the unit shown, so it canโt describe a seat run in legacy-plan terms or the other way around.A run whose last step completes past the cap now prints finished past the cap on that line, rather than reading as a plain success.See Operate workflow runs.lua workflows logs shows the budget events
lua workflows logs shows the budget events
paused on its run budget, raised, finished past the cap โ naming the spend against the cap.See Operate workflow runs.๐ Bug Fixes
A seat-plan run parked before its first claim is no longer told to raise credits it doesn't have
A seat-plan run parked before its first claim is no longer told to raise credits it doesn't have
lua workflows raise-budget names the unit it raised
lua workflows raise-budget names the unit it raised
--credits flag keeps its name on both plans โ only the words around it changed.v3.36.0
Released: September 18, 2026โจ New Features
Lua.request.conversation โ who is in the group conversation
Lua.request.conversation โ who is in the group conversation
Lua.request.conversation is undefined on 1:1 turns, jobs, webhooks and triggers. Teams group chats now run as one shared conversation per chat, so User.getChatHistory() there returns what the whole group said. See Lua and Microsoft Teams.Choose a model per workflow step
Choose a model per workflow step
lua workflows view shows what each step asked for and what it resolves to today; lua workflows status adds a per-model roll-up of the runโs spend. A misspelled class, task class, trait or effort is refused by lua push before anything is sent.See Models and Choose a model per step.lua push workflow --apply-effort
lua push workflow --apply-effort
effort is recorded and counted in the estimate but not sent to the model until you push with --apply-effort. Versions pushed before, and runs in flight, are unaffected; push without the flag to go back.lua workflows policy models get|set
lua workflows policy models get|set
--compose on|off (may the composer assign models), --max-class (the class ceiling), --consent-actions (the consent threshold), --allow (the allowed models), --class-fast / --class-balanced / --class-strong (per-class overrides), --class-map (task class to model class), --pins class-only|allowed (may a composed workflow pin a model) and --fallback same-class|same-provider (where a failed call may fall back). Only the flags you pass are changed.lua workflows policy autonomy get|set
lua workflows policy autonomy get|set
get shows both what you set and what the platform actually applies. --clear restores a member to its default. lua workflows status shows Consent: auto (policy) with the envelope on a run that started this way. A start over any bound, or after the hourly allowance is spent, still asks.lua workflows clear-gate and lua workflows recompose
lua workflows clear-gate and lua workflows recompose
lua workflows clear-gate <runId> --kind model_policy clears a run parked because a step asked for a model class the current policy cannot resolve.lua workflows recompose <workflow> rewrites a workflow composed before model classes existed so its steps ask for classes, and publishes the result as a new version.lua models list --workflows
lua models list --workflows
More in workflow output
More in workflow output
lua workflows logsshows which model each step resolved to, and a policy warning when a pinned model outside your organizationโs allowed set was substituted.lua workflows startprints the consent card โ the per-step plan and the cost line โ on a start that needs consent.lua workflows status --stepsexplains an escalated approval: when an approval stepโs approver would have been the person who started the run and the workflow excludes them, the request now goes to your organizationโs admins instead of failing, and status says so.
๐ง Improvements
lua push and lua push all now push workflows and activate the pushed version
lua push and lua push all now push workflows and activate the pushed version
lua push skipped workflows entirely โ only lua push workflow sent them โ so a changed workflow could stay on an old version while the rest of the agent moved on. Workflows are versioned and activated on their own, so lua push now makes the workflow version it pushed live even without --auto-deploy, and says so.To roll back:lua workflows deactivate <name> pauses a workflowโs schedules and triggers without changing the live version.๐ Bug Fixes
lua workflows status --strict exits 6 on a gated run
lua workflows status --strict exits 6 on a gated run
--strict help text says so.๐ Notes
Known issues
Known issues
- The success line of
lua workflows recomposeprints the wrong figures;--jsonis correct. lua workflows clear-gateon a run that is not gated is refused by the platform rather than answering โnothing to clearโ.lua workflows watchandlua workflows logslabel a run parked on a quota slot as gated for consent; the exit code is right either way.
v3.35.0
Released: September 15, 2026โจ New Features
Request context in your tools and processors
Request context in your tools and processors
Lua.request now exposes the turnโs runtime context to your tools, preprocessors and postprocessors โ not just the model. Alongside Lua.request.channel and Lua.request.webhook, you can now read Lua.request.runtimeContext (whatever the caller passed as the requestโs runtimeContext, e.g. via LuaPop.init({ runtimeContext })), Lua.request.threadId, Lua.request.timezone, Lua.request.userId and Lua.request.agentId.๐ Bug Fixes
lua push persona hint corrected
lua push persona hint corrected
lua push now makes clear that a pushed persona is served immediately โ the push publishes it and points the agent at it in the same step.lua workflows recovery hint corrected
lua workflows recovery hint corrected
lua workflows no longer points to a recovery step that isnโt available; the hints describe the supported path.v3.34.0
Released: September 14, 2026โจ New Features
A preprocessor can end a turn silently
A preprocessor can end a turn silently
response is now optional on a block result. Return it with no response and the turn ends with nothing sent โ on every channel and in the web chat widget.Data to remember when a person last replied, and Lua.request.webhook?.payload to see the incoming event.Workflow agent nodes can take their model from the run input
Workflow agent nodes can take their model from the run input
model may be a single placeholder instead of a fixed model, so one workflow can run a different model per stage, chosen when the run starts:| is the default, used when the run input doesnโt supply a value. The whole model string must be the placeholder โ no prefix, suffix or second placeholder โ and initData is the only source it can read from.Job-tier steps must supply a default. Without one, lua push canโt check the model and the step is judged when it runs.New template parameter options for install wizards
New template parameter options for install wizards
paramsMeta:type: 'repositories'โ the installer picks repositories from an account theyโve already connected. Name the connection withconnection: 'github';maxcaps how many they can choose (1โ50, default 8).advanced: trueโ the parameter moves into a collapsed โAdvanced settingsโ section. A value thatโs been set still appears in review.group: { id, title, description? }โ parameters sharing agroup.idrender together as one card, in the order you declare them.
lua workflows deploy surfaces advisory warnings
lua workflows deploy surfaces advisory warnings
๐ Bug Fixes
Template self-audit settings are included when publishing
Template self-audit settings are included when publishing
selfAudit block in lua.skill.yaml was read but not sent with the publish, so published versions didnโt carry it.Leaving the block out still leaves the previous versionโs settings untouched โ it is not cleared.v3.33.0
Released: September 10, 2026โจ New Features
Sign out per device
Sign out per device
lua auth logout now ends the session on this device only; your other devices and apps stay signed in. --all ends every session for your account.See where you are signed in
See where you are signed in
lua auth sessions lists every device and app signed in as you; --json for scripts. lua auth sessions revoke <id> signs one of them out once per-device sign-out is enabled for your account; until then it points you to lua auth logout --all.Template publish updates consenting installs
Template publish updates consenting installs
Conditional template parameters
Conditional template parameters
showIf so installers only see it when another parameter has one of the listed values. Hidden parameters are not required.lua marketplace template show prints the condition beside each conditional entry.Triggers can start workflows
Triggers can start workflows
transform may return { startWorkflow: { name, input } } to start a workflow run instead of an agent turn. name accepts the workflowโs name or id. lua triggers shows the started run, and a โskipped, already in flightโ outcome when a run of that workflow is still going.Template schedules run as the installer
Template schedules run as the installer
schedule.runAs: 'system' on the workflow to keep a system run.ripwire read-only Job tool
ripwire read-only Job tool
ripwire, a read-only code-search tool that stays available on ro steps. Read-only Job steps can no longer run shell commands.Offloaded outputs say where to download them
Offloaded outputs say where to download them
lua workflows status prints the download route and the size or row count for a step or run output the engine stored out of band; --steps shows one line per offloaded step.๐ง Improvements
Chat-composed workflows cannot be deployed from the CLI
Chat-composed workflows cannot be deployed from the CLI
lua workflows deploy on a workflow composed in chat is refused with WORKFLOW_DYNAMIC. Compose it again in chat under the same name to change what runs.Typed passthrough errors in local runs
Typed passthrough errors in local runs
Integrations.passthrough under lua dev and lua test throws an error carrying code, statusCode, retryAfterSeconds, vendor and requestId beside the message, so skill code can branch on the code instead of the text.Vendor outages name the vendor
Vendor outages name the vendor
503 VENDOR_UNAVAILABLE naming the vendor and whether a retry is safe. The CLI hint says so instead of โthe Lua API could not be reachedโ.lua compile warns on a read-only step with no tools
lua compile warns on a read-only step with no tools
๐ Bug Fixes
A dead session heals itself
A dead session heals itself
lua auth logout.Model-provider refusals are a typed outcome
Model-provider refusals are a typed outcome
provider_rejected with a hint that says what to fix, instead of an error that looks worth retrying.lua workflows export writes a file lua compile accepts
lua workflows export writes a file lua compile accepts
$self agent reference, get a title on every approval and place container arms. The command compiles its own output before exiting 0.foreach.items accepts every supported source
foreach.items accepts every supported source
fromInit, fromStep and initData / stepResults references type-check. An unsupported source is refused with a named build error instead of a type error or a silently dropped page.Trigger-started workflows resolve by name
Trigger-started workflows resolve by name
startWorkflow that names the workflow no longer fails with WORKFLOW_NOT_FOUND.Workflows
Released: September 5, 2026 Platform changes for Lua Workflows shipped on September 4 and 5, 2026.โจ New Features
Declared connection keys (LUA-623)
Declared connection keys (LUA-623)
connection.resolved event and returned in the run detail. A key with no match fails the step with credentials_unresolved and a notice naming the integration to connect; an undeclared key fails lua push with connection-key-undeclared. Literal connection ids and template installs are unchanged.Declaring keys in a lua-cli project (and the same check at lua compile) needs the next CLI release; agent templates already declare them.See Connections.Goals from chat
Goals from chat
listWorkflowGoals, getWorkflowGoal, pauseWorkflowGoal, resumeWorkflowGoal, closeWorkflowGoal). setWorkflowGoal accepts a deterministic judge.predicate beside an agent judge, and maxRuns defaults to 3 when the user does not name one. unscheduleWorkflow refuses a goalโs cadence (goal_schedule): a goal is stopped by pausing or closing it, never by removing its schedule.See Goals.Composing workflows from chat
Composing workflows from chat
composeWorkflow teaches the node grammar (promptTemplate on agent nodes; ${initData.<field>} and ${stepResults.<stepId>.text} placeholders), and the validator names an unknown member (unknown-node-key) or a missing prompt (agent-prompt-template-required) with a repair.See Workflows from chat.๐ง Improvements
Step failures name the cause
Step failures name the cause
reason (provider_error, context_overflow, rate_limited, timeout, unknown), the providerโs status, a scrubbed message, the model and the coding-turn index - on the step.failed event, in the run detail and in lua workflows status --steps --json. From the next CLI release the formatted table shows them too:job-logs serves finished attempts
job-logs serves finished attempts
lua workflows job-logs - returns the persisted log for that attempt with a note saying so. A finished attempt with nothing persisted is a 404 JOB_LOGS_NOT_PERSISTED rather than a control-plane error. The CLIโs Note: line, the --follow stop on a finished attempt and the exit-3 handling follow in the next CLI release.sleepUntil is refused until the engine runs it
sleepUntil is refused until the engine runs it
sleepUntil node fails validation with node-type-unsupported-by-engine at push and in composed workflows alike (and at lua compile from the next CLI release). Use sleep with a duration in milliseconds.lua workflows goals and lua workflows schedules are coming in the next CLI release.
v3.30.0
Released: September 2, 2026โจ New Features
Know whether your message arrived
Know whether your message arrived
Channels.send, template, reaction and email send now returns a deliveryId and a status (queued, accepted, sent, delivered, read, failed). Read the current state later, and the reason category for a failure:Delivery events on every channel
Delivery events on every channel
message.sent, message.delivered, message.read and message.failed now receive them for SMS, email, Messenger, Instagram and the other channels, not only WhatsApp, with the full delivery in the payload.Safe retries
Safe retries
Model picker for template parameters
Model picker for template parameters
type: model so installers pick a model instead of typing a code.๐ง Improvements
delivered stays for compatibility
delivered stays for compatibility
delivered flag; prefer status, which keeps updating as receipts arrive.v3.29.1
Released: August 31, 2026๐ Bug Fixes
Email sign-in completes successfully
Email sign-in completes successfully
Large accounts can list and select agents
Large accounts can list and select agents
v3.29.0
Released: August 31, 2026โจ New Features
Sign in once with email
Sign in once with email
Choose the agent for each project
Choose the agent for each project
lua init to select an agent for a project. The selection stays in that projectโs lua.skill.yaml.Create or duplicate agents from the CLI
Create or duplicate agents from the CLI
๐ง Improvements
Moving from the v3.28.0 login flow
Moving from the v3.28.0 login flow
Keep using API keys for automation
Keep using API keys for automation
LUA_API_KEY, .env, or direct API-key setup.Scoped API keys
Released: August 27, 2026โจ New Features
Scoped API keys, alongside your existing keys
Scoped API keys, alongside your existing keys
403 response for a valid key whose role doesnโt cover the action.v3.28.0
Released: August 30, 2026โจ New Features
Create scoped CLI credentials
Create scoped CLI credentials
Require signed webhook requests
Require signed webhook requests
LuaWebhook. When configured, Lua verifies an HMAC-SHA256 signature over the exact request body before running the webhook. Existing webhooks without a key behave as before.Run tools and instructions during template lifecycle events
Run tools and instructions during template lifecycle events
LUA_TRIGGER_URL__<KEY>.Execute a skill tool directly from a trigger
Execute a skill tool directly from a trigger
Manage marketplace skills by organization
Manage marketplace skills by organization
๐ง Improvements
Send messages as the authenticated user
Send messages as the authenticated user
User.send() now targets the authenticated user without a separate profile lookup. Existing code needs no changes.Reuse connections during template installation
Reuse connections during template installation
Use scoped credentials across the CLI
Use scoped credentials across the CLI
๐ Bug Fixes
Reliable compiled-bundle uploads
Reliable compiled-bundle uploads
lua push fail while uploading compiled bundles.Webhook turns reach the bound user
Webhook turns reach the bound user
v3.27.0
Released: August 25, 2026โจ New Features
Connect an integration once, as yourself
Connect an integration once, as yourself
lua integrations connect now asks who should own the connection.--scope still connects to the agent, so existing scripts keep their meaning.See and manage your personal connections
See and manage your personal connections
Re-home a connection you already made
Re-home a connection you already made
๐ง Improvements
Options that cannot apply are refused up front
Options that cannot apply are refused up front
--triggers, --custom-webhook, --hook-url, --account-label or --hide-sensitive with --scope user now fails immediately, naming the flags โ rather than partway through a browser sign-in. The interactive prompts for those steps are skipped in that scope too.The personal catalog only offers what can be yours
The personal catalog only offers what can be yours
Channels.send documents conversationId
Channels.send documents conversationId
Channels.send typings now describe addressing a shared Teams conversation with conversationId, alongside the existing per-person options.v3.26.0
Released: August 24, 2026โจ New Features
lua marketplace template draft โ compose your template's manifest instead of hand-writing it
lua marketplace template draft โ compose your template's manifest instead of hand-writing it
template: section into lua.skill.yaml, inferred from your agent: the connections its skills use, {{variable}} slots detected in the persona, trigger presets with their current on/off state as recommended defaults, and display metadata for install-time parameters.draft merges additively โ newly inferred entries are appended and your hand-edits are never modified โ and prints a per-section added/kept diff. Pass --force to replace the authored sections wholesale, and --source-version <n> to compose from a specific promoted agent version. See Publishing Templates.Publishes are linted before a version number is spent
Publishes are linted before a version number is spent
{{variables}}, invalid schedule intervals, unknown connection platforms or scopes, duplicate keys, and secrets in frozen code all reject with actionable per-field errors โ and a rejected publish burns no version number. Publishing from a source agent with voices or device triggers is rejected with a message saying why (voice agents canโt be templated yet).Deploy a template as a brand-new agent
Deploy a template as a brand-new agent
{{variables}} are filled in from your answers, connections youโve already granted are reused automatically, and automations only arm after an explicit confirmation. See Deploying Templates.Integrations.passthrough โ raw provider API through your connected integrations
Integrations.passthrough โ raw provider API through your connected integrations
{ status, headers, data } envelope: provider errors such as a 403 on a missing OAuth scope are relayed faithfully in status, never thrown. Every connected integration also gains a matching {integration}_passthrough agent tool.๐ง Improvements
--skip-env-check retired
--skip-env-check retired
lua env or --env-vars instead.v3.25.0
Released: August 19, 2026โจ New Features
Declare what your agent does, in code
Declare what your agent does, in code
LuaAgent accepts an optional description โ a short capability summary that Spaces read when deciding which member agent to hand a request to:lua push:description and a value set in the dashboard is left untouched, so existing projects are unaffected. Set it to an empty string to clear it.Put a card on a user's desk with User.Inbox.push()
Put a card on a user's desk with User.Inbox.push()
key lands on the existing card instead of knocking twice, and reaching the daily limit returns { outcome: 'capped' } rather than throwing.See the Inbox API reference for card kinds, limits and the full receipt contract.v3.24.0
โจ New Features
Declared indexes for the Data primitive โ filtered queries on large collections no longer degrade silently. Declare the fields you filter on where you store data, and the platform builds and maintains an agent-scoped database index for them:Data.create()/Data.update()/patch()accept{ searchText?, index? }(the legacy positionalsearchTextstring still works)- New
Data.collections()lists your collections with entry counts and index status (pending | building | ready | failed | rejected+ reasons) - Indexes build within minutes, stay alive while your agent uses them (writes or filtered reads), and are removed automatically ~14 days after all usage stops โ no cleanup code
- Limits: 2 fields per index, 3 declarations per call, 5 indexes per agent; invalid declarations are rejected visibly, never silently trimmed
- Filtered queries that exceed the time budget on an undeclared field now fail with an error naming the collection, the field, and the exact declaration to add โ instead of an opaque 502
{ searchText?, index? }) described above works in local development runs only. In a deployed agent, Data.create() and Data.update() accept a plain searchText string as the third argument, and passing an object fails with searchText must be a string. Keep deployed code on the string form until index declarations are supported in the deployed runtime; Data.create() tracks the current state.
v3.23.2
Released: August 14, 2026๐ Bug Fixes
Administrators can clear another user's agent conversation again
Administrators can clear another user's agent conversation again
--user with a user ID, email address, or mobile number when you have organization management permission for the agent:--user, the command continues to clear only your own conversation history.v3.23.0
Released: August 7, 2026โจ New Features
Target and update another user's stored data safely
Target and update another user's stored data safely
update(), save(), and clear() are target-bound too. Existing User.get() calls without an identifier still use the current conversation user, and update() keeps its merge behavior.Patch or delete Custom Data entries
Patch or delete Custom Data entries
searchText: null also removes the entryโs semantic-search text.๐ Bug Fixes
Targeted User writes update the selected user
Targeted User writes update the selected user
Job timeouts are validated and honored consistently
Job timeouts are validated and honored consistently
LuaJob.timeout accepts whole seconds from 1 through 600 and defaults to 300 seconds.v3.22.0
Released: July 28, 2026โจ New Features
Skill-level condition โ hide a whole capability
Skill-level condition โ hide a whole capability
LuaSkill now accepts the same optional condition as LuaTool, one level up:false, the skillโs tools canโt be called and the skillโs name, context, and tool names are left out of the agentโs prompt entirely โ the agent doesnโt know the capability exists. A tool-level condition only makes a tool uncallable; the skillโs name and context stay in the prompt, so the agent can still say โโฆbut youโre not enrolled, so I canโt do thatโ. Reach for the skill-level gate when the existence of a feature is itself sensitive: tiering, entitlements, per-customer capabilities.Evaluated per message, per user, with the full Platform API available. Fail-closed โ a condition that throws or times out hides the skill. Skills without a condition are unaffected. See Conditional Skills.Send a template media header by Meta media id
Send a template media header by Meta media id
image_id, video_id and document_id sit alongside the existing image_url / video_url / document_url keys โ an id is used in preference to a URL when both are given, and document_filename still applies either way.๐ Bug Fixes
Skills written with method shorthand keep their condition
Skills written with method shorthand keep their condition
async condition() { ... } now behaves the same as condition: async () => { ... }. Previously the condition was dropped and the skill failed to build.v3.21.0
Released: July 24, 2026โจ New Features
Agent templates on the marketplace
Agent templates on the marketplace
lua version promote, and manifest inspection.Private marketplace skills
Private marketplace skills
--visibility private to make it visible and installable only within your organization.๐ง Improvements
Unified marketplace command
Unified marketplace command
lua marketplace [skill|template] <action> replaces the previous create/install role menus with one flat action namespace per domain. Two actions were renamed: viewing your own listings is now mine, and editing listing metadata is now edit. See the marketplace command reference for the full old โ new migration table.Subcommand --version flags fixed
Subcommand --version flags fixed
lua marketplace template view --version 2 previously printed the CLIโs own version instead of selecting a version. The CLIโs version flag is now -V / --cli-version (bare lua --version still works).๐ Changes
lua chat clear --user removed
lua chat clear --user removed
--user is passed.v3.20.0
Released: July 21, 2026โจ New Features
lua version status โ what's live vs what's local
lua version status โ what's live vs what's local
lua version create + lua version promote (or lua deploy <type> for a single primitive), while local files older than whatโs live get a lua sync recommendation โ with a warning that deploying older files would roll production back.WhatsApp message reactions
WhatsApp message reactions
๐ง Improvements
lua deploy always takes effect for versioned agents
lua deploy always takes effect for versioned agents
lua deploy now automatically creates and promotes a new agent version scoped to the deployed primitive โ the deploy is live immediately and shows up in lua version list. The success output includes the promoted version, and if the live version canโt be updated the deploy fails with a clear message instead of reporting success.Integration connections show paused state
Integration connections show paused state
v3.19.0
Released: July 3, 2026โจ New Features
Per-request timezone on chat requests (PRO-258)
Per-request timezone on chat requests (PRO-258)
clientContext.timezone field โ an IANA timezone string. When provided, the agent uses it as the userโs local timezone for date/time-aware responses; when omitted it falls back to the userโs stored profile, country, or UTC.Agents.invoke. See HTTP API and Agents API.LuaAgent({ modelSettings: { reasoning } }) โ per-agent reasoning effort
LuaAgent({ modelSettings: { reasoning } }) โ per-agent reasoning effort
effort is one of 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'max'. Left unset, it defaults to adaptive reasoning where the model supports it and an explicit low effort otherwise, favoring lower cost/latency on turns that donโt ask for deeper thinking. show controls whether the reasoning trace is surfaced to the caller (default true). A per-request reasoning override always takes precedence over this agent-level default. See LuaAgent โ modelSettings and Model Selection โ Reasoning Effort.Team.findMember() โ reach a teammate without their number
Team.findMember() โ reach a teammate without their number
Channels.send to message them directly โ no hard-coded phone numbers.targets[] (empty if the teammate hasnโt opted in to sharing anything).browser switch on LuaAgent โ give your agent a browser
browser switch on LuaAgent โ give your agent a browser
browser: true to give your agent browser tools like searchWeb, routed to the userโs connected desktop browser when available, or a cloud fallback otherwise.true for policy: engine ('auto' default, 'agent-browser' for local-only, 'browser-use' for cloud-only), allowedDomains, credentials (named vault entries โ never raw secrets), and maxSessionMinutes. Off by default โ a browser session costs money and carries risk, so itโs opt-in.๐ Bug Fixes
lua version create no longer false-blocks on a no-op counter
lua version create no longer false-blocks on a no-op counter
version create could previously refuse with โno staged changesโ even when you had real changes to snapshot, or silently accept a run with nothing to snapshot. It now diffs the actual content against the previous version โ including a rename with no other change. When thereโs genuinely nothing new, it now tells you so plainly instead of throwing an error. lua version diff also shows voice changes, and the โโauto-deploy was ignoredโ notice now appears in the final push summary, not just at the very top.v3.18.0
Released: June 22, 2026โจ New Features
Channels API โ agent-initiated messaging
Channels API โ agent-initiated messaging
Triggers โ paste-anywhere URLs that invoke your agent
Triggers โ paste-anywhere URLs that invoke your agent
verify โ filter โ transform pipeline and get a pasteable URL that wakes your agent on any external event โ no execute function required.lua triggers create --name daily --instruction "Reply with today's date" creates a URL trigger with no SDK.Agent-native outbound messaging
Agent-native outbound messaging
outboundChannels feature:current_user (message only the person itโs talking to) or anyone (message recipients it specifies).Voice: exclude tools and hand off calls
Voice: exclude tools and hand off calls
WhatsApp template image/video/document headers
WhatsApp template image/video/document headers
format: 'IMAGE', 'VIDEO', or 'DOCUMENT' and provide a sample media URL for approval (must be publicly reachable HTTPS and within Metaโs size/MIME limits).When sending, use values.header.image_url for IMAGE templates, values.header.video_url for VIDEO templates, or values.header.document_url (with optional document_filename) for DOCUMENT templates:๐ง Improvements
Pasted and dragged images in emails now reach your agent
Pasted and dragged images in emails now reach your agent
[image: โฆ] text placeholder, with no image part. They are now forwarded to your agent as image parts, the same way paperclip attachments are.The rules:- The embedded image must be referenced in the emailโs HTML body and be at least 1 KB (spacer pixels are filtered out)
- Up to 10 embedded images per email are forwarded; regular attachments are unaffected
- Remote-hosted images (e.g. Gmail signature images, which are hosted rather than embedded) are not fetched
- Attachments mislabeled as embedded content by some clients are detected and forwarded as normal attachments
[image: โฆ] placeholder still appears in the message text โ use the image part, not the placeholder. See Email Channel โ Attachments and Embedded Images.v3.17.2
Released: June 1, 2026๐ Fixes
GitHub account linking now works
GitHub account linking now works
lua git auth github now links your GitHub account reliably using GitHubโs
device flow โ a code is shown in your terminal that you enter at
github.com/login/device.โจ New Features
Enable auto-push with one command
Enable auto-push with one command
lua git connect --auto-push enables pushing each auto-commit to your
linked GitHub repository. It checks that a GitHub account is linked and that
your origin is a GitHub HTTPS remote before turning auto-push on, so a
missing link or remote is reported immediately.git block in lua.skill.yaml is managed by these commands โ you no
longer need to edit it by hand. See the Git Command
documentation for details.v3.17.1
Released: May 29, 2026โจ New Features
LuaAgent({ modelSettings }) โ per-call sampling settings
LuaAgent({ modelSettings }) โ per-call sampling settings
temperature, topP, topK, maxOutputTokens, presencePenalty, frequencyPenalty, stopSequences, and seed โ forwarded to the model on every chat turn.temperature outside 0..2, topP outside 0..1, non-positive maxOutputTokens, non-string stopSequences) are rejected at construction time. Provider-specific range checks are deferred to the provider.AI.generate({ structuredOutput }) โ JSON Schema-constrained output
AI.generate({ structuredOutput }) โ JSON Schema-constrained output
result.output. No more โrespond with JSON onlyโ prompts and no more JSON.parse boilerplate.google_search tool is suppressed when structuredOutput is set (Vertex does not allow mixing function-calling tools with google_search).Named type exports for AI and LuaAgent
Named type exports for AI and LuaAgent
AiGenerateInput, AiGenerateOutput, AiGenerateStructuredOutput, AgentModelSettings, and sub-shapes (AiGenerateJsonSchema, AiGenerateSource, AiGenerateToolCall, AiGenerateToolResult) are now importable directly from lua-cli.v3.5.0-alpha.2
๐ง Improvements
Email channel now exposes parsed message metadata
Email channel now exposes parsed message metadata
Lua.request.webhook.payload is now populated for inbound emails with a JMAP-aligned object containing parsed message metadata.headerLines, and all threading metadata (messageId, inReplyTo, references). See the API reference for the complete shape and AgentMail divergence note.v3.16.0
Released: May 19, 2026โจ New Features
Voice agents via LuaVoice
Voice agents via LuaVoice
LuaAgent. Supports cascaded (STT/LLM/TTS) and realtime (speech-to-speech) shapes, with hooks for onEnter, onUserTurnCompleted, onExit, and voice-only tools.LuaAgentโs voices: [supportVoice]. lua push ships it through the same versioned-primitive flow as skills and webhooks.lua channels phone โ interactive phone-number provisioning
lua channels phone โ interactive phone-number provisioning
lua voice test โ deterministic voice-agent testing
lua voice test โ deterministic voice-agent testing
lua voice terminal / lua voice browser โ local dev
lua voice terminal / lua voice browser โ local dev
lua logs --type calls โ voice call logs
lua logs --type calls โ voice call logs
lua logs picker.lua-cli/voice โ LiveKit plugin namespaces
lua-cli/voice โ LiveKit plugin namespaces
lua-cli so you donโt need a direct LiveKit dependency in your project:๐ง Improvements
Voice version updates take effect immediately
Voice version updates take effect immediately
lua push voice is enough โ the next
call uses the new version. No need to re-push the agent.๐ Notes
Server compatibility
Server compatibility
lua push.v3.15.3
Released: May 12, 2026โจ New Features
lua push --include-source / --no-include-source
lua push --include-source / --no-include-source
v3.15.2
Released: May 8, 2026 If youโre upgrading from v3.15.1, upgrade directly to v3.15.2 (or later). v3.15.1 has a startup crash on fresh installs from npm.๐ Bug Fixes
lua-cli no longer crashes on startup with Cannot find package 'axios'
lua-cli no longer crashes on startup with Cannot find package 'axios'
npm install [email protected], not just the new lua source subcommands. v3.15.2 removes the dependency entirely โ the affected paths now use the same HTTP layer as the rest of the CLI, so install size and dependency footprint are unchanged from v3.15.0.If you were stuck on v3.15.0 because of this, you can upgrade safely now:v3.15.1
Released: May 7, 2026 This release has a startup crash on fresh installs from npm. Upgrade directly to v3.15.2 or later.โจ New Features
lua source list and lua source rollback
lua source list and lua source rollback
v12 is never overwritten. After a rollback you have an explicit new version at the head representing โwe returned to v12 on this date.โAuto-backup-push after every primitive push
Auto-backup-push after every primitive push
lua push <primitive> now always runs a fresh-from-disk backup-push as the final step. If the backup fails, the command exits non-zero.No more silent partial success where the primitive landed on the server but your local source never reached the canonical store. This makes the CLI a reliable single source of truth for โthis version was pushed from this machine in this state.โ--fresh flag on lua push backup
--fresh flag on lua push backup
lua push backup calls. Use this when files have been written by the Builder or by any other out-of-band path that bypassed lua compile.๐ง Improvements
lua init restores from the latest active backup
lua init restores from the latest active backup
lua init against a Builder-managed agent could restore a backup days or weeks behind the actual runtime state because the Builderโs writes werenโt reaching the legacy backup manifest reliably.activeVersion tracked in lua.skill.yaml
activeVersion tracked in lua.skill.yaml
lua init and after every successful lua push, the CLI records the
serverโs active backup version into your local lua.skill.yaml. Foundation
for future staleness warnings (โlocal is behind serverโ) and for cross-machine
drift recovery.Fresh backups now include Builder-written files
Fresh backups now include Builder-written files
node_modules, .git, dist, dist-v2, .env, and lockfiles.Previously, the reconcile-only path re-hashed files already in the compiled manifest, missing anything written outside lua compile.๐ Bug Fixes
lua init no longer crashes on transient restore failures
lua init no longer crashes on transient restore failures
lua init continues with an empty workspace and tells you what failed, instead of aborting with an unhandled exception.Compiled output excluded from fresh backups
Compiled output excluded from fresh backups
dist-v2 directory is no longer accidentally pulled into fresh backups. Previously, every fresh backup included the entire compiled tree (bundles, per-file source copies, the manifest), inflating per-push size and contradicting the intent that compiled artifacts stay separate.v3.15.0
Released: May 6, 2026โจ New Features
Duplicate an existing agent
Duplicate an existing agent
lua push immediately. The new agent inherits its sourceโs LLM model โ lua init no longer prompts for a model.Opt-in flags add more buckets to the copy:--org-id <target-org-id>.The interactive lua init flow (no flags) now offers โDuplicate an existing agentโ as a third choice alongside โCreate a new agentโ and โUse one of your existing agentsโ.Channel-aware personas
Channel-aware personas
lua sync --pull round-trips the object form back to your source file with all channel branches preserved.The new PersonaText type is exported from lua-cli for use in your own typings.๐ง Improvements
Clearer authentication errors
Clearer authentication errors
lua-cli now distinguishes between two very different conditions and tailors the remediation hint accordingly:- API key invalid or expired โ
Authentication failed. Run \lua auth configure` to set a new API key.` - API key valid, but no access to this agent โ
Access denied for this agent. Run \lua agents` to list agents you can access, or `lua init` to switch projects.`
Postprocessor priority is preserved on push
Postprocessor priority is preserved on push
priority on a LuaPostprocessor now correctly ships to production. In previous versions, the field was silently dropped during compile, so postprocessors always ran in their default order regardless of declared priority.No code change needed โ re-run lua push and your existing priority declarations now take effect.More resilient backup restore
More resilient backup restore
incorrect header check when one of its stored blobs was archived without compression. Uncompressed blobs are now passed through verbatim.Affects lua init --restore-sources, lua init --from-agent-id, and any other path that restores a project backup.Object personas round-trip faithfully
Object personas round-trip faithfully
- Voice-only personas now push. A persona of just
{ voice: '...' }(nobase, notext) is correctly applied. Earlier this was silently skipped as empty. lua sync --pullpreserves all channel branches. Pulling an object-form persona from the server and writing it back to local source no longer dropsvoiceortext.
๐ Bug Fixes
lua production no longer prints [object Object] for channel-aware personas
lua production no longer prints [object Object] for channel-aware personas
lua production now correctly displays personas using the new object form, instead of crashing on .length / .substring() calls or printing the literal string [object Object].Skills without a context push correctly under stricter validation
Skills without a context push correctly under stricter validation
context now push without error. Previously the
CLI would send an empty string and the server would reject it under the new
stricter persona/context validator.lua init writes valid TypeScript for string-form personas
lua init writes valid TypeScript for string-form personas
v3.14.0
Released: May 5, 2026๐ง Improvements
Reliable push for large agents
Reliable push for large agents
lua push now reliably uploads agents of any size, including those with many tools or large code bundles.Previously, agents that exceeded the upload size limit would fail mid-push with a โrequest too largeโ error. This no longer happens โ pushes succeed regardless of total bundle size.Applies to every primitive type:- skills (and their tools)
- webhooks
- jobs
- preprocessors / postprocessors
- devices and device triggers
lua push as usual.Faster, leaner pushes
Faster, leaner pushes
lua chat benefit from the same reduction.No action needed; the change is automatic with this release.v3.13.0
Released: April 29, 2026โจ New Features
lua status / lua describe โ full agent state at a glance
lua status / lua describe โ full agent state at a glance
lua status command (alias: lua describe) dumps the full state of your agent in one shot โ no more running five separate commands to understand whatโs going on.- Environment โ CLI version, install method, Node version, API base, env overrides
- Updates โ current vs latest published version
- Auth โ key source, email, user ID, org list, server reachability
- Project โ config path, agent name/ID, manifest primitive count
- Primitives โ per-type sync table: local version, server version, status (synced / ahead / behind / not deployed) for skills, webhooks, jobs, preprocessors, postprocessors, MCP servers, devices, device triggers
- Persona โ synced / drifted
- Backup โ synced / out-of-sync
- Telemetry โ enabled/disabled
- Next steps โ actionable hints based on current state
--json flag outputs a stable JSON document (schemaVersion: 1) suitable for LLM agent consumption or CI dashboards. All progress output is suppressed in JSON mode.Fuzzy command suggestions
Fuzzy command suggestions
Alias shorthands for common CLI arguments
Alias shorthands for common CLI arguments
lua logs --type pp is equivalent to lua logs --type postprocessor.Post-deploy debug coaching
Post-deploy debug coaching
- Error paths โ
๐ก Diagnose: run \lua logs โtype X โname Y โlimit 10โ pointing at the right log stream for what just failed. - Success paths โ
โจ Tip: run \lua logs โlimit 10โ nudges you to verify production execution. lua chatโ after each conversation turn, silently probes foragent_errorlogs. If any fired during that turn, prints:โ ๏ธ N new agent error(s) โ run \lua logs โtype agent_error` to inspect.`lua compileโ tip to runlua testafter a successful compile.lua sync --pushโ tip to verify withlua logsafter pushing.
LUA_NO_HINTS=1 lua push alllua test --json and shape headers
lua test --json and shape headers
lua test output:Shape headers โ the tool return value is now prefixed with its type and field names:--json flag โ outputs pure JSON on stdout, with all progress and compile output redirected to stderr. Enables clean piping:๐ Bug Fixes
Compiler: variable reference resolution (major fix)
Compiler: variable reference resolution (major fix)
โ
Compiled N primitives) but with the primitives silently absent from the manifest โ resulting in a broken agent after push.Version collision auto-retry
Version collision auto-retry
lua push all now automatically retries once when it encounters an โalready existsโ version collision. It re-fetches the current highest server version, bumps to the next one, and retries โ resolving the most common lua push all failure without any user intervention.Additionally, sandbox versions (e.g. 1.0.21-sandbox) are now correctly excluded when calculating the next production version bump.Orphaned primitives: delete and trigger
Orphaned primitives: delete and trigger
[server only]. Previously these orphaned primitives were invisible in menus, making them impossible to delete or trigger interactively.Non-interactive delete (lua preprocessors delete --preprocessor-name X) also now falls back to server data for all primitive types.The orphan warning message now shows the exact delete command to use:lua compile: tools no longer get empty schemas on corrupted installs
lua compile: tools no longer get empty schemas on corrupted installs
zod is now bundled with the CLI. Previously, if your node_modules/zod was corrupted โ by a partial install, a dependency conflict, or switching branches mid-install โ every tool got an empty inputSchema: {} and the compile printed โ
Compiled N primitives anyway, shipping a broken agent silently.Now:- The bundled copy is used first and is immune to
node_modulescorruption. - A local
node_modulesfallback is tried second. - If both fail, compile aborts immediately with a clear reinstall hint before any primitive is processed.
Monorepo backup, log types, and other fixes
Monorepo backup, log types, and other fixes
- Monorepo backup โ
lua push backupnow captures source files imported from cross-package paths in a monorepo and restores them to.lua/external/onlua sync --accept. - Log type
runtimeโ The log source previously calledmastrais nowruntime. Uselua logs --type runtime(was--type mastra). - New log types โ
lua logs --type ragandlua logs --type device-triggerare now valid filter values. - Startup warnings eliminated โ Extraneous warnings that appeared on every CLI command have been removed.
- Skill sandbox stale ID โ Sandbox sessions that expire after 24 hours no longer show a misleading โrun lua push firstโ message. The CLI now recovers automatically.
lua inittemplate fixes โData.updateandProducts.searchusage in the scaffolded template was corrected.
v3.12.3
Released: April 24, 2026โจ New Features
heylua and lua-ai as additional CLI aliases
heylua and lua-ai as additional CLI aliases
lua, heylua, and lua-ai. Users who have the Lua programming language
interpreter installed (which also claims the lua command) can run heylua
or lua-ai without any conflict or post-install workaround. Existing
scripts using lua continue to work unchanged.v3.12.2
Released: April 23, 2026โจ New Features
@filepath attachments in lua chat
@filepath attachments in lua chat
@<path> syntax โ in both interactive and non-interactive mode.@ token is stripped from the message text โ only the file is forwarded alongside any remaining text.Supported types include: .png, .jpg, .gif, .webp, .heic, .pdf, .docx, .xlsx, .ppt, .csv, .json, .html, .txt, .md, .eml, and more. Files with unsupported extensions are left in your message as plain text. Email addresses ([email protected]) are never mistaken for file paths.Maximum attachment size: 10 MB per file. Multiple attachments per message are supported.v3.12.1
Released: April 22, 2026๐ Bug Fixes
lua init no longer waits 30 seconds after creating an agent
lua init no longer waits 30 seconds after creating an agent
lua init now completes immediately after the server responds. The agent persona is read directly from the create API response.Model set at agent creation time
Model set at agent creation time
v3.12.0
Released: April 22, 2026โจ New Features
lua triggers โ pause and resume integration triggers
lua triggers โ pause and resume integration triggers
lua triggers is now a top-level command (alias for lua integrations webhooks) that lets you manage your integration triggers directly from the CLI.New pause and resume subcommands let you suspend or restore triggers individually or for an entire connection:๐ Bug Fixes
Skills compilation โ skills now push correctly
Skills compilation โ skills now push correctly
defineSkill) were silently dropped from the compiled manifest because they were fed through esbuild like tools and webhooks. Skills are metadata-only (name, description, context, tool refs) and do not contain executable code. They now produce a JSON metadata artifact and flow through the full pipeline. Resolves the circular failure: lua push skill โ โno server ID, run lua compileโ โ โnot found in manifestโ.MCP server ID tracking in lua.skill.yaml
MCP server ID tracking in lua.skill.yaml
lua.skill.yaml immediately after a successful push, so the server is never treated as an orphan on its first deploy. Re-pushes are fully idempotent.v3.11.0
Released: April 21, 2026โจ New Features
Agents.invoke API for agent-to-agent calls (BAC-107)
Agents.invoke API for agent-to-agent calls (BAC-107)
Standalone defineDeviceTrigger primitive
Standalone defineDeviceTrigger primitive
Governance SDK Integration
Governance SDK Integration
lua governance add and lua governance remove commands to configure runtime enforcement of governance policies for your agents.๐ Bug Fixes
Device Trigger Names
Device Trigger Names
Push Backup Refusal
Push Backup Refusal
v3.10.0
Released: April 16, 2026โจ New Features
lua models command โ manage your agent's LLM model (LUA-268)
lua models command โ manage your agent's LLM model (LUA-268)
lua models list shows all approved models grouped by provider, with the current model highlighted. lua models set writes the chosen model into your src/index.ts and syncs it to the server. lua models unset removes the model property and clears it on the server.lua devices command โ bidirectional agent-device communication
lua devices command โ bidirectional agent-device communication
lua push device or include them in lua push all. Connect hardware or virtual devices using @lua/device-client.All actions support interactive mode โ omit --device-name to choose from a picker.Sync pull conflict guard
Sync pull conflict guard
lua sync --accept now detects files you have modified locally since the last lua push backup and refuses to overwrite them.lua push backup, a local cache of file hashes is stored in .lua/backup-manifest.json. The guard compares this cache against your current files and only flags files that were actually modified.If no backup has been run yet, the pull proceeds with a warning rather than failing.Persona guide template for new agents (LUA-271)
Persona guide template for new agents (LUA-271)
lua init now receive a structured persona template instead of "Placeholder persona". The template includes suggested sections โ identity, tone, audience, capabilities, boundaries, and guidelines โ each with guidance notes to help you write an effective persona. It is designed to be reshaped or replaced entirely.๐ Bug Fixes
Sync conflict detection always triggered even with no local changes
Sync conflict detection always triggered even with no local changes
lua sync --accept exited 0 in CI even when restore failed
lua sync --accept exited 0 in CI even when restore failed
๐ง Improvements
--force flag for lua sync to bypass conflict guard
--force flag for lua sync to bypass conflict guard
lua sync --accept --force (or lua sync --force) to intentionally
overwrite local changes when pulling from the server.v3.9.3
Released: April 15, 2026โจ New Features
Model selection in lua init (LUA-262)
Model selection in lua init (LUA-262)
lua init.Interactive mode: a searchable, provider-grouped model list appears after org and name selection. Select a model or skip to use the server default.Non-interactive mode:src/index.ts and synced to the server. Works correctly across fresh init, re-init, backup restore, and agent-switch flows.๐ Bug Fixes
MCP sync pull now works
MCP sync pull now works
lua sync --accept and interactive pull for MCP servers were silently no-ops โ servers created via the dashboard were never written to local YAML even when drift was detected. Fixed: MCP servers missing locally are now correctly added to YAML on pull.lua push mcp suggestion fix
lua push mcp suggestion fix
lua sync, the push suggestion for MCP servers was lua push mcpServer --name "X" (invalid command). Fixed to lua push mcp --name "X".๐ง Improvements
lua init wording clarity
lua init wording clarity
v3.9.0
Released: April 13, 2026๐ง Improvements
CI/CD-friendly authentication โ no keychain required (LUA-258)
CI/CD-friendly authentication โ no keychain required (LUA-258)
keytar (OS keychain) has been removed. The CLI now works on headless Debian, Docker, and VMs without any native system dependencies.API key resolution order:LUA_API_KEYenvironment variable~/.lua-cli/credentialsfile (written bylua auth configure).envfile values
lua auth configure once to store your key in the new location. Your previous key stored in the OS keychain is not migrated automatically.v3.8.0
Released: April 8, 2026โจ New Features
Webhook event subscriptions (BAC-131)
Webhook event subscriptions (BAC-131)
sent, delivered, read, failed, played.Generic multi-primitive deploy (BAC-137)
Generic multi-primitive deploy (BAC-137)
lua deploy now mirrors lua push [type] โ deploy any primitive interactively or directly:--name (replaces --skill-name) and --set-version (replaces --skill-version). Deprecated aliases kept for backwards compatibility.๐ Bug Fixes
Jobs short flags and live status (BAC-94)
Jobs short flags and live status (BAC-94)
lua jobs deploy -i myJob -v latest now works correctly โ -i and -v are registered as short flags for --job-name and --job-version. The activate/deactivate selection list now shows the live server status badge next to each job.Active version comparison for all primitives
Active version comparison for all primitives
activeVersionId, causing the active version to not be highlighted correctly.
Fixed to use the versionโs own ID in all cases.Webhook unsubscribe event type validation
Webhook unsubscribe event type validation
lua webhooks events unsubscribe now show a clear validation error instead of a misleading โnot subscribedโ message.v3.7.5
Released: March 30, 2026โจ New Features
Per-agent message batching (BAC-113)
Per-agent message batching (BAC-113)
lua chat flags for testing:v3.7.4
Released: March 27, 2026๐ Bug Fixes
Keychain authentication reliability
Keychain authentication reliability
Inline comment stripping in .env files
Inline comment stripping in .env files
.env parsing now correctly strips inline comments: LUA_API_KEY=abc # my comment resolves to abc.v3.7.3
Released: March 24, 2026๐ง Improvements
HTTP retry with exponential backoff
HTTP retry with exponential backoff
Reduced package size
Reduced package size
lua dev web UI command and unused dependencies, significantly reducing install size.๐ Bug Fixes
Chat stream timeout
Chat stream timeout
v3.7.2
Released: March 24, 2026โจ New Features
Isolated AI text generation โ AI.generate (BAC-14)
Isolated AI text generation โ AI.generate (BAC-14)
AI.generate API for running text generation from within tools, aligned with Vercel AI SDK generateText semantics.Simplified โ returns plain text:google/* (Vertex AI), openai/*, anthropic/* โ with automatic fallback if the requested providerโs API key is missing.Google Search grounding is automatically attached for Google models.๐ง Improvements
Lazy keytar loading for WebContainer support
Lazy keytar loading for WebContainer support
LUA_SKIP_KEYCHAIN is set. Fixes MODULE_NOT_FOUND errors in StackBlitz WebContainers and browser sandboxes.v3.7.0
Released: March 20, 2026โจ New Features
Chat thread isolation
Chat thread isolation
lua chat -t or --thread <id> for isolated sessions. lua chat clear --thread <id> clears one thread. Omit the thread ID with -t to auto-generate a UUID.Auto-clear chat history
Auto-clear chat history
--clear / --clear-thread clear history when the session endsโuseful after testing without running lua chat clear separately.๐ Bug Fixes
Model cleared when removed from agent
Model cleared when removed from agent
model from your agent now clears the server-side model (BAC-87).Features help and examples
Features help and examples
inquiry instead of deprecated tickets).v3.6.7
Released: March 15, 2026๐ Bug Fixes
MCP integrations defaults (BAC-83)
MCP integrations defaults (BAC-83)
defer_tools is aligned with Unified.to expectations.Skill tool references
Skill tool references
v3.6.6
Released: March 11, 2026โจ New Features
Agent error filter in logs
Agent error filter in logs
lua logs --type agent_error to filter logs for execution errors in
tools, webhooks, and jobs.๐ Bug Fixes
Cron timezone and logs
Cron timezone and logs
v3.6.5
Released: March 10, 2026๐ง Improvements
Internal URL resolution
Internal URL resolution
v3.6.1
Released: March 2, 2026๐ Bug Fixes
Job Schedule Fields Now Preserved
Job Schedule Fields Now Preserved
interval and once job schedules now compile and push correctly. Previously, the seconds field (interval) and executeAt field (once) were silently dropped during compilation, causing lua push job to fail with:Agent Imported Primitive Resolution
Agent Imported Primitive Resolution
jobs: [new MyJob()]) now correctly resolve and
compile.CLI Exits Immediately
CLI Exits Immediately
v3.6.0
Released: February 27, 2026โจ New Features
Agent Model Selection
Agent Model Selection
LuaAgent now supports a model property to control which AI model your agent uses. Specify a static model string or a dynamic resolver function.google/*, openai/*, anthropic/*. Default: google/gemini-2.5-flash.Usage Telemetry
Usage Telemetry
lua telemetry command lets you control data collection:LUA_TELEMETRY=false in your environment. See Telemetry for details.๐ง Improvements
keytar as Optional Dependency
keytar as Optional Dependency
keytar (OS keychain access) is now optional. Fixes installation on CI/CD
systems without native build tools. Falls back to environment variables or
.env file.v3.5.0
Released: February 20, 2026โจ New Features
User Lookup by Email or Phone
User Lookup by Email or Phone
User.get() method now supports looking up users by email address or phone number, in addition to userId.Integrations Command
Integrations Command
- OAuth and API token authentication
- Automatic MCP server creation and activation per connection
- Event-driven webhook triggers that wake up your agent
- Server-side finalization for reliable connection setup
Webhook Triggers for Integrations
Webhook Triggers for Integrations
- Triggers pre-selected by default in interactive mode
- Choose between โAgent wake-upโ mode or custom webhook URLs
- Friendly labels for OAuth scopes and webhook events
- JSON output:
lua integrations webhooks list --json
Project Backup & Restore
Project Backup & Restore
- Content-addressed storage with automatic deduplication
- S3 direct upload โ no file size limits
- Efficient incremental backups (only changed files uploaded)
- Full project recovery on new machines
CI/CD Mode (--ci flag)
CI/CD Mode (--ci flag)
--ci flag makes the CLI fail loudly on missing required arguments instead of silently hanging in non-TTY environments.Self-Update Command
Self-Update Command
lua update command for self-updating from npm, plus a background outdated version warning on every command.- Background version check with 24h file cache (zero latency impact)
- Alpha users stay on alpha channel, stable users stay on latest
- Boxed warning to stderr when outdated
Agents Discovery Command
Agents Discovery Command
lua agents command lists all organizations and agents you have access to.Variable References in Primitive Config
Variable References in Primitive Config
Complete Push All โ Persona & Backup Included
Complete Push All โ Persona & Backup Included
lua push all now pushes everything including persona and backup:Auto-Add dist-v2/ to .gitignore
Auto-Add dist-v2/ to .gitignore
dist-v2/ to your .gitignore: - New
projects: Included in lua init template - Existing projects: Added
after first successful compilation - Idempotent and safe to run multiple timesMCP and Mastra Log Types
MCP and Mastra Log Types
๐ง Breaking Changes
These changes may affect existing scripts and workflows. Update accordingly.Push Flag: --version renamed to --set-version
Push Flag: --version renamed to --set-version
--version flag that shows CLI version.Compile Sync: --no-sync changed to --sync (opt-in)
Compile Sync: --no-sync changed to --sync (opt-in)
--verbose for detailed compilation output.๐ Improvements
Version Conflict Avoidance in Push
Version Conflict Avoidance in Push
lua push --force now automatically checks the server for the highest existing version.Benefit: Prevents โVersion already existsโ errors during automated deployments.Sync Compiles Before Checking Drift
Sync Compiles Before Checking Drift
lua sync now runs compilation first for more accurate drift detection.Chat Preprocessor Block Response
Chat Preprocessor Block Response
Consistent Error Messages
Consistent Error Messages
โก Performance
Parallel Server Sync During Compilation
Parallel Server Sync During Compilation
- Before: 6 sequential HTTP calls (~3-6s)
- After: All fetched in parallel (~1s)
Batch Version Checks in Push All
Batch Version Checks in Push All
Lazy Authentication
Lazy Authentication
๐ Bug Fixes
- Job Creation: Fixed
__exportsnaming collision when primitives calledJobs.create()at runtime - Backup Size Limit: S3 presigned uploads fix โrequest entity too largeโ for large projects
- MCP Server Duplicates: Intelligent URL merging handles concurrent MCP creation flows
- Email Channels: Aligned with updated API schema (mode selection, displayName, response types)
- Agent Config Arrays: Defining
jobs: MY_JOBSvia variables no longer silently empties the agent - Webhook headerSchema: Header validation schemas now correctly pushed to server
- Tool Conditions: Tools without
condition()no longer fail at runtime - MCP Server Push: Fixed detection, manifest metadata, and push pipeline (3 bugs)
- Auth Errors:
AuthenticationErrorproperly propagated; 403 Forbidden handling added - Compile Sync: Handlers no longer overwrite each otherโs IDs
- Marketplace: Only shows skills with published and approved versions
- Test Command: Fixed preprocessor test handling for object format
๐ Interface Updates
- Added
UserLookupOptionsfor email/phone lookup - Added
EmailChannelMode,CreateGeneratedEmailChannelResponse,CreateExistingEmailChannelResponse - Added
MCPServerSourceenum for tracking MCP server origin - Updated
User.get()return type toUserDataInstance | null - Added
'mcp'and'mastra'to log type enums
v3.4.0
Released: January 22, 2026โจ New Features
Non-Destructive Compile Sync
Non-Destructive Compile Sync
lua compile command now uses a safer, non-destructive sync pattern. Instead of automatically deleting primitives on the server that arenโt in your local code, it now:- Warns about orphaned primitives (skills, webhooks, jobs, MCP servers)
- Suggests using explicit delete commands
- Filters warnings to CLI-sourced skills only (ignores marketplace and manual skills)
New Delete Commands
New Delete Commands
'streamable-http'- Modern MCP standard (recommended)'sse'- Legacy Server-Sent Events transport
stdio transport are not supported yet. Use remote servers with streamable-http or sse instead.๐ Bug Fixes
- Push: Fixed crash when pushing primitives without a version field. First push now defaults to version
0.0.1and shows โ(none - first push)โ in prompts.
๐ Interface Updates
- Added
MCPStreamableHttpServerConfiginterface for streamable-http transport - Updated
MCPTransporttype to'sse' | 'streamable-http' - Added
SkillSourcetype:'cli' | 'marketplace' | 'manual' - Removed
MCPStdioServerConfig(stdio not supported yet)
v3.3.0
Released: January 20, 2026โจ New Features
Complete Non-Interactive Mode for All Commands
Complete Non-Interactive Mode for All Commands
- Consistent option naming:
--<entity>-nameand--<entity>-version --forceflag for skipping confirmation prompts--jsonflag for machine-readable output- Action arguments for entity management (view, versions, deploy, activate, deactivate)
User Message and Agent Response Log Types
User Message and Agent Response Log Types
url and headers resolver functions.Products.get() Filter Support
Products.get() Filter Support
Products.get() with backward compatibility:๐ Bug Fixes
- Chat: Allow
lua chatto work without mandatory skills - agents can now have only webhooks, jobs, or processors - Commands: Normalized action handling for case-insensitive action comparisons
๐ง Improvements
- Chat Command: Informational message when defaulting to sandbox environment
- Chat Command: Improved visual separation between compile logs and chat response
- Env Command: Proper error handling for save/delete operations
- Push Command: Shared helper functions reduce code duplication
v3.2.0
Released: January 13, 2026โจ New Features
Sync Command for Drift Detection
Sync Command for Drift Detection
lua sync command to detect drift between server and local code:- Compare agent name and persona between server state and local code
- Fetch latest published persona version (excludes drafts and rollbacks)
- Show colored line-by-line diff for easy comparison
- Interactive resolution: update local from server or continue with local
- Integrated into compile flow with
--no-syncand--force-syncflags
Chat History Clear Command
Chat History Clear Command
lua chat clear command to clear conversation history:Lua Runtime API with Channel Type
Lua Runtime API with Channel Type
Lua namespace for runtime access:'dev' | 'webchat' | 'whatsapp' | 'messenger' | 'voice' | 'api' | 'email'Lua.request.webhook for Raw Webhook Payload
Lua.request.webhook for Raw Webhook Payload
Marketplace Pagination
Marketplace Pagination
- Navigate through pages with Previous/Next options
- Shows page info (Page X/Y) and total count
- Configurable page size (default: 10 items)
๐ง Improvements
- Simplified Agent Creation: Streamlined
lua initflow with cleaner prompts - Better TypeScript Support: Improved handling of path aliases and variable references in your code
๐ Bug Fixes
- Fixed sync command occasionally showing false drift detection
- Fixed skill publishing issues
- Fixed compilation when skills are defined inline vs imported from separate files
v3.1.0
Released: December 7, 2025โจ New Features
MCP Server Support
MCP Server Support
LuaMCPServer class for integrating Model Context Protocol servers with your agent:lua mcp- List, activate, deactivate, or delete MCP serverslua push mcp- Push individual MCP servers- MCP servers included in
lua push all --force
Tool Conditions
Tool Conditions
condition function that determines if the tool is available:CDN API
CDN API
CDN namespace for uploading and retrieving files:Jobs API Enhancements
Jobs API Enhancements
Evaluations Dashboard
Evaluations Dashboard
lua evals command opens the Evaluations Dashboard with your agent
pre-configured. bash lua evals Templates API
Templates API
Templates namespace for WhatsApp template messaging:Marketplace CLI
Marketplace CLI
lua marketplace command for discovering, installing, and publishing
skills: For Creators: - Publish skills to the global marketplace - Version
management with semantic versioning - Environment variable configuration per
version For Installers: - Browse and search for verified skills - Smart
installation with dependency checks - Interactive environment variable
configurationEnhanced Logs Command
Enhanced Logs Command
lua logs command now features: - Interactive filtering by primitive type
(Skills, Jobs, Webhooks, etc.) - Live data from API including dynamically
created jobs - Context-aware log display with detailed metadataImmutable User Profile
Immutable User Profile
user._luaProfile property for read-only core user data:๐ฅ Breaking Changes
These changes may require updates to your existing code.JobInstance Restructured
JobInstance Restructured
JobInstance now receives the full Job entity with activeVersion:welcomeMessage Removed from LuaAgent
welcomeMessage Removed from LuaAgent
welcomeMessage field has been removed from LuaAgent configuration: -
For voice: use voiceConfig.welcomeMessage - For chat widgets: use
WebchatChannelConfig.welcomeMessageWebhook Execute Signature Changed
Webhook Execute Signature Changed
PreProcessor Response Redesigned
PreProcessor Response Redesigned
PreProcessorResult now uses a discriminated union:modifiedMessageis nowChatMessage[](array)- Added
priorityfield for execution order - Removed
contextfield
๐ง Improvements
- Data API Type Safety:
searchTextparameter added toData.create()andData.update(),dataparameter type changed toRecord<string, any> - PostProcessor Simplified: Return type now requires
modifiedResponse: string, removedasyncfield - Compilation: Handle
.jsextensions for Node16/NodeNext module resolution - Template: Minimal by default, use
--with-examplesflag for examples - Web UI: React Query, Sonner toasts, improved env panels, docs in toolbar
๐ ๏ธ Refactoring
- Removed
contextfield from webhooks, jobs, and postprocessors - Removed
versionfield fromLuaSkill,LuaJob, and processor configurations - Improved push command: displays both
webhookIdandwebhook-nameURL formats - Rewritten
interfaces/jobs.tsto matchlua-apiDTOs exactly
v3.0.3
Released: October 30, 2025๐ฏ User API Enhancement
EnhancedUser.get() method now accepts an optional userId parameter:
- Fetch data for specific users in admin tools
- Access user information in webhooks/jobs
- Multi-user data operations
- User management features
v3.0.2
Released: October 30, 2025๐ Major Improvements to Compilation System
This release brings comprehensive dependency bundling, debug mode, enhanced validation, and critical bug fixes.Comprehensive Dependency Bundling
Comprehensive Dependency Bundling
- โ LuaWebhooks bundle dependencies (e.g., Stripe, axios)
- โ LuaJobs bundle dependencies
- โ PreProcessors bundle dependencies (e.g., lodash)
- โ PostProcessors bundle dependencies (e.g., date-fns)
- โ
Nested Jobs (
Jobs.create()) independently bundle their own dependencies
Debug Mode
Debug Mode
--debug flag to lua compile command: bash lua compile --debug # or LUA_DEBUG=true lua compile Features: - Verbose step-by-step logging- Shows detected imports and dependencies - Displays bundle sizes (uncompressed and compressed) - Preserves temp files for inspection - Shows timing information for each component - Full error stack traces
Enhanced Validation
Enhanced Validation
- tsconfig.json validation - Clear error if missing or invalid - Empty bundle detection - Warns about suspiciously small bundles (under 100 bytes)
- Bundle output validation - Ensures esbuild creates valid output - Null config handling - Graceful compilation without lua.skill.yaml - Safe optional chaining - Fixed crash when agentData is null
Improved Error Handling
Improved Error Handling
Import Resolution
Import Resolution
resolveImportPath() to support:.ts,.tsx,.js,.jsxfiles- Directory imports (
index.ts,index.tsx,index.js)
๐ Bug Fixes
- Fixed null reference error when compiling without LuaAgent
- Fixed crash when lua.skill.yaml is missing
- Fixed compilation with empty agent name/persona
- Critical: Fixed relative import resolution in all component types
๐งน Code Quality
- Removed obsolete
dynamic-job-bundler.ts - Extracted common helpers (
extractRelevantImports,bundleAndCompressExecuteFunction) - Reduced bundling.ts from 1,149 to 1,036 lines (9.8% reduction)
- Added 27 comprehensive tests for bundling, execution, validation, and relative imports
v3.0.0
Released: October 2025๐ Major Release
Version 3.0.0 focuses on developer experience, deployment automation, and real-time chat capabilities.โจ New Features
LuaAgent - Unified Configuration
LuaAgent - Unified Configuration
- Single source of truth
- Clearer organization
- Automatic YAML synchronization
- Better IDE support
Streaming Chat Interface
Streaming Chat Interface
bash lua chat - โ
Animated
typing indicator while waiting - โ
Text streams character-by-character - โ
Sandbox and production environment selection - โ
Uses /chat/stream endpoint
for real-time updatesBatch Deployment
Batch Deployment
bash # Push all with auto-versioning lua push all --force # Push and deploy to production lua push all --force --auto-deploy What it does: 1. Compiles project 2.
Reads all components from lua.skill.yaml 3. Increments patch versions
automatically 4. Pushes all components to server 5. Deploys to production (if
--auto-deploy) Features: - Auto-bumps patch versions (e.g., 1.0.0 โ
1.0.1) - Perfect for CI/CD pipelines - Retry mechanism with exponential
backoffAPI Key Fallback
API Key Fallback
LUA_API_KEY) 3. .env File (LUA_API_KEY=...)
Usage in CI/CD: bash export LUA_API_KEY=your-key lua push all --force --auto-deploy Auto-Sync YAML and Code
Auto-Sync YAML and Code
lua init:- Agent name, persona โ YAML +
index.tsLuaAgent
lua compile:- LuaAgent persona โ YAML
๐ง Improvements
Enhanced Bundling
Enhanced Bundling
- Excluded lua-cli internals from bundles
- Reduced bundle sizes by 50-70%
- Fixed relative import issues
- Proper sandbox globals (tools use sandbox-provided APIs)
Jobs.create() Fixes
Jobs.create() Fixes
codefield now properly compressed and included - Execute function properly converts to strings - Excludes lua-cli imports from job execute functions - Better metadata support for passing data
Developer Experience
Developer Experience
- Comprehensive template with 30+ example tools
- Quick Start Guide for new users
- TypeScript examples with best practices
- CI/CD integration examples
๐ Bug Fixes
Bundling:- Fixed
Cannot find module '../services/ApiService'in pre-bundled tools - Fixed
process.cwd is not a functionin sandbox execution - Fixed lua-cli API code being bundled into tools
- Fixed webhooks and jobs not found during
push all - Fixed missing
toolsarray causing validation errors - Fixed deployment timing issues with retry mechanism
- Fixed welcome message reading from
lua.skill.yaml - Fixed streaming endpoint integration
- Fixed typing indicator cleanup on errors
๐ฅ Breaking Changes
These changes require updates to your existing code.LuaAgent Required
LuaAgent Required
- Wrap your existing skills in a
LuaAgent - Add
nameandpersonafields - Run
lua compileto sync with YAML
Chat Endpoint Changed
Chat Endpoint Changed
- Old:
/chat/generate/:agentId- New:/chat/stream/:agentIdNo action needed - handled automatically by CLI.
Jobs.create() Signature
Jobs.create() Signature
metadata for data passing:๐ Statistics
Upgrade Guides
From v3.0.x to v3.1.0
- Update
JobInstanceaccess patterns (useactiveVersion.schedule,idinstead ofjobId) - Update webhook execute functions to use event object
- Update PreProcessor responses to use discriminated union
- Remove
welcomeMessagefrom LuaAgent (configure on channel/voice instead)
From v2.x to v3.0.0
- Wrap skills in a
LuaAgentconfiguration - Update jobs to use
metadatafor data passing - Run
lua compileto sync with YAML

