Skip to main content
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.
Returns — the reply text, after the target’s postprocessors. Example
Errors — the same as 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.
Returns
AgentInvocationOutput
Example
Errors — the call throws. In a deployed agent the error is an 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 (prompt or messages), threadId, runtimeContext, webhookPayload, and the reasoning effort.
  • Dropped: systemPrompt, model, clientContext, and every other field. A channel of workflow, task or trigger becomes agent-invocation; any other channel is kept.
The call still succeeds; the dropped fields are simply not applied, and the target runs with its own persona, model and tools. When an agent invokes itself, nothing is dropped. The target always knows who called: every turn created by 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 to invoke. 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:
Every supervision call that is allowed, or refused for lack of a grant, writes a 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()

The agents of your organization other than your own, each { 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()

Recent log lines of the target, newest first. Needs 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.
Each row is { 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()

The target’s workflow runs, newest first, as metadata only: { 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()

Read-only access to the target’s 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()

The target’s agent versions and persona versions, in the same shapes as the REST routes, newest first. 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.
A call with only 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()

The files of the target’s source backup, each up to 512 KB. Paths that look like credentials (.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()

The names of the target’s environment variables. Values are never returned. Needs observe.

secrets()

Hands the target a credential without it passing through a model. From your code (a workflow code step or a job), 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 act on the target and the collection in the grant’s secretWriteCollections, which only an org admin sets. Without it, no collection takes a secret write.
  • value is flat: string, finite number, boolean or null fields 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 }, where fingerprint is sha256: and the first 16 hex characters of the SHA-256 of the stored row as JSON with sorted keys (_pk included). 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).get and query refuse it, and an admin cannot also list it in dataCollections.
  • The target’s logs get a supervisor_access line and a secret_written line 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 put in one step, and return only the receipt.
  • Refused on your own agent, in a test session, and under lua test.

Preview and release

Not generally available. Agents.versions(id).preview(version, prompt), Agents.versions(id).promote(version, { expectActive }) and Agents.persona(id).activate(version, { expectActive }) exist in the SDK, but the platform refuses them (supervision_preview_disabled, supervision_release_disabled) unless it has been switched on for your environment. They are off by default.
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

In lua 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, get and preview fail with supervision_unavailable_offline: the readable collections are part of the grant, which a developer credential cannot see.
  • promote, activate and versions.delete fail with supervision_release_offline_refused: a local test never changes a live agent.
  • secrets.put fails with supervision_offline_unsupported: it writes into a live agent’s data.

Supervision errors

Every supervision member throws a SupervisionError 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 agent
  • Lua — what the target reads from channel and webhookPayload
  • LuaJob — 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