Skip to content

Using Lightspeed

Sub-agents and federation

An agent can split a task into work for specialists, or send an event to another bot with its own ongoing job. Lightspeed provides separate mechanisms for those relationships because they have different ownership and lifetimes.

A sub-agent is a child session created for a bounded task. It uses an allowed profile, returns one result, and closes. Bot federation sends a durable event to an independently configured bot in the same universe. That bot owns its inbox, routing, conversations, and future work.

Need Use
Review a draft and return findings to the current task A sub-agent.
Run several independent checks and combine their results Multiple sub-agents, with joined calls or promises.
Notify an ongoing release bot that a review is ready A federation event.
Ask another bot to handle work on its own schedule and report later Federation with a requested reply receipt.

Both mechanisms require explicit grants. Use a universe owner/admin or platform administrator account to configure them.

Delegate a release review

First create the release-reviewer profile from Profiles and instructions. It should have a clear description, read-only VFS tools, and its own read-only link to the release-notes workspace at /workspace.

Open the parent release-editor profile and enable Sub-agents. In Agents, select release-reviewer. Set a small limit for this task, for example Max depth 1, Max descendants 8, Max concurrent 2, and Deadline (ms) 300000. Save and start a new session from the parent profile, or apply it to an existing idle session.

Ask the parent:

Ask the release-reviewer sub-agent to compare /workspace/release-notes.md
with /workspace/changes.md. Give it both paths and ask for unsupported claims,
missing changes, and uncertainties. Wait for its result. Check its findings
against the files, then report the changes you recommend. Do not edit yet.

The child receives the supplied brief and its own profile. It does not receive the parent’s conversation or inherit its tool grants. Include the facts, paths, and expected result the child needs in the brief. In this example, both profiles explicitly link the same workspace, so both agents can read the files without copying them into the child conversation.

Inspect the parent’s tool activity and follow the Sub-agents link to the child transcript. A completed child should show its own reads and review; the parent should use that result in its answer. To find finished children in the main session list, clear Hide sub-agent sessions and Hide closed sessions.

Understand the child boundary

The child runs with the selected profile’s full grants. Allowing a profile that can write to a database delegates that authority even if the parent cannot call the database tool directly. Review the child profile as part of the parent’s access design.

Workspace links are shared only when both profiles point to the same live workspace. They do not create isolated copies. Give a reviewer read-only access, or use a snapshot when it must review a fixed version while another agent continues editing.

Environment behavior is also explicit. An existing environment or an inherited parent environment shares a real filesystem. The child profile option Inherit the parent’s active environment (sub-agents only) needs a parent with an active environment and the appropriate capability. Provisioning can give the child a separate machine, normally closed with its session according to the selected policy. VFS files remain separate from these machine files; see Environments.

A sub-agent spawned by a bot does not become another bot. It gets its profile and brief, without the parent’s bot history, inbox, or controller-specific tools.

Join a result or use a promise

The parent uses agent_run for a result returned with the tool call. Several calls in the same model turn can run concurrently and return together. For work that can proceed alongside other parent activity, agent_spawn returns a promise that the parent can await later.

Both calls accept the same model-facing arguments. For example:

{
"agent": "release-reviewer",
"input": "Compare /workspace/release-notes.md with /workspace/changes.md. Report unsupported claims, omitted changes, and uncertainty. Do not edit files.",
"label": "Review Acorn release notes"
}

For a spawned task, the parent passes returned promise IDs to await:

{
"promises": ["promise_1"],
"mode": "all",
"timeout_ms": 300000
}

Use the actual returned ID. mode: "any" resumes when any listed promise is ready. An await timeout stops waiting for that interval; it does not cancel the child. cancel requests cancellation through the promise and closes the child session.

Pending spawned work normally belongs to the parent run and is canceled when that run ends. detach promotes a promise to session lifetime when work must survive that boundary. The session then owns that outstanding work until it finishes or is canceled; force-closing the session cancels it.

The result includes a status such as completed, failed, cancelled, or deadline, plus output or error information and the child session ID. Check the status before treating the output as a completed review. A child returns one run’s result and closes automatically; there is no child-continuation conversation tool.

Bound the delegation tree

The default limits are depth 2, 16 total descendants, 4 concurrent open descendants, and a one-hour deadline per child. The deadline ceiling is 24 hours. Configure smaller values when a task should be quick and shallow.

These limits apply through the root’s delegation tree. Max descendants is a lifetime count, not a slot returned whenever a child finishes. Max concurrent limits open descendants. Nested grants can narrow the limits but cannot widen the limits already pinned by their origin.

The child records its profile revision, parent, and root, so its execution can be inspected against the setup it received. Changing the saved profile does not rewrite a child already running.

Connect two independent bots

Suppose release-watch should ask a separate review bot for help. Create a bot with ID release-reviewer using the shared profile of the same name, following Bots and triggers. The bot and profile are different records even when their IDs match. Give the bot a brief describing how to review incoming requests and resolve their events with findings.

Open release-watch and choose Settings → Other bots. Enable Can message other bots and save. Check Accepts messages from as well: enabling sending can also open an otherwise disabled inbox in the form. Set the receiving policy you actually intend.

On the receiving release-reviewer bot, set Accepts messages from → Only these bots, select release-watch, and save. Nobody disables acceptance; Any bot here accepts senders in this universe. The recipient owns its inbox’s Routing & batching… settings. Keep queue delivery for a review that needs its own completed run.

Give each bot a useful description. The sender’s directory lists enabled bots in the same universe whose inboxes accept it. Sending permission takes effect at the sender’s next idle boundary; receiving policy applies to the next event.

Send a test event to release-watch asking it to request a review from release-reviewer and request a reply. Its bot_emit tool can submit:

{
"to": "release-reviewer",
"kind": "release.review",
"summary": "Review the Acorn 1.2 release notes against the change list.",
"data": {
"changes": "/workspace/changes.md",
"notes": "/workspace/release-notes.md"
},
"reply": true
}

The receiving profile must independently have access to those paths. Event data supplies references and facts; it does not mount the sender’s files or grant its capabilities.

Follow admission and replies

bot_emit returns the destination bot and admitted event sequence number. That means the recipient accepted the event, not that the review finished. Inspect the recipient’s Activity and the conversation that handled the event to follow its work.

With reply: true, the controller can later send a bot.reply receipt to the original logical sender conversation. The receipt is correlated by bot and event sequence. The recipient should resolve the event with a useful outcome and summary; the sender handles that later receipt as another event. There is no cross-bot promise to await like a sub-agent result. When the sender’s current event depends on that reply, it can resolve the event as deferred and handle bot.reply in a later run. Deferral itself does not schedule a retry.

Receipts follow the recipient’s delivery semantics. Append or steer delivery can acknowledge that disposition rather than a completed answer. Receipts can also be skipped when the requester is disabled or closed, or the hop limit is reached. Design the bot’s brief to handle missing or deferred replies without claiming the requested work completed.

Federation is confined to one universe. Rate limits and an eight-hop ceiling bound chains between bots. A send can be refused because the target is unavailable, has no accepting inbox, filters the event, or reaches a rate or loop limit. Messaging permission does not let one bot create or configure its neighbors.

If delegated work is missing

Symptom What to check
The parent cannot find a specialist Add the named profile to Sub-agents → Agents and give it a useful description.
The child cannot read the parent’s files Configure links in the child profile; the brief alone grants no access.
New children are refused despite none currently running Check the lifetime descendant budget as well as concurrency and depth.
A spawned child ends before its result is used The parent run may have ended with a run-scoped promise still pending. Await it or deliberately detach it.
A bot is absent from the federation directory Check sending permission, target state, and the recipient’s enabled inbox allowlist.
A send succeeded but there is no answer Admission and completion are separate. Inspect receiver delivery, outcome, pause/budget state, and requested-reply limits.