Skip to content

fix(telegram): combine voice payload with preceding streamed text#81131

Closed
sdimantsd wants to merge 3 commits into
openclaw:mainfrom
sdimantsd:fix/telegram-voice-caption-combined
Closed

fix(telegram): combine voice payload with preceding streamed text#81131
sdimantsd wants to merge 3 commits into
openclaw:mainfrom
sdimantsd:fix/telegram-voice-caption-combined

Conversation

@sdimantsd

@sdimantsd sdimantsd commented May 12, 2026

Copy link
Copy Markdown

Summary

When a final voice payload arrives in Telegram after partial/block streaming has already sent the text, two separate Telegram messages appear: first the streamed text, then the voice note. This restores the pre-bca16d0f00 behavior where audioAsVoice payloads implicitly carried the spoken text as the voice's caption, so voice+text arrive as one combined message.

Behavior change

Before: User receives 1) streamed text message 2) separate voice note (two messages).
After: User receives a single voice note with the spoken text as caption.

Real behavior proof

After-fix screenshot (Telegram chat, agent reply with TTS):

after-fix

The single message in the screenshot is the voice note with the spoken text bound to it as caption.

Running on openclaw:local built from this branch on top of 2026.5.12-beta.1. Patch identifiable at runtime in /app/dist/bot-DiUeqsFG.js (grep -c voice-combine returns 2).

Mechanism

When info.kind === final, effectivePayload.audioAsVoice === true, and answerLane.hasStreamedMessage:

  1. Delete the previously-streamed text message via bot.api.deleteMessage.
  2. Rebuild payloadForSend with text set to the spoken text — the bot send pipeline then attaches it as caption to the voice.
  3. Clear answerLane.hasStreamedMessage and the partial-text trackers.

The keying on audioAsVoice + hasStreamedMessage is necessary because audioAsVoice payloads don't set mediaUrls (so reply.hasMedia=false), and in partial-streaming mode the payload carries text (so reply.trimmedText is non-empty).

Test plan

  • Local reproduction confirmed: streaming text + voice payload arrives as a single voice message with caption (see screenshot).
  • Maintainer review of keying logic appreciated — happy to widen/narrow the condition if there are edge cases.

When a final voice payload arrives after partial/block streaming already
sent the text, delete the streamed text message and attach the spoken
text as caption so voice+text arrive as one combined message.

This restores pre-bca16d0f00 behavior where audioAsVoice payloads
implicitly carried the spoken text and the streamed text was suppressed.

Note: audioAsVoice payloads don't set mediaUrls (reply.hasMedia=false)
and in partial streaming mode the payload carries text (reply.trimmedText
non-empty), so we key only on audioAsVoice + hasStreamedMessage.
@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 12, 2026
@clawsweeper

clawsweeper Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close this PR as superseded: the remaining Telegram final-mode TTS behavior is now tracked by the canonical issue and broader replacement PR, while this one-file Telegram transport patch is the riskier delete-and-resend path.

Canonical path: Close this branch and continue the captioned final-mode TTS decision and implementation review in #83511 and #83988.

So I’m closing this here and keeping the remaining discussion on #83511 and #83988.

Review details

Best possible solution:

Close this branch and continue the captioned final-mode TTS decision and implementation review in #83511 and #83988.

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

Yes. Source and tests on current main show late media after streamed Telegram text is delivered as separate media while the streamed text remains, and the PR screenshot shows the proposed combined voice-caption result; I did not run a fresh live Telegram session in this read-only review.

Is this the best way to solve the issue?

No. This is not the best fix because it deletes an already-delivered Telegram message in the transport layer; the safer canonical path is the upstream capability-gated final-TTS deferral under review.

Security review:

Security review cleared: No concrete security or supply-chain concern was found; the diff only changes Telegram runtime delivery behavior.

AGENTS.md: found and applied where relevant.

What I checked:

  • Repository policy applied: Root AGENTS.md was read fully from disk; the review used its guidance on full-path PR review, Telegram/channel proof, and compatibility-sensitive message delivery changes. (AGENTS.md:1, fef839407995)
  • Scoped extension policy applied: The extension boundary guide was read and applied because the touched file is under a bundled plugin. (extensions/AGENTS.md:1, fef839407995)
  • Telegram maintainer note applied: The Telegram review note requires real Telegram proof for transport/streaming behavior and treats a single visible preview message as intentional streaming behavior. (.agents/maintainer-notes/telegram.md:1, fef839407995)
  • Current main owns late media behavior elsewhere: Current main routes late media after streamed text through createLaneTextDeliverer, finalizing the preview and sending a media-only payload rather than deleting the visible text in the dispatch fallback branch. (extensions/telegram/src/lane-delivery-text-deliverer.ts:544, fef839407995)
  • Current main tests the separate late-media behavior: The Telegram dispatch test explicitly expects the streamed text to remain and the late media payload to be delivered without text. (extensions/telegram/src/bot-message-dispatch.test.ts:2582, fef839407995)
  • Current main does not treat spokenText as a successful caption: The delivery test asserts spokenText is not rendered as a caption on a successful voice send, so changing that behavior is a delivery-policy decision rather than a small transport cleanup. (extensions/telegram/src/bot/delivery.test.ts:1269, fef839407995)

Likely related people:

  • obviyus: GitHub commit metadata and blame connect this person to the current lane-delivery behavior and the earlier streamed-text finalization change that this PR tries to alter. (role: introduced/current behavior contributor; confidence: high; commits: d498b1cce49c, bca16d0f00c0; files: extensions/telegram/src/lane-delivery-text-deliverer.ts, extensions/telegram/src/bot-message-dispatch.ts, extensions/telegram/src/bot-message-dispatch.test.ts)
  • ragesaq: Recent current-main history touches nearby auto-reply/channel final delivery behavior that intersects with the final-mode TTS delivery path. (role: recent adjacent contributor; confidence: medium; commits: a15427d605fe; files: src/auto-reply/reply/dispatch-acp.ts, src/auto-reply/reply/dispatch-from-config.ts, extensions/telegram/src/shared.ts)
  • Jerry-Xin: Authored the open broader PR that currently owns the captioned final-mode TTS implementation path for the canonical issue. (role: active replacement PR author; confidence: high; commits: e2de93d4f6ae; files: src/auto-reply/reply/dispatch-acp.ts, src/auto-reply/reply/dispatch-from-config.ts, extensions/telegram/src/shared.ts)

Codex review notes: model internal, reasoning high; reviewed against fef839407995.

@clawsweeper clawsweeper Bot added the mantis: telegram-visible-proof Mantis should capture Telegram visible proof. label May 12, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 13, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 28, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels May 28, 2026
@clawsweeper

clawsweeper Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg: 🔥 warming; proof passed, review follow-up or readiness checks remain. Hatch with @clawsweeper hatch when eligible.

Rules and details

Hatchability:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

About:

  • Eggs appear after real-behavior proof passes. They are collectible flavor only.
  • Review momentum changes the shell state: follow-up work warms it, re-review makes it wobble, and a clean final review lets it hatch.
  • 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.

@openclaw-barnacle openclaw-barnacle Bot removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. stale Marked as stale due to inactivity labels May 28, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels May 29, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 29, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels May 29, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 29, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels May 29, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 29, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 14, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label Jun 14, 2026
@openclaw-clownfish

Copy link
Copy Markdown
Contributor

Thanks @sdimantsd for the focused Telegram proof and patch in #81131. I am closing this as superseded by #83988 because the remaining final-mode TTS churn is now being handled in the broader canonical path for #83511.

Clownfish is keeping the canonical PR open there so implementation review, validation, and follow-up stay in one place. The source PR context and attribution are preserved in the cluster record, and your Telegram repro/proof remains useful for the canonical review. If this branch covers a different reproduction path or the issue still reproduces after #83988 lands, please reply and we can reopen or split it back out.

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

Labels

channel: telegram Channel integration: telegram clownfish Tracked by Clownfish automation mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal backlog priority with limited blast radius. proof: 📸 screenshot Contributor real behavior proof includes screenshot evidence. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XS status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant