Skip to content

fix: Preserve Telegram hooks when flushing buffered finals#83670

Open
bpconnor3-r2 wants to merge 1 commit into
openclaw:mainfrom
bpconnor3-r2:codex/fix-telegram-buffered-final-flush-v2
Open

fix: Preserve Telegram hooks when flushing buffered finals#83670
bpconnor3-r2 wants to merge 1 commit into
openclaw:mainfrom
bpconnor3-r2:codex/fix-telegram-buffered-final-flush-v2

Conversation

@bpconnor3-r2

@bpconnor3-r2 bpconnor3-r2 commented May 18, 2026

Copy link
Copy Markdown

Summary

  • flush buffered Telegram final answers before returning from segmented final delivery
  • preserve the normal preview-finalized message:sent hook and transcript mirror when the buffered answer flushes
  • add a regression test covering skipped reasoning, visible answer delivery, internal hook emission, and transcript mirroring

Why this PR exists

This is a hook-preserving replacement for the canonical fix path in #53762. PR #53762 has the right user-visible fix direction, but ClawSweeper flagged that its flushBufferedFinalAnswer() path discards the LaneDeliveryResult, so a buffered final answer can display in Telegram while bypassing the same preview-finalized hook/transcript path used by ordinary final segment delivery.

I cannot update #53762 directly, so this branch rebases the fix onto current main and addresses that review finding in the replacement patch.

Root cause

When Telegram final output is split into reasoning and answer lane segments, the reasoning segment can be handled/skipped without marking reasoning as delivered. The answer segment is then buffered, but the segments.length > 0 branch returns before the buffered final answer is drained.

A minimal flush fixes visible Telegram delivery, but the flush also needs to route any preview-finalized LaneDeliveryResult through emitPreviewFinalizedHook(...); otherwise internal message:sent and transcript mirroring diverge from normal final delivery.

Real behavior proof

  • Behavior or issue addressed: Telegram automatic direct-message delivery silently dropped the visible final answer when a final payload split into reasoning and answer lanes left the answer buffered behind a skipped reasoning segment.
  • Real environment tested: R2/OpenClaw production-style Linux droplet, OpenClaw npm global install 2026.5.12, systemd user gateway, Telegram channel enabled, real allowlisted direct Telegram chat, direct-message visible replies set to automatic.
  • Exact steps or command run after this patch: Applied the equivalent installed-bundle guard to the live OpenClaw Telegram dispatcher, restarted the gateway, injected a controlled Telegram ingress asking for exact final text R2_AUTO_OK_SIM, then ran the live health sequence including curl -sS http://127.0.0.1:18789/health, systemctl --user status openclaw-gateway.service --no-pager -l, openclaw gateway status, and the downstream hotfix checker.
  • Evidence after fix: Redacted live output: gateway /health returned {"ok":true,"status":"live"}; the downstream checker printed OpenClaw Telegram auto-delivery hotfix present; the Telegram sent-message cache recorded the outbound Bot API delivery at 2026-05-18T12:45:28Z, message id 27371; no message.action send tool was used.
  • Observed result after fix: The model final was exactly R2_AUTO_OK_SIM, and Telegram automatic delivery sent that visible answer through the Bot API instead of leaving it buffered and unsent.
  • What was not tested: I did not attach a screenshot or recording of the private Telegram chat; chat details are redacted. The live proof used the installed-bundle equivalent of this source patch, while the exact source branch is covered by the dispatcher regression test below.

Additional redacted proof context is posted on #53762: #53762 (comment)

Validation

  • git diff --check
  • OPENCLAW_VITEST_INCLUDE_FILE=/tmp/openclaw-telegram-include-v2.json node scripts/run-vitest.mjs run --config test/vitest/vitest.extension-telegram.config.ts
    • Result: extensions/telegram/src/bot-message-dispatch.test.ts passed, 68 tests

Note: I also tried node scripts/run-vitest.mjs run --config test/vitest/vitest.extension-telegram.config.ts bot-message-dispatch.test.ts, but that CLI-filter form reported No test files found, so I am not counting it as validation.

Related

@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 18, 2026
@clawsweeper

clawsweeper Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Workflow note: Future ClawSweeper reviews update this same comment in place.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

Summary
The PR updates Telegram segmented final delivery to flush buffered final answers, route preview-finalized flush results through hook/transcript mirroring, and add a dispatcher regression test.

Reproducibility: yes. Source inspection on current main shows a final payload split into reasoning and answer segments can buffer the answer and then return from the segmented-delivery branch without flushing it; I did not run the test lane in this read-only review.

PR rating
Overall: 🐚 platinum hermit
Proof: 🐚 platinum hermit
Patch quality: 🦞 diamond lobster
Summary: Good, likely mergeable PR with strong focused patch quality and sufficient redacted live proof, though independent Telegram proof would reduce residual transport risk.

Rank-up moves:

  • Optionally run independent Telegram live or Mantis proof if maintainers want unredacted transport confirmation before merge.
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

PR egg
✨ Hatched: 🥚 common Velvet Lint Imp

        /\     /\            
      _/  \___/  \_          
     /  ( o   o )  \         
    |      \_/      |        
    |   /\  ===  /\ |        
     \_/  \_____/  \_/       
        _/|_| |_|\_          
       /__| | | |__\         
          ' ' ' '            
         /_/     \_\         
       .-----------.         
      '-------------'        

Rarity: 🥚 common.
Trait: polishes edge cases.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Velvet Lint Imp in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • How to hatch it: reach status: 👀 ready for maintainer look or status: 🚀 automerge armed; that usually means sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

Real behavior proof
Sufficient (live_output): The PR body includes redacted live Telegram gateway/Bot API output showing after-fix automatic final-answer delivery, paired with targeted source-branch regression coverage for the hook path.

Mantis proof suggestion
A Telegram live run would independently verify the visible transport path and hook recording beyond the redacted author-provided output. A maintainer can ask Mantis to capture proof by posting a new PR comment that starts with the OpenClaw Mantis account mention, followed by:

telegram live: verify that a final payload split into hidden reasoning and visible answer sends the visible answer automatically and records the sent hook.

Risk before merge
Why this matters: - The supplied live proof is redacted and was run against an installed-bundle equivalent rather than this exact checkout; maintainers may still want independent Telegram live proof before merge.

  • The touched path controls whether buffered Telegram final answers are sent and mirrored, so a regression here could still affect message delivery even though the diff is small and targeted.

Maintainer options:

  1. Land With Supplied Proof (recommended)
    Maintainers can accept the residual transport risk because the diff is scoped to final segmented payloads and the PR includes redacted live Telegram output plus targeted regression coverage.
  2. Request Independent Telegram Proof
    Ask Mantis or the contributor to capture a redacted live Telegram proof showing the visible final answer delivery and hook/transcript behavior before merge.

Next step before merge
No automated repair is needed; maintainers should review and either land this replacement for #53762 or request independent Telegram live proof.

Security
Cleared: The diff only changes Telegram dispatcher control flow and a focused test, with no new dependencies, credentials, permissions, workflows, or supply-chain surface.

Review details

Best possible solution:

Land this focused Telegram dispatcher fix after maintainer review and required checks, or request independent Telegram live proof if maintainers want unredacted transport confirmation before merging.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main shows a final payload split into reasoning and answer segments can buffer the answer and then return from the segmented-delivery branch without flushing it; I did not run the test lane in this read-only review.

Is this the best way to solve the issue?

Yes. The PR keeps the fix inside Telegram segmented-final delivery, flushes only final buffered answers, and reuses the existing preview-finalized hook/transcript path rather than adding a competing delivery mechanism.

Label justifications:

  • P2: This is a focused Telegram message-loss bug fix with limited channel blast radius.
  • merge-risk: 🚨 message-delivery: The PR changes the final-answer flush path that decides whether buffered Telegram replies are sent and mirrored.

Acceptance criteria:

  • git diff --check
  • OPENCLAW_VITEST_INCLUDE_FILE=/tmp/openclaw-telegram-include-v2.json node scripts/run-vitest.mjs run --config test/vitest/vitest.extension-telegram.config.ts
  • Optional Telegram live or Mantis proof for the split reasoning/final-answer transport path

What I checked:

Likely related people:

  • @ngutman: Blame and commit metadata tie the current Telegram dispatcher and reasoning coordinator import in this checkout to commit 29f39db, with review metadata naming @ngutman. (role: current code path carrier; confidence: medium; commits: 29f39db8578c; files: extensions/telegram/src/bot-message-dispatch.ts, extensions/telegram/src/reasoning-lane-coordinator.ts)
  • Tyler Bea: Recent Telegram history shows commit 03c303d changed the same dispatcher for progress transcript mirroring, adjacent to the hook/transcript behavior this PR preserves. (role: recent transcript mirror contributor; confidence: medium; commits: 03c303d953ea; files: extensions/telegram/src/bot-message-dispatch.ts)
  • Ayaan Zaidi: Recent history shows commit 890139f refactored the native draft progress path in the same dispatcher surface. (role: recent area refactor contributor; confidence: medium; commits: 890139f99826; files: extensions/telegram/src/bot-message-dispatch.ts)
  • Alexander Krimm: Blame and log history show commit 7cc4258 changed native Telegram DM draft progress logic adjacent to the final-answer lane delivery path. (role: adjacent draft-progress feature contributor; confidence: medium; commits: 7cc4258dd592; files: extensions/telegram/src/bot-message-dispatch.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3e6f7494af75.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 18, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels May 18, 2026
@clawsweeper clawsweeper Bot temporarily deployed to qa-live-shared May 18, 2026 15:59 Inactive
@Takhoffman Takhoffman changed the title Preserve Telegram hooks when flushing buffered finals fix: Preserve Telegram hooks when flushing buffered finals May 18, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 18, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 18, 2026
@bpconnor3-r2

Copy link
Copy Markdown
Author

Additional downstream evidence from R2 after an OpenClaw package update:

  • Runtime updated to OpenClaw 2026.5.18 on 2026-05-19.
  • The installed Telegram bundle changed from the prior hashed file to /usr/lib/node_modules/openclaw/dist/bot-BRuINTsq.js.
  • Before the downstream hotpatch, that bundle still had the same buffered-final risk: the segments.length > 0 branch tracked media and returned before flushing a buffered final answer. Its flushBufferedFinalAnswer() also delivered the buffered answer without preserving the preview-finalized hook result path.
  • R2 applied the same behavior as this PR to the live installed bundle, then restarted the gateway.

Post-patch R2 verification:

$ ./scripts/openclaw_auto_delivery_hotfix.sh check
OpenClaw Telegram auto-delivery hotfix present: /usr/lib/node_modules/openclaw/dist/bot-BRuINTsq.js

$ curl -fsS http://127.0.0.1:18789/health
{"ok":true,"status":"live"}

$ openclaw gateway status
CLI version: 2026.5.18 (/usr/bin/openclaw)
Gateway version: 2026.5.18
Runtime: running
Connectivity probe: ok
Capability: admin-capable

Recent Telegram sends after the restart were recorded in the gateway journal, including outbound sendMessage successes to the direct chat. This is not a replacement for maintainer review, but it confirms the issue is still present in the current installed package line and that the PR shape matches the live downstream mitigation.

@RomneyDa

Copy link
Copy Markdown
Member

Heads up: this PR needs to be updated against current main before the new required Dependency Guard check can pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: XS status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: streaming: partial drops text block when assistant turn contains [thinking, text]

2 participants