docs(cron): clarify delivery modes

This commit is contained in:
Ayaan Zaidi
2026-04-21 09:40:36 +05:30
parent 4c1f187da0
commit 8d6ed34e4a
5 changed files with 27 additions and 31 deletions

View File

@@ -125,22 +125,19 @@ retries, cron aborts instead of looping forever.
## Delivery and output
| Mode | What happens |
| ---------- | -------------------------------------------------------- |
| `announce` | Deliver summary to target channel (default for isolated) |
| `webhook` | POST finished event payload to a URL |
| `none` | Internal only, no delivery |
| Mode | What happens |
| ---------- | ------------------------------------------------------------------- |
| `announce` | Fallback-deliver final text to the target if the agent did not send |
| `webhook` | POST finished event payload to a URL |
| `none` | No runner fallback delivery |
Use `--announce --channel telegram --to "-1001234567890"` for channel delivery. For Telegram forum topics, use `-1001234567890:topic:123`. Slack/Discord/Mattermost targets should use explicit prefixes (`channel:<id>`, `user:<id>`).
For cron-owned isolated jobs, the runner owns the final delivery path. The
agent is prompted to return a plain-text summary, and that summary is then sent
through `announce`, `webhook`, or kept internal for `none`. `--no-deliver`
does not hand delivery back to the agent; it keeps the run internal.
If the original task explicitly says to message some external recipient, the
agent should note who/where that message should go in its output instead of
trying to send it directly.
For isolated jobs, chat delivery is shared. If a chat route is available, the
agent can use the `message` tool even when the job uses `--no-deliver`. If the
agent sends to the configured/current target, OpenClaw skips the fallback
announce. Otherwise `announce`, `webhook`, and `none` only control what the
runner does with the final reply after the agent turn.
Failure notifications follow a separate destination path:
@@ -406,15 +403,15 @@ openclaw doctor
### Cron fired but no delivery
- Delivery mode is `none` means no external message is expected.
- Delivery mode `none` means no runner fallback send is expected. The agent can
still send directly with the `message` tool when a chat route is available.
- Delivery target missing/invalid (`channel`/`to`) means outbound was skipped.
- Channel auth errors (`unauthorized`, `Forbidden`) mean delivery was blocked by credentials.
- If the isolated run returns only the silent token (`NO_REPLY` / `no_reply`),
OpenClaw suppresses direct outbound delivery and also suppresses the fallback
queued summary path, so nothing is posted back to chat.
- For cron-owned isolated jobs, do not expect the agent to use the message tool
as a fallback. The runner owns final delivery; `--no-deliver` keeps it
internal instead of allowing a direct send.
- If the agent should message the user itself, check that the job has a usable
route (`channel: "last"` with a previous chat, or an explicit channel/target).
### Timezone gotchas

View File

@@ -19,9 +19,9 @@ Tip: run `openclaw cron --help` for the full command surface.
Note: isolated `cron add` jobs default to `--announce` delivery. Use `--no-deliver` to keep
output internal. `--deliver` remains as a deprecated alias for `--announce`.
Note: cron-owned isolated runs expect a plain-text summary and the runner owns
the final send path. `--no-deliver` keeps the run internal; it does not hand
delivery back to the agent's message tool.
Note: isolated cron chat delivery is shared. `--announce` is runner fallback
delivery for the final reply; `--no-deliver` disables that fallback but does
not remove the agent's `message` tool when a chat route is available.
Note: one-shot (`--at`) jobs delete after success by default. Use `--keep-after-run` to keep them.

View File

@@ -1094,15 +1094,14 @@ for usage/billing and raise limits as needed.
<Accordion title="Cron fired, but nothing was sent to the channel. Why?">
Check the delivery mode first:
- `--no-deliver` / `delivery.mode: "none"` means no external message is expected.
- `--no-deliver` / `delivery.mode: "none"` means no runner fallback send is expected.
- Missing or invalid announce target (`channel` / `to`) means the runner skipped outbound delivery.
- Channel auth failures (`unauthorized`, `Forbidden`) mean the runner tried to deliver but credentials blocked it.
- A silent isolated result (`NO_REPLY` / `no_reply` only) is treated as intentionally non-deliverable, so the runner also suppresses queued fallback delivery.
For isolated cron jobs, the runner owns final delivery. The agent is expected
to return a plain-text summary for the runner to send. `--no-deliver` keeps
that result internal; it does not let the agent send directly with the
message tool instead.
For isolated cron jobs, the agent can still send directly with the `message`
tool when a chat route is available. `--announce` only controls the runner
fallback path for final text that the agent did not already send.
Debug:

View File

@@ -95,9 +95,9 @@ export function registerCronAddCommand(cron: Command) {
.option("--timeout-seconds <n>", "Timeout seconds for agent jobs")
.option("--light-context", "Use lightweight bootstrap context for agent jobs", false)
.option("--tools <list>", "Tool allow-list (e.g. exec,read,write or exec read write)")
.option("--announce", "Announce summary to a chat (subagent-style)", false)
.option("--deliver", "Deprecated (use --announce). Announces a summary to a chat.")
.option("--no-deliver", "Disable announce delivery and skip main-session summary")
.option("--announce", "Fallback-deliver final text to a chat", false)
.option("--deliver", "Deprecated (use --announce). Fallback-delivers final text to a chat.")
.option("--no-deliver", "Disable runner fallback delivery")
.option("--channel <channel>", `Delivery channel (${getCronChannelOptions()})`, "last")
.option(
"--to <dest>",

View File

@@ -66,9 +66,9 @@ export function registerCronEditCommand(cron: Command) {
.option("--no-light-context", "Disable lightweight bootstrap context for agent jobs")
.option("--tools <list>", "Tool allow-list (e.g. exec,read,write or exec read write)")
.option("--clear-tools", "Remove tool allow-list (use all tools)", false)
.option("--announce", "Announce summary to a chat (subagent-style)")
.option("--deliver", "Deprecated (use --announce). Announces a summary to a chat.")
.option("--no-deliver", "Disable announce delivery")
.option("--announce", "Fallback-deliver final text to a chat")
.option("--deliver", "Deprecated (use --announce). Fallback-delivers final text to a chat.")
.option("--no-deliver", "Disable runner fallback delivery")
.option("--channel <channel>", `Delivery channel (${getCronChannelOptions()})`)
.option(
"--to <dest>",