Skip to content

fix: use direct delivery for cron announce to forum topics#23841

Closed
AndrewArto wants to merge 2 commits intoopenclaw:mainfrom
AndrewArto:fix/cron-announce-forum-topics
Closed

fix: use direct delivery for cron announce to forum topics#23841
AndrewArto wants to merge 2 commits intoopenclaw:mainfrom
AndrewArto:fix/cron-announce-forum-topics

Conversation

@AndrewArto
Copy link
Contributor

@AndrewArto AndrewArto commented Feb 22, 2026

Problem

Cron jobs targeting Telegram forum topics (e.g. delivery.to = "-1003885638534:topic:562") silently fail to deliver their output to the user.

Root Cause

For text-only cron output, the delivery path goes through the subagent announce flow (runSubagentAnnounceFlowsendSubagentAnnounceDirectly), which triggers a full agent turn in the target session. The receiving agent is given the option to respond with ANNOUNCE_SKIP (or NO_REPLY), and it frequently does — silently dropping the cron output.

Forum topic sessions are especially prone to this because:

  1. The announce arrives via an internal webchat-like channel context (channel=webchat in logs)
  2. The target agent sees the ANNOUNCE_SKIP option in the announce prompt and decides to stay silent
  3. The cron output never reaches the Telegram topic

Reproduction

  1. Create a cron job with delivery.mode = "announce" targeting a Telegram forum topic:
    {
      "delivery": {
        "mode": "announce",
        "channel": "telegram",
        "to": "-1003885638534:topic:562"
      }
    }
  2. The cron runs successfully, generates text output
  3. parseTelegramTarget correctly extracts chatId and messageThreadId
  4. resolveDeliveryTarget correctly sets threadId: 562 and threadIdExplicit: true
  5. resolveCronAnnounceSessionKey correctly resolves to the forum topic session ✓
  6. But sendSubagentAnnounceDirectly triggers an agent turn where the agent responds ANNOUNCE_SKIP
  7. Gateway logs: [agent:nested] session=...topic:562 channel=webchat ANNOUNCE_SKIP
  8. User sees nothing in the Telegram topic

Fix

When resolvedDelivery.threadId is present (indicating a forum topic or thread target), use the direct outbound delivery path (deliverOutboundPayloads) — the same path already used for structured payloads (media, etc.). This bypasses the intermediary agent turn entirely and sends the text straight to the Telegram API with the correct message_thread_id.

// Before: only structured payloads got direct delivery
if (deliveryPayloadHasStructuredContent) {

// After: forum topics also get direct delivery
const useDirectDelivery = deliveryPayloadHasStructuredContent || resolvedDelivery.threadId != null;
if (useDirectDelivery) {

Changes

  • src/cron/isolated-agent/run.ts: Added useDirectDelivery condition that includes threadId presence
  • New test file: isolated-agent.direct-delivery-forum-topics.test.ts — verifies direct delivery for forum topics and confirm announce flow still used for non-threaded targets
  • Updated existing test: Changed "passes resolved threadId into shared subagent announce flow" to expect direct delivery behavior

Test Results

All 219 cron tests pass (36 test files).

Greptile Summary

This PR fixes a bug where cron job outputs targeting Telegram forum topics (or other threaded channels) were silently failing to deliver. The root cause was that text-only cron output went through the subagent announce flow, which triggered an agent turn in the target session. The receiving agent would often respond with ANNOUNCE_SKIP or NO_REPLY, silently dropping the cron output.

The fix introduces a useDirectDelivery flag that triggers direct delivery (bypassing the announce flow) when either:

  • The payload contains structured content (media, channel data) - existing behavior
  • The delivery target has a threadId (forum topics, Discord threads, Slack threads) - new behavior

This ensures forum topic deliveries go straight to the channel API with the correct message_thread_id, avoiding the intermediary agent turn entirely.

Changes:

  • Modified src/cron/isolated-agent/run.ts:667-668 to check for threadId presence in addition to structured content
  • Added comprehensive test coverage for both forum topic direct delivery and non-threaded announce flow preservation
  • Updated existing test to reflect new behavior when threadId is present

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is well-targeted and addresses a specific, well-documented bug. The change uses the correct null-safety check (!= null) to handle both null and undefined while preserving valid falsy values like 0. The implementation properly passes threadId through the existing deliverOutboundPayloads path, which already handles threading for multiple channels (Telegram, Discord, Slack). Test coverage is comprehensive, including both the new forum topic scenario and verification that non-threaded targets still use the announce flow. All 219 cron tests pass.
  • No files require special attention

Last reviewed commit: 28c5faf

(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

Andey Artamonov and others added 2 commits February 22, 2026 14:49
When a cron job targets a Telegram forum topic (delivery.to with :topic:NNN),
use the direct outbound delivery path (deliverOutboundPayloads) instead of
routing through the subagent announce flow.

The announce flow triggers an agent turn in the target session, where the
receiving agent can respond with ANNOUNCE_SKIP or NO_REPLY, silently dropping
the cron output. Forum topic sessions are especially prone to this because
the announce arrives via an internal webchat-like channel context, causing
the target agent to treat it as already-delivered or irrelevant.

This affects any cron job configured with delivery.mode='announce' and a
forum topic target (e.g. to='-1003885638534:topic:562'). The cron generates
its output correctly, resolves the threadId correctly, but the output never
reaches the user because the intermediary agent decides to skip it.

The fix: when resolvedDelivery.threadId is present, take the same direct
delivery path used for structured payloads. This bypasses the agent
intermediary and sends the text straight to the Telegram API with the
correct message_thread_id.

Fixes silent cron delivery failures for Telegram forum topic targets.
@vincentkoc vincentkoc force-pushed the fix/cron-announce-forum-topics branch from 28c5faf to 13cd20a Compare February 22, 2026 19:49
@steipete
Copy link
Contributor

Thanks for the fix and discussion here.

This has now landed on main in commit ffb1239 (same core change + tests/changelog), so I’m closing this PR as superseded by the direct merge.

@steipete steipete closed this Feb 22, 2026
lanyasheng added a commit to lanyasheng/openclaw that referenced this pull request Mar 2, 2026
…ummarization

The announce flow routes cron output through a subagent turn that may
summarize, truncate, or silently drop content via ANNOUNCE_SKIP/NO_REPLY.
This affects all channel types (Discord channels, Telegram chats, etc.),
not just forum topics.

PR openclaw#23841 partially fixed this for forum topics by checking threadId,
but regular channel targets still go through the announce flow and
receive summarized output instead of the full cron result.

This change makes all cron announce deliveries use the direct outbound
path, ensuring users receive the complete output verbatim.

Fixes: openclaw#13812
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants