Tool reference
Agents interact with the runtime through tools. The full built-in tool list and enablement configuration are documented in Tool configuration.
This page details respond, the primary way an agent communicates with users, and invoke, which requests a turn in another conversation.
respond
Sends a message to the current or another channel, with optional file attachments.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
content | string | Either | — | Message content in Markdown; supply exactly one of content or draft. |
draft | string | Either | — | Runtime-supplied ID of an undelivered draft from this turn; sends its exact text to the current conversation. |
channel | string | No | "current" | Target channel for the message. |
attachments | object[] | No | — | Files to attach, e.g. [{"path": "/workspace/report.pdf"}]. Each entry carries a sandbox path and an optional altText. |
final | boolean | No | true | Whether this is the final message of the turn; false sends an intermediate status update. |
Channel resolution
| Value | Description |
|---|---|
"current" (default) | Send to the current conversation. |
"last" | Send to the most recently active session. |
"owner" | Send a DM to the bot owner; requires ownerId to be configured. |
| Explicit session id | Send to a specific session, e.g. "discord:123456789|987654321". |
These targets depend on the current channel's resolver and authorization. Remote sessions support only "current" or an authorized owned remote:... session ID, not "last", "owner", or Discord session IDs. See Remote sessions.
Notes
- Attachments work only on platforms that support them (Discord; internal sessions do not).
- Cross-channel sends to a different session mark the response as not final.
Undelivered draft recovery
Plain assistant text is not delivered to users. When a model emits a complete text-only answer, the runtime preserves it as a draft and asks the model to authorize delivery with respond. Sending by reference avoids copying or regenerating the answer:
json
{
"draft": "draft-ID-supplied-by-runtime"
}Supply exactly one of content or draft. Draft references only work during their originating turn and only with channel: "current". Incomplete outputs and outputs with an unknown completion status cannot be sent by reference; author a complete replacement using content instead. The agent may deliberately replace a draft using content, or decline delivery using no-response. Do not send "see above": the user cannot see undelivered output. Reasoning settings remain unchanged during recovery, and the runtime never sends a draft automatically.
After successful reference delivery, history stores the actual text as respond.content, and the tool result also includes the supplied draft ID. If recovery fails, the runtime reports a recovery failure instead of treating plain text as delivered. For persistent sessions with a session repository, the agent's SQLite response_recovery table retains the latest rejected-output turn per session, including exact drafts, completion reasons, per-draft outcomes, and the overall recovery outcome. These diagnostics are separate from conversational history and are not available through session-reading tools. A later rejected-output turn replaces that session's diagnostic record, and deleting or resetting a session deletes its record. Ephemeral sessions do not persist these diagnostics; failed turns still carry their drafts in the runtime recovery exception. Treat the diagnostic table as sensitive conversation data and protect it and database backups accordingly. A pending outcome means recovery has not completed, including a process interruption or cancellation.
Initialization templates explain draft recovery for new agents. Existing agents receive the tool description and runtime correction without needing to replace their custom instruction files.
Return value
json
{
"final": true,
"sent": true
}sent: true means the configured send path completed successfully. It is not an end-user delivery receipt: a send filter may intentionally suppress output, such as a scheduled job with delivery = "none". Remote output delivery is acknowledged separately through ack_output.
Examples
Send a final reply to the current channel:
json
{
"content": "Here's the information you requested.",
"final": true
}Send an intermediate status update:
json
{
"content": "Looking into that for you...",
"final": false
}Send a DM to the bot owner:
json
{
"content": "Alert: Something needs attention",
"channel": "owner"
}Send with file attachments:
json
{
"content": "Here's the report you asked for",
"attachments": [{ "path": "/workspace/report.pdf" }, { "path": "/workspace/data.csv" }]
}Attach an image with alt text:
json
{
"content": "Here is the chart",
"attachments": [{ "path": "/workspace/chart.png", "altText": "Bar chart of revenue by quarter" }]
}altText is optional and is only accepted on image file paths, where the platform renders it in place of the image and for screen readers. It is rejected on documents and archives, where it would be silently ignored, and is capped at 1024 characters.
invoke
Queues a turn in another existing session of the same agent. Unlike a cross-channel respond, the destination generates its own response using its own history, pinned context, and selected provider/model. The caller's conversation and model overrides are not copied.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
session | string | Yes | Explicit existing session ID from list-sessions. Aliases such as last, owner, and current are not accepted. |
reason | string | Yes | Why to wake the destination and what needs attention there. Prefer intent over a prewritten reply. |
json
{
"session": "discord:123456789",
"reason": "It's time for the check-in Lys requested. Ask how she's feeling."
}The destination receives a user-level invocation request identifying the calling agent and source session, followed by the reason. It is not a user-authored message or a higher-priority instruction. The destination can use respond to speak in that conversation or no-response to stay silent.
The result contains queued: true, an invocation id, and the canonical destination session. Queuing does not end the calling turn and does not wait for a response or guarantee delivery. Invocations use persisted immediate main-session one-shot jobs, so unstarted work survives scheduler restart. Busy destinations are checked again after one second. Execution failures use the existing scheduler error handling rather than automatically rerunning a failed turn.
Enable the tool with invoke = true in config/tools.toml. Targets must already exist when invoked. The current session, ephemeral destinations, remote callers, and remote destinations are rejected. Cross-agent invocation is not supported.
For heartbeat-driven check-ins, use a separate heartbeat session as described in Scheduling.