投递(deliver)的含义

Cron 任务后台独立运行,没有等待回复的用户。Agent 跑完后结果默认只写入 session 文件。 投递 = 把 Agent 的回复主动推送到某个聊天 channel。

两条投递路径

路径 1:Agent 自己用 message 工具发 Agent 执行过程中主动调用 message 工具,直接发到目标 channel。

路径 2:Runner Fallback(--announce) Agent 跑完后,如果它没有自己发消息,Runner 把最终回复文本作为兜底发出去。

--no-deliver 只关掉路径 2,不影响路径 1。

Runner Fallback(—announce)详解

核心逻辑

Agent turn 结束
    ↓
Runner 检查:Agent 有没有发到"已配置/当前目标"?
    ├── 发了 → 跳过 announce fallback(不重复发)
    └── 没发 → 执行 announce,把最终回复文本发出去

三种投递模式

模式行为
announce(isolated 默认)Agent 没发 → Runner 把最终回复发到目标 channel
webhook把完整事件 payload POST 到一个 URL
noneRunner 不发任何东西

投递目标解析顺序

1. 显式指定:--channel telegram --to "123456789"
2. channel: "last" → 从 session 历史找上次聊天的 route
3. 单个已配置的 channel(只有一个时自动选)
4. provider-prefixed target:to: "telegram:123" 可以隐式选 channel

边界行为

  • 抑制中间状态:Agent 第一个回复只是 "on it" 等过渡语时,OpenClaw 重新提示一次要真正的结果再投递
  • NO_REPLY 静默:Agent 回复 NO_REPLY 时,Runner 同时抑制直接投递和 fallback,什么都不发
  • 子 Agent 场景:投递优先用最终子 Agent 的输出,子 Agent 还在跑时父 Agent 的中间更新被压制
  • 白名单验证:announce 投递用 channel 的 allowFrom 白名单验证目标

查看投递诊断

openclaw cron show <job-id>          # 预览投递路由
openclaw cron runs --id <job-id>     # 历史运行的投递诊断
# 包含:intended target / resolved target / message-tool sends / fallback use / delivered state

—best-effort-deliver

控制投递目标无法解析时的行为:

标志行为
--best-effort-deliver路由解析失败 → 降级为 session-only 执行(任务照常跑,结果只写 session)
--no-best-effort-deliver路由解析失败 → 直接返回 INVALID_REQUEST,任务不执行

适合开启:任务本身有价值(写文件、更新记忆),即使发不出消息也没关系。 适合关闭(严格模式):任务目的就是发消息,发不出去应该报错而不是静默成功。

WebChat 无 channel 场景:cron 结果回写 session

问题

WebChat 是 internal session,没有外部 channel。announce 的外部投递路径对它无效。 bestEffortDeliver=true 的文档明确说明:webchat session 就是”无法解析外部投递路由”的典型场景。

方案一:--session main(外部 CLI 创建 cron)

openclaw cron add \
  --name "my-task" \
  --at "20m" \
  --session main \
  --system-event "任务完成,结果是:xxx" \
  --wake now \
  --delete-after-run

工作原理:

cron 触发
    ↓
把 system-event 注入到 main session 的消息队列
    ↓
--wake now 立即唤醒 heartbeat
    ↓
Agent 在 main session 里处理这条 system-event
    ↓
回复出现在 WebChat 的同一个 session 里

方案二:--session current(Agent 在对话中自己创建 cron)

openclaw cron add \
  --name "follow-up" \
  --at "30m" \
  --session current \
  --message "检查任务是否完成"

current 在创建时绑定到当前活跃的 session,结果回到同一个 session。

main vs current 的本质区别

  • main:固定——无论在哪个 session 里创建 cron,永远指向该 agent 的主 session。
  • current:快照——创建时把当前活跃的 session ID 记录下来,之后每次触发都回到这个 session。

两种方案对比

--session main--session current
适合外部触发的 cron(CLI 创建)Agent 在对话中自己创建的 cron
绑定时机固定绑定 main session创建时绑定当前 session
结果去向main session(WebChat 默认就是这个)创建时所在的那个 session
多 agent 场景需要指定 --agent <id>自动继承当前 agent
口诀”回到主入口""回到我这里”

相关官方文档