Files
openclaw-openclaw/docs/cli/agent.md
Peter Steinberger f7d7148cf0 docs: rewrite published docs grounded in current source (#100142)
Source-grounded rewrite of 529 published docs pages with per-unit information-loss verification: 1,713 factual corrections cited to src/**, generated surfaces regenerated, frontmatter titles preserved for i18n, release notes pages untouched. All docs gates green.

Closes #100141
2026-07-05 00:32:47 -04:00

8.0 KiB

summary, read_when, title
summary read_when title
CLI reference for `openclaw agent` (send one agent turn via the Gateway)
You want to run one agent turn from scripts (optionally deliver reply)
Agent

openclaw agent

Run one agent turn through the Gateway. Falls back to the embedded agent if the Gateway request fails; pass --local to force embedded execution up front.

Pass at least one session selector: --to, --session-key, --session-id, or --agent.

Related: Agent send tool

Options

  • -m, --message <text>: message body
  • --message-file <path>: read the message body from a UTF-8 file
  • -t, --to <dest>: recipient used to derive the session key
  • --session-key <key>: explicit session key to use for routing
  • --session-id <id>: explicit session id
  • --agent <id>: agent id; overrides routing bindings
  • --model <id>: model override for this run (provider/model or model id)
  • --thinking <level>: agent thinking level (off, minimal, low, medium, high, plus provider-supported custom levels such as xhigh, adaptive, or max)
  • --verbose <on|off>: persist verbose level for the session
  • --channel <channel>: delivery channel; omit to use the main session channel
  • --reply-to <target>: delivery target override
  • --reply-channel <channel>: delivery channel override
  • --reply-account <id>: delivery account override
  • --local: run the embedded agent directly (after plugin registry preload)
  • --deliver: send the reply back to the selected channel/target
  • --timeout <seconds>: override agent timeout (default 600, or agents.defaults.timeoutSeconds); 0 disables the timeout
  • --json: output JSON

Examples

openclaw agent --to +15555550123 --message "status update" --deliver
openclaw agent --agent ops --message "Summarize logs"
openclaw agent --agent ops --message-file ./task.md
openclaw agent --agent ops --model openai/gpt-5.4 --message "Summarize logs"
openclaw agent --session-key agent:ops:incident-42 --message "Summarize status"
openclaw agent --agent ops --session-key incident-42 --message "Summarize status"
openclaw agent --session-id 1234 --message "Summarize inbox" --thinking medium
openclaw agent --to +15555550123 --message "Trace logs" --verbose on --json
openclaw agent --agent ops --message "Generate report" --deliver --reply-channel slack --reply-to "#reports"
openclaw agent --agent ops --message "Run locally" --local

Notes

  • Pass exactly one of --message or --message-file. --message-file strips a leading UTF-8 BOM and preserves multiline content; it rejects files that are not valid UTF-8.
  • Slash commands (for example /compact) cannot run through --message. The CLI rejects them and points you at the first-class command instead (openclaw sessions compact <key> for compaction).
  • --local and embedded fallback runs are one-shot: bundled MCP loopback resources and warm Claude stdio sessions opened for the run are retired after the reply, so scripted invocations do not leave local child processes running. Gateway-backed runs keep Gateway-owned MCP loopback resources under the running Gateway process instead.
  • --channel, --reply-channel, and --reply-account affect reply delivery, not session routing.
  • --session-key selects an explicit session key. Agent-prefixed keys must use agent:<agent-id>:<session-key>, and --agent must match the key's agent id when both are given. Bare non-sentinel keys scope to --agent when supplied, or to the configured default agent otherwise; for example --agent ops --session-key incident-42 routes to agent:ops:incident-42. The literal keys global and unknown stay unscoped only when no --agent is supplied.
  • --json reserves stdout for the JSON response; Gateway, plugin, and embedded-fallback diagnostics go to stderr so scripts can parse stdout directly.
  • Embedded fallback JSON includes meta.transport: "embedded" and meta.fallbackFrom: "gateway" so scripts can detect a fallback run.
  • If the Gateway accepts a run but the CLI times out waiting for the final reply, embedded fallback uses a fresh gateway-fallback-* session/run id and reports meta.fallbackReason: "gateway_timeout" plus the fallback session fields, instead of racing the Gateway-owned transcript or silently replacing the original session.
  • SIGTERM/SIGINT interrupt a waiting Gateway-backed request; if the Gateway already accepted the run, the CLI also sends chat.abort for that run id before exiting. --local and embedded fallback runs receive the same signal but do not send chat.abort. If the internal run-dedup key already has an active run for this session, the response reports status: "in_flight" and the non-JSON CLI prints a stderr diagnostic instead of an empty reply. For external cron/systemd wrappers, keep a hard-kill backstop such as timeout -k 60 600 openclaw agent ... so the supervisor can reap the process if shutdown cannot drain.
  • When this command triggers models.json regeneration, SecretRef-managed provider credentials are persisted as non-secret markers (for example env var names, secretref-env:ENV_VAR_NAME, or secretref-managed), never resolved secret plaintext. Marker writes come from the active source config snapshot, not from resolved runtime secret values.

JSON delivery status

With --json --deliver, the CLI JSON response includes top-level deliveryStatus so scripts can distinguish delivered, suppressed, partial, and failed sends:

{
  "payloads": [{ "text": "Report ready", "mediaUrl": null }],
  "meta": { "durationMs": 1200 },
  "deliveryStatus": {
    "requested": true,
    "attempted": true,
    "status": "sent",
    "succeeded": true,
    "resultCount": 1
  }
}

Gateway-backed CLI responses also preserve the raw Gateway result shape at result.deliveryStatus.

deliveryStatus.status is one of:

Status Meaning
sent Delivery completed.
suppressed Delivery was intentionally not sent (for example a message-sending hook cancelled it, or there was no visible result). Terminal, no retry.
partial_failed At least one payload sent before a later payload failed.
failed No durable send completed, or delivery preflight failed.

Common fields:

  • requested: always true when the object is present.
  • attempted: true once the durable send path ran; false for preflight failures or no visible payloads.
  • succeeded: true, false, or "partial"; "partial" pairs with status: "partial_failed".
  • reason: lowercase snake-case reason from durable delivery or preflight validation. Known values include cancelled_by_message_sending_hook, no_visible_payload, no_visible_result, channel_resolved_to_internal, unknown_channel, invalid_delivery_target, and no_delivery_target; failed durable sends may also report the failed stage. Treat unknown values as opaque since the set can expand.
  • resultCount: number of channel send results, when available.
  • sentBeforeError: true when a partial failure sent at least one payload before erroring.
  • error: true for failed or partial-failed sends.
  • errorMessage: present only when an underlying delivery error message was captured. Preflight failures carry error/reason but no errorMessage.
  • payloadOutcomes: optional per-payload results with index, status, reason, resultCount, error, stage, sentBeforeError, or hook metadata when available.