Skip to content

fix(telegram): honor table mode while chunking#85098

Open
zerone0x wants to merge 1 commit into
openclaw:mainfrom
zerone0x:fix/85085-telegram-table-mode
Open

fix(telegram): honor table mode while chunking#85098
zerone0x wants to merge 1 commit into
openclaw:mainfrom
zerone0x:fix/85085-telegram-table-mode

Conversation

@zerone0x

@zerone0x zerone0x commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Telegram outbound chunking ignored channels.telegram.markdown.tables for non-HTML/streamed chunked messages.
  • Solution: propagate outbound cfg/accountId into chunker contexts and resolve Telegram table mode before Markdown-to-HTML chunking.
  • What changed: markdownToTelegramHtmlChunks now accepts chunk options; Telegram chunker forwards resolved tableMode; core outbound planning/payload helpers pass config context; regression tests cover both direct format and adapter/core seams.
  • What did NOT change (scope boundary): no Telegram send API changes, no media behavior changes, no default table-mode change.

Motivation

  • Fixes raw Markdown tables (| --- |) leaking into Telegram chunked/streaming messages even when markdown.tables is configured for bullets.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Telegram chunked Markdown table rendering now honors channels.telegram.markdown.tables.

  • Real environment tested: local source checkout with Node v22.19.0.

  • Exact steps or command run after this patch: corepack pnpm exec tsx -e 'import { markdownToTelegramHtmlChunks } from "./extensions/telegram/src/format.ts"; const input=["| Name | Status |","| --- | --- |","| Bot | OK |"].join("\n"); const rendered=markdownToTelegramHtmlChunks(input,4096,{tableMode:"bullets"}).join(""); console.log("OpenClaw Telegram chunk render proof"); console.log("input:"); console.log(input); console.log("rendered:"); console.log(rendered); console.log("contains raw separator:", rendered.includes("| --- | --- |"));'

  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):

    OpenClaw Telegram chunk render proof
    input:
    | Name | Status |
    | --- | --- |
    | Bot | OK |
    rendered:
    <b>Bot</b>
    • Status: OK
    contains raw separator: false
    
  • Supplemental local tests: node scripts/run-vitest.mjs extensions/telegram/src/format.test.ts extensions/telegram/src/outbound-adapter.test.ts src/infra/outbound/message-plan.test.ts src/plugin-sdk/reply-payload.test.ts passed (Test Files 4 passed (4) / Tests 104 passed (104)).

  • Observed result after fix: configured tables: "bullets" removes raw table separator output from Telegram chunked HTML and renders the table row as Telegram-safe bullet text.

  • What was not tested: live Telegram bot delivery.

  • Before evidence (optional but encouraged): issue reproduction documents raw table separators in Telegram chunked/streamed output.

Root Cause (if applicable)

  • Root cause: markdownToTelegramHtmlChunks did not accept/pass tableMode, and outbound chunker call sites only passed formatting context, not config/account context.
  • Missing detection / guardrail: no regression test covered configured Markdown table modes through Telegram chunked outbound paths.
  • Contributing context (if known): HTML parse-mode paths bypass Markdown conversion, so the bug affected Markdown chunking/streaming paths specifically.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/telegram/src/format.test.ts, extensions/telegram/src/outbound-adapter.test.ts, src/infra/outbound/message-plan.test.ts, src/plugin-sdk/reply-payload.test.ts.
  • Scenario the test should lock in: configured tables: "bullets" flows from outbound config/account context to Telegram Markdown chunk rendering.
  • Why this is the smallest reliable guardrail: it covers the format helper plus the adapter and shared outbound context propagation seams without live Telegram credentials.
  • Existing test that already covers this (if any): none.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

Telegram chunked/streamed Markdown messages now honor configured table rendering modes instead of emitting raw Markdown tables.

Diagram (if applicable)

Before:
outbound config -> chunker receives formatting only -> default table mode -> raw table separators may remain

After:
outbound config/account -> chunker context -> resolve table mode -> Telegram HTML chunks use configured table rendering

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: Linux local checkout
  • Runtime/container: Node v22.19.0
  • Model/provider: N/A
  • Integration/channel (if any): Telegram
  • Relevant config (redacted): channels.telegram.markdown.tables = "bullets"

Steps

  1. Configure Telegram Markdown tables to bullets.
  2. Send/chunk Markdown table text through Telegram outbound Markdown chunking.
  3. Inspect rendered Telegram HTML chunks.

Expected

  • Table rows are converted according to bullets; raw | --- | separator text is not delivered.

Actual

  • Fixed by this PR; tests verify the configured chunk path.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: targeted unit/seam tests for format helper, Telegram outbound adapter, outbound message planning, and payload chunking context propagation.
  • Edge cases checked: HTML parse-mode path remains routed to HTML splitting; Markdown table mode is only applied to Markdown chunking path.
  • What you did not verify: live Telegram bot delivery and broad full-suite CI.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: shared outbound chunker context type changes could affect channel implementations.
    • Mitigation: additive optional fields only; existing chunkers continue to accept/ignore the third argument.

@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram size: S triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 21, 2026
@clawsweeper

clawsweeper Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof 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 forwards config/account context into outbound text chunkers, lets Telegram HTML chunk rendering accept tableMode, and adds focused regression tests for Telegram formatting, outbound adapter, message planning, and reply payload chunking.

Reproducibility: yes. from source inspection: current main has a table-mode-aware Telegram chunk renderer underneath, but the HTML chunk wrapper and outbound chunker path do not pass table mode or config/account context. I did not run a live failing Telegram send in this read-only review.

PR rating
Overall: 🦐 gold shrimp
Proof: 🦐 gold shrimp
Patch quality: 🦐 gold shrimp
Summary: The fix is well targeted and tested, but merge confidence is limited by the undocumented plugin API context change and missing live Telegram behavior proof.

Rank-up moves:

  • Document ctx.cfg and ctx.accountId for outbound chunkers in the plugin channel docs or get explicit maintainer acceptance that this remains internal.
  • Add redacted real Telegram proof showing a configured tables: "bullets" chunked or streamed message no longer displays raw table separators.
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.

Real behavior proof
Needs stronger real behavior proof before merge: The PR body includes copied terminal output from a local formatter helper and targeted tests, but it does not show after-fix Telegram delivery for the visible chunked/streamed path; add a redacted screenshot, recording, terminal/live output, or log that exercises the real send path and update the PR body to trigger re-review.

Mantis proof suggestion
A native Telegram Desktop proof would directly show whether the user-visible chunked table output honors the configured table mode. 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 desktop proof: verify Telegram chunked Markdown table output honors channels.telegram.markdown.tables=bullets and does not show raw table separators.

Risk before merge

  • The PR widens a plugin-facing chunker context and begins passing config/account context into shared chunker calls; maintainers should consciously accept and document that contract before merge.
  • The supplied proof shows a local formatter helper invocation and targeted tests, but it does not show a real Telegram chunked or streamed delivery rendering the configured table mode.

Maintainer options:

  1. Document and prove the new context (recommended)
    Update the plugin channel docs/API expectations for ChannelOutboundChunkContext cfg and accountId, then add redacted real Telegram proof for the chunked or streamed table-rendering path before merge.
  2. Accept the additive API risk
    Maintainers can intentionally accept the optional context fields as a compatible plugin API extension if they record that choice and are comfortable with the current focused tests.
  3. Keep the branch open for owner review
    If the permanent chunker contract is not settled, pause this PR for Telegram/plugin-SDK owner review rather than merging an undocumented public surface change.

Next step before merge
Needs contributor-visible Telegram proof and maintainer acceptance of the documented plugin chunker context before merge; automation cannot supply the contributor’s real-environment proof.

Security
Cleared: No concrete security or supply-chain issue found; the diff adds no dependencies, workflow changes, network calls, permissions, or secret-handling changes.

Review findings

  • [P2] Document the new chunker context fields — src/channels/plugins/outbound.types.ts:135-136
Review details

Best possible solution:

Land the Telegram fix with a documented additive chunker-context contract, focused regression coverage, and live or maintainer-waived Telegram proof for the visible chunked/streamed table rendering path.

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

Yes from source inspection: current main has a table-mode-aware Telegram chunk renderer underneath, but the HTML chunk wrapper and outbound chunker path do not pass table mode or config/account context. I did not run a live failing Telegram send in this read-only review.

Is this the best way to solve the issue?

Mostly yes: forwarding resolved config/account context to the Telegram chunker is the narrow fix shape, but the public chunker context extension needs docs/API acceptance and live Telegram proof before merge.

Label changes:

  • add P2: This is a normal-priority Telegram formatting bug fix with limited channel blast radius.
  • add merge-risk: 🚨 compatibility: The PR changes an exported plugin-facing chunker context and the core behavior for what context chunkers receive.
  • add rating: 🦐 gold shrimp: Current PR rating is 🦐 gold shrimp because proof is 🦐 gold shrimp, patch quality is 🦐 gold shrimp, and The fix is well targeted and tested, but merge confidence is limited by the undocumented plugin API context change and missing live Telegram behavior proof.
  • add status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes copied terminal output from a local formatter helper and targeted tests, but it does not show after-fix Telegram delivery for the visible chunked/streamed path; add a redacted screenshot, recording, terminal/live output, or log that exercises the real send path and update the PR body to trigger re-review.
  • add mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. This changes visible Telegram chat rendering for chunked/streamed Markdown tables and can be demonstrated in a short Telegram Desktop proof.

Label justifications:

  • P2: This is a normal-priority Telegram formatting bug fix with limited channel blast radius.
  • merge-risk: 🚨 compatibility: The PR changes an exported plugin-facing chunker context and the core behavior for what context chunkers receive.
  • rating: 🦐 gold shrimp: Current PR rating is 🦐 gold shrimp because proof is 🦐 gold shrimp, patch quality is 🦐 gold shrimp, and The fix is well targeted and tested, but merge confidence is limited by the undocumented plugin API context change and missing live Telegram behavior proof.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: The PR body includes copied terminal output from a local formatter helper and targeted tests, but it does not show after-fix Telegram delivery for the visible chunked/streamed path; add a redacted screenshot, recording, terminal/live output, or log that exercises the real send path and update the PR body to trigger re-review.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. This changes visible Telegram chat rendering for chunked/streamed Markdown tables and can be demonstrated in a short Telegram Desktop proof.

Full review comments:

  • [P2] Document the new chunker context fields — src/channels/plugins/outbound.types.ts:135-136
    This adds cfg and accountId to the exported chunker context, but the plugin author docs still only describe ctx.formatting for chunker(text, limit, ctx). Since ChannelOutboundAdapter is exposed through plugin SDK entrypoints, please document the new fields and their compatibility expectations so third-party channel authors do not rely on an undocumented contract.
    Confidence: 0.82

Overall correctness: patch is incorrect
Overall confidence: 0.82

Acceptance criteria:

  • node scripts/run-vitest.mjs extensions/telegram/src/format.test.ts extensions/telegram/src/outbound-adapter.test.ts src/infra/outbound/message-plan.test.ts src/plugin-sdk/reply-payload.test.ts
  • Redacted live Telegram Desktop or bot-transcript proof for configured chunked/streamed table output

What I checked:

Likely related people:

  • @steipete: Recent current-main history and blame around the Telegram formatting and outbound adapter files point to Peter Steinberger, including broad Telegram work and the current-main boundary for the affected files. (role: recent Telegram/outbound area contributor; confidence: medium; commits: e510042870cf, 94b6d9f8b238, 04c976b43d50; files: extensions/telegram/src/format.ts, extensions/telegram/src/outbound-adapter.ts)
  • @vincentkoc: Recent commits by Vincent Koc split and narrowed reply-payload and outbound adapter type surfaces that this PR now extends. (role: plugin SDK seam contributor; confidence: medium; commits: a88fbf0f6476, b1290e61fd8a, f3f1ab0a3f7a; files: src/plugin-sdk/reply-payload.ts, src/channels/plugins/outbound.types.ts)
  • Robin Waslander: A prior Telegram long-message chunking fix changed the same formatter/chunking surface, making this a useful routing candidate for chunk behavior review. (role: adjacent Telegram chunking contributor; confidence: low; commits: ab2ef7bbfc5c; files: extensions/telegram/src/format.ts)

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

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels May 21, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels May 21, 2026
@clawsweeper

clawsweeper Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

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: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: S status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] markdown.tables config is ignored during Telegram outbound message chunking / streaming

1 participant