Agents.invoke runs a full turn on the target agent, with its persona, skills, processors, and governance; AI.generate calls a model with a prompt and nothing else. For routing between agents set up in the admin dashboard, use a Space.
Verified against lua-cli 3.33.0.
Before you begin
- A project created with
lua initand signed in withlua auth configure(Install and sign in). - The target agent, in the same organization, released and answering in
lua chat, or this agent’s own ID, to invoke itself.
1
Find the target agent's ID and store it
lua agents --json --ci prints an array of organizations, each with an agents array of agentId and name; your own project’s ID is project.agentId in lua status --json --ci. Keep the ID in an environment variable: lua test reads .env, deployed code reads the production variables, and sandbox chat uploads the .env values with the sandbox version.Output
2
Invoke it from a tool
Inside a conversation the turn runs as the current end user.
threadId isolates the target agent’s conversation; without it the invocation joins the end user’s default thread with that agent. When the target’s preprocessor or governance stops the turn, the call throws with code set to PREPROCESSOR_BLOCKED or GOVERNANCE_BLOCKED and the block text as the message; catch that case rather than treating it as a tool failure.src/skills/tools/DraftReplyTool.ts
3
Invoke it from a job
A job has no current user. Pass
userId so the turn runs as that user, with their profile and history; omit it and the turn runs in system scope, with no end user and no stored conversation (Execution contexts). user_abc123 is a placeholder for a stored Lua user ID (Identify users).src/jobs/WeeklyReviewJob.ts
4
Make a one-off model call
AI.generate with an options object returns text, finishReason, and usage; model pins a code from lua models list --json --ci (About models), and without it the platform default answers. With structuredOutput.schema, a JSON Schema whose top-level type is object, the parsed value lands on output when the model finishes normally; it is not validated, so check it before use.src/skills/tools/ClassifyTicketTool.ts
5
Test locally
lua test skill runs a tool on your machine; AI.generate and Agents.invoke still reach the platform. Locally, Agents.invoke runs as you with your developer credentials, drops userId, model, and timeoutMs, and reports a blocked turn as finishReason preprocessor_blocked or governance_blocked instead of throwing.Output
model, the platform default answered the same input in another shape ("category": "Billing", a sub_category, no summary), which is why the tool validates output and falls back to text.6
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.7
Verify
Ask a question the tool delegates, then read the logs.The reply contains the sales agent’s draft, and the log shows
draft_reply running. The target agent records the delegated turn on the thread you named; lua logs --agent-id <agent-id> --type all --limit 5 shows it when you administer that agent.Options you may need
Set a timeout that fits the caller
timeoutMs defaults to 120 000 ms. A tool, webhook, or processor is itself stopped at 180 seconds, so a larger value buys nothing there; a job runs up to its own timeout (300 seconds by default, 600 at most).
Override the target’s persona for one turn
systemPrompt replaces the target agent’s persona for that invocation only, and runtimeContext appends context to the request; the target’s skills and processors still apply. Agents.invoke(agentId, 'a plain prompt') returns only the reply text.
Shape a plain call
messages replaces prompt with a full message array; maxOutputTokens caps the answer.
If it isn’t working
The call throws PREPROCESSOR_BLOCKED or GOVERNANCE_BLOCKED
The call throws PREPROCESSOR_BLOCKED or GOVERNANCE_BLOCKED
Cause The target agent’s preprocessor or governance policy stopped the turn; the error’s
message is the block text. Fix Catch the error as in the example, read lua logs --type preprocessor on the target agent, and adjust its rules or your prompt.The invocation times out
The invocation times out
Cause The target took longer than
timeoutMs, or your calling context hit its own budget first. Fix Raise timeoutMs up to the caller’s limit, move the call into a job, or narrow the prompt.output is undefined or does not match the schema
output is undefined or does not match the schema
Cause
output is set only when the model finishes with stop, and the parsed JSON is not validated against your schema. Fix Validate with zod as in the example, fall back to text, and try a different model.Next steps
Agents reference
Every option and the output shape.
AI reference
AI.generate inputs, outputs, and structured output.About Spaces
Routing between agents, set up in the admin dashboard.
Workflow quickstart
Agent steps with retries, approvals, and budgets.

