Agents.invoke sends a prompt to a target agent and returns that agent’s reply after a complete turn: its persona, skills and tools, processors, and governance all run. For a bare model call with no agent, use AI. The reply is returned, not delivered: nothing reaches a channel unless the target’s tools send it or you pass result.text to Channels.send. Available in tools, jobs, webhooks, triggers, processors, and workflow code steps. The target must be in your agent’s organization.
The supervision members (Agents.list, logs, runs, data, versions, persona, source and env) read another agent of your organization. They work only after an org admin has granted your agent supervision over that agent; see Supervise another agent.
Verified against lua-cli 3.33.0. The supervision members are live on the platform; their lua-cli types, and those of Lua.request.invokedBy, arrive in the next CLI release.
Quick example
The short form returns the reply text; the options form returns the full result.Methods
invoke(targetAgentId, prompt)
Runs one turn with a plain prompt and returns the reply text.string
required
The target’s agent id, for example
baseAgent_agent_1770000000000_k3xq9mz2p. Pass this agent’s own id to invoke itself; there is no alias for the current agent. Your project’s id is agent.agentId in lua.skill.yaml and project.agentId in lua status --json --ci; lua agents --json lists every agent you can access.string
required
The end-user message for the turn.
invoke(targetAgentId, input).
invoke(targetAgentId, input)
Runs one turn with full options and returns the structured result.string
required
The target’s agent id. See the short form.
string
Plain end-user message. Pass
prompt or messages, not both.UserContent
AI SDK v5 parts:
{ type: 'text', text }, { type: 'image', image, mediaType? }, { type: 'file', data, mediaType, filename? }.string
Replaces the persona for this turn only, when an agent invokes itself. Dropped when the target is another agent, which always runs with its own persona. See What reaches another agent.
string
Extra context attached to the request, for example serialized metadata.
{ timezone?: string }
The end user’s IANA time zone, such as
Africa/Nairobi. When omitted, the target uses the end user’s stored profile, then UTC. Dropped when the target is another agent.string
Thread suffix that isolates this turn’s conversation. When omitted, the turn joins the end user’s default thread with the target, exactly like a direct message.
string
default:"agent-invocation"
The channel value the target’s code reads from
Lua.request.channel. It labels the turn; it doesn’t deliver the reply anywhere. On another agent, workflow, task and trigger are replaced by agent-invocation.string
Free-form tag stored on the message record, for example a trace id. Not a user id.
string
The end user to run the turn as. In a tool or processor the turn’s end user is used and this field isn’t needed. In a job, webhook, or trigger there is no ambient end user: pass
userId to run as that end user (conversation history is stored), or omit it to run without a user identity (no history, no User profile). The user must belong to your agent’s organization. The target sees the id as Lua.request.invokedBy.delegatedUserId.unknown
Raw payload from the source event. The target’s code reads it from
Lua.request.webhook.payload for this turn; it isn’t stored.number
default:120000
Per-call timeout in milliseconds. The calling context’s own budget caps it: a tool or processor run is walled at 180 s and a job at its own
timeout, so larger values buy nothing; a webhook handler has no server-side wall, but its caller is disconnected after about 90 s.string
A model code for this turn, when an agent invokes itself. A code the platform doesn’t approve falls back per its policy. Dropped when the target is another agent, which always runs on its own model.
AgentInvocationOutput
AgentInvocationError with a code and, where an HTTP status applies, a statusCode; in lua test it is a plain Error carrying the server’s message, or Agent invocation failed.
A
userId who cannot reach the target fails with a 403, User <userId> cannot be delegated to agent <id>.
In
lua test the call is made with your developer credentials: userId, model, and timeoutMs are not sent, so you are always the end user and the default timeout applies. A blocked turn is returned with finishReason set to preprocessor_blocked or governance_blocked rather than thrown; deployed agents honor all three fields and throw. Because the local call is made as you rather than as an agent, it is not treated as another agent’s turn: a systemPrompt sent to a different agent can still apply locally although a deployed agent drops it, and the target sees no Lua.request.invokedBy.What reaches another agent
When your agent invokes a different agent, the target decides how it runs. The platform keeps only the conversation fields of your request and drops the rest:- Kept: the message (
promptormessages),threadId,runtimeContext,webhookPayload, and the reasoning effort. - Dropped:
systemPrompt,model,clientContext, and every other field. Achannelofworkflow,taskortriggerbecomesagent-invocation; any otherchannelis kept.
Agents.invoke, including a self-invoke, carries Lua.request.invokedBy with the calling agent’s id, verified by the platform. Use it to refuse writes that did not come from someone allowed to make them; see Accept changes from a supervisor.
Supervision
An org admin can grant one agent supervision over another agent of the same organization. The grant unlocks read-only members next toinvoke. Nothing in your code, your environment or a push can create a grant: without one, every member below except list fails, and list returns [].
Each grant names one or more actions:
supervisor_access line to the target’s logs, where its owner reads it with lua logs (source supervision; --type supervision from the next CLI release). If that line cannot be written, the call fails. A supervising agent may make 60 supervision calls a minute. The members are refused in a turn that runs in a group conversation.
list() and get()
{ agentId, name?, actions }, where actions are the supervision actions your agent holds on it (empty for an agent you hold no grant on). Only an agent that holds at least one grant in the organization sees them: anyone else gets [] from list() and supervision_not_found from get(). get adds the persona version the agent serves.
logs()
observe.
string | number
An ISO timestamp or epoch milliseconds. Defaults to 24 hours ago; nothing older than 7 days is returned.
number
default:50
At most 100.
'debug' | 'info' | 'warn' | 'error'
Only lines of this level.
string
Only lines of this source, as in
lua logs --type.{ timestamp, level?, logSource?, primitiveName?, toolName?, message? }. message, truncated to 2,000 characters, is present only when the grant also holds observe-content. No row ever carries a user id.
runs()
{ runId, workflowId?, workflowName?, status, reason?, trigger?, createdAt?, startedAt?, completedAt? }. Inputs, outputs and step results are never returned. limit defaults to 20, at most 50. Needs observe.
data()
Data collections that the grant names in dataCollections. Any other collection fails with supervision_data_not_granted, whatever the target’s own code does. filter is a Lua Query filter; limit defaults to 20, at most 100. Needs observe.
versions() and persona()
list returns 20 versions by default, at most 50. Needs observe.
From lua-cli 3.50.0, list also takes:
SupervisionVersionStatus | SupervisionVersionStatus[]
Only versions with this status, or any of these:
active, staged, superseded or deleted.number
default:0
Versions to skip, newest first, 0 to 10,000. Use it to page past the newest 50.
limit answers as before. An invalid status or offset fails with supervision_bad_args. A platform that predates these options ignores them, so check each row’s status and version before you rely on the filter.
source()
.env*, *.pem, *.key, id_*, .npmrc, .netrc, credentials*, *.p12, *.pfx, *secret*), dot-directories and the files a backup already skips are never listed or returned. Needs observe.
env()
observe.
secrets()
put writes one row into the target’s own Data: the entry of collection whose _pk field is key is replaced whole by value, with _pk set to key, or created when there is none. Later puts update the same entry. Available in lua-cli 3.50.0 and later.
- Needs
acton the target and the collection in the grant’ssecretWriteCollections, which only an org admin sets. Without it, no collection takes a secret write. valueis flat: string, finite number, boolean ornullfields with plain identifier names, at most 32 fields, a string at most 8 KB and 16 KB in all. No search text is set, so the value is never embedded.- The answer never carries the value:
{ ok, id, fingerprint }, wherefingerprintissha256:and the first 16 hex characters of the SHA-256 of the stored row as JSON with sorted keys (_pkincluded). Send the target a message carrying only the fingerprint to tell it to reload a cached secret. - The collection is write-only for you:
Agents.data(id).getandqueryrefuse it, and an admin cannot also list it indataCollections. - The target’s logs get a
supervisor_accessline and asecret_writtenline with the collection, entry id and fingerprint, never the value. A refusal gets a line with its code only. - Keep the value out of your step’s result and memory: fetch and
putin one step, and return only the receipt. - Refused on your own agent, in a test session, and under
lua test.
Preview and release
Agents.versions(id).delete(version) is a release member too: it removes a superseded version, or, from lua-cli 3.50.0, a staged version that was never active, is over 24 hours old and is not the newest staged version, so an agent at its version limit can free slots. The active version and the last version are never deleted.
Where they are switched on, they need a preview or release grant. A release also runs only from a live workflow step of a workflow the grant names, never from a tool, always needs expectActive (see Promote safely), is limited to 3 a day for each supervising and supervised pair, and records promotedBy: service:agent:<supervisorId> on the version.
Offline in lua test
Inlua test the read members call the platform with your developer credential, so they return what you can see rather than what a grant allows. They mirror the same projections: logs without user ids or message bodies, runs as metadata, env as names only.
data,source.get,list,getandpreviewfail withsupervision_unavailable_offline: the readable collections are part of the grant, which a developer credential cannot see.promote,activateandversions.deletefail withsupervision_release_offline_refused: a local test never changes a live agent.secrets.putfails withsupervision_offline_unsupported: it writes into a live agent’s data.
Supervision errors
Every supervision member throws aSupervisionError with a code:
Types
AgentInvocationInput and AgentInvocationOutput have the fields listed under invoke(targetAgentId, input). They are not exported from lua-cli; declare your own variables with those fields, or let inference type the call.
See also
AI— one model call without an agentLua— what the target reads fromchannelandwebhookPayloadLuaJob— invoke an agent on a schedule- Compose agents — routing, self-invocation, and identity patterns
- Supervise another agent — how an org admin grants supervision, and the write gate a supervised agent keeps
- REST chat API — the same turn from outside the platform

