- A project created with
lua initand signed in withlua auth configure(Install and sign in). - Any secret the job needs stored with
lua env production -k <KEY> -v <value>(About environments).
1
Create the job
Add a file under A job runs outside any conversation:
src/jobs/. schedule takes a cron expression and an optional IANA timezone; timeout is in seconds, from 1 to 600 (default 300); retry gives a failed or timed-out attempt more tries: each retry waits a fixed backoffSeconds, and the platform stops after 10 attempts (Jobs reference).src/jobs/DailyDigestJob.ts
User.get() with no argument has nobody to return, and job.user() resolves to the user recorded on the job, which for a declared job is never an end user. Reach an end user with User.get(userId) and an ID you stored earlier (Execution contexts).2
Register it on the agent
Only primitives referenced from
LuaAgent are compiled.src/index.ts
3
Run it once locally
lua test job compiles the project and runs execute on your machine straight away, ignoring the schedule; the platform APIs it calls are real.Output
4
Release it
lua push uploads a version and changes nothing for end users; lua version create snapshots the agent; lua version promote <n> makes that snapshot live and is also the rollback path (Release an agent to production).lua version create prints β Created v<n> (staged); in a script, n=$(lua version list --limit 1 --json --ci | jq -r '.[0].version') then lua version promote "$n". lua push all exits 0 even when a primitive fails; check its output for component(s) failed to push.5
Verify
Run the job immediately instead of waiting for 09:00, then read its history.
trigger prints the execution ID and leaves the schedule unchanged. history prints π Execution History for daily-digest and the last 20 runs, newest first, each as a status line such as β
COMPLETED, then Started, Completed, Duration, and Result: with the first 100 characters of what execute returned. lua logs --type job --name daily-digest --limit 5 shows what the run logged.Options you may need
Run once or at an interval
Two other schedule shapes exist:{ type: 'once', executeAt: '2026-10-01T09:00:00Z' } runs a single time at a Date or ISO string, and { type: 'interval', seconds: 300 } runs every fixed period.
Create a job from a tool
Jobs.create makes a job while the agent runs, stores it as version 1.0.0, and starts it unless you pass activate: false. Its execute function is sent to the platform as source text, so it cannot read variables from the tool around it: put what it needs in metadata and read job.metadata inside. A dynamic job remembers the end user who was in the conversation, and job.user() returns them.
src/skills/tools/RemindMeTool.ts
reminder - <timestamp> (reminder_<timestamp> when the tool runs under lua test), so every call creates a distinct job, and Jobs.getAll() includes dynamic jobs only with { includeDynamic: true }.
Deploy the job on its own
lua deploy job is the single-primitive shortcut: it creates and promotes an agent version scoped to that job, so the job goes live immediately and the version appears in lua version list like any other.
If it isnβt working
No jobs found in compiled output.
No jobs found in compiled output.
Cause
lua test job only sees jobs registered on LuaAgent.jobs. Fix Import the job in src/index.ts, add it to jobs, and run the test again.The job ran but no end user received anything
The job ran but no end user received anything
Cause A declared job has no current user, so
User.get() without an argument has nothing to return. Fix Store the user ID when you learn it and call User.get(userId) inside the job; see Send proactive messages.A dynamic job cannot see the tool's input
A dynamic job cannot see the tool's input
Cause
Jobs.create serializes execute to text and sends nothing it closed over. Fix Pass the values in metadata and read job.metadata inside execute.Next steps
About jobs
Declared and dynamic jobs, schedules, timeouts, and when a workflow fits better.
LuaJob reference
Every schedule type, limit, and retry field.
Jobs reference
Jobs.create, Jobs.getAll, and JobInstance.lua jobs
Trigger, history, activate, deactivate, and deploy.

