Skip to content

feat(slack): render native charts from portable presentations#102635

Merged
steipete merged 1 commit into
mainfrom
codex/slack-native-charts
Jul 10, 2026
Merged

feat(slack): render native charts from portable presentations#102635
steipete merged 1 commit into
mainfrom
codex/slack-native-charts

Conversation

@steipete

@steipete steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Related: #12602

What Problem This Solves

Slack users asking an OpenClaw agent to visualize structured data currently receive prose or must rely on Slack-specific raw Block Kit payloads. The portable presentation contract has no chart primitive, so agents cannot request native Slack charts while retaining accessible and cross-channel delivery.

Why This Change Was Made

Adds one portable chart block for line, bar, area, and pie data. Slack maps valid charts to its public data_visualization Block Kit block; unsupported channels and rejected Slack blocks receive the same deterministic text representation.

Slack-specific validation owns the platform limits, including Slack's live maximum of two data-visualization blocks per message. This adds no config, environment variable, OAuth scope, dependency, file upload, or image renderer. Gateway-routed channel actions retain gateway ownership; local adapters retain core presentation rendering. Explicit plugin payload-preparation declines also remain on their provider-native action path.

User Impact

Agents and CLI/plugin producers can send structured chart data once and get native inline charts in Slack. Discord, Telegram, Feishu, Matrix, and other channels without native chart support retain the chart title, axes, categories, series, and values as readable text.

Existing presentation payloads remain unchanged.

Evidence

Maintainer API direction: accept chart as a portable presentation primitive. Release-note context stays in this PR body because the landing gate reserves CHANGELOG.md for release work.

AI-assisted implementation; Slack API, source, sibling channels, tests, and runtime ownership paths were reviewed. Private Slack identifiers and credentials were not disclosed.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: matrix Channel integration: matrix channel: slack Channel integration: slack channel: telegram Channel integration: telegram cli CLI command changes agents Agent runtime and tooling channel: feishu Channel integration: feishu size: XL maintainer Maintainer-authored PR labels Jul 9, 2026
@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 9, 2026, 10:46 AM ET / 14:46 UTC.

Summary
The PR adds portable chart presentation blocks, Slack native data-visualization rendering, and cross-channel fallback text with related docs and tests.

Reproducibility: yes. for the review finding: source inspection shows quoteText is a generic message-tool argument, buildSendPayloadParts only copies channelData into the reply payload, and Telegram sendPayload only reads channelData.telegram.quoteText. Not applicable as a bug reproduction for the chart feature itself.

Review metrics: 1 noteworthy metric.

  • Public Presentation API Surface: 2 added: chart block kind and charts capability flag. These become plugin-facing contracts that third-party channel plugins may depend on after merge.

Stored data model
Persistent data-model change detected: database schema: extensions/codex/doctor-contract-api.test.ts, migration/backfill/repair: extensions/codex/doctor-contract-api.test.ts, migration/backfill/repair: src/commands/doctor-config-preflight.state-migration.test.ts, migration/backfill/repair: src/commands/doctor-config-preflight.ts, migration/backfill/repair: src/commands/doctor-security.test.ts, migration/backfill/repair: src/flows/doctor-health-contributions.test.ts, and 20 more. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🦐 gold shrimp
Result: blocked until stronger real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Fix Telegram quoteText preservation for presentation sends.
  • [P1] Add redacted native Slack chart proof or get an explicit maintainer proof waiver.

Proof guidance:

  • [P1] Needs stronger real behavior proof before merge: Telegram fallback proof exists, but the central native Slack chart behavior is supported only by a private, non-inspectable attestation and needs a redacted Slack artifact or maintainer waiver before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Telegram presentation sends can silently lose the existing quoteText behavior until the core delivery path preserves Telegram channelData.
  • [P1] The PR expands the public plugin SDK/message presentation contract with a chart block and charts capability that downstream channel plugins may treat as stable after merge.
  • [P1] The central native Slack chart path is still supported only by a private attestation rather than an uploaded redacted artifact reviewers can inspect.

Maintainer options:

  1. Fix Telegram Metadata And Require Slack Proof (recommended)
    Preserve Telegram quoteText on the core presentation path, then require an inspectable native Slack chart artifact before merge.
  2. Accept Proof Risk After Code Fix
    Maintainers may fix the Telegram regression and explicitly accept the private Slack attestation instead of requiring a public artifact.
  3. Pause The Shared Contract
    If chart should not become stable plugin-facing presentation surface now, pause this PR and continue under the broader Slack rich-output tracker.

Next step before merge

  • [P1] The PR needs contributor-visible Slack proof, a targeted code fix, and protected maintainer review rather than conservative cleanup closure.

Maintainer decision needed

  • Question: After the Telegram quoteText regression is fixed, should this PR require uploaded redacted native Slack chart proof before merge, or may maintainers accept the private Slack attestation?
  • Rationale: The implementation adds a public presentation primitive and Slack API behavior, but ClawSweeper cannot verify the central Slack runtime behavior from a private uninspectable run.
  • Likely owner: steipete — They posted the API-direction and exact-head evidence comments and have recent presentation/Slack history.
  • Options:
    • Require Inspectable Slack Proof (recommended): Ask for a redacted screenshot, recording, transcript, log, or live output showing a portable chart rendering natively in Slack after the code fix.
    • Accept Private Attestation: A maintainer can explicitly waive public Slack proof and own the remaining native Slack runtime risk after the code fix.
    • Pause Under Rich Output Umbrella: If proof or API direction cannot be confirmed, pause this PR under the broader Slack rich-output issue.

Security
Cleared: No concrete security or supply-chain concern was found; the effective chart path adds no dependency, workflow, lockfile, permission, secret, or downloaded-code execution surface.

Review findings

  • [P2] Preserve Telegram quote text on core presentation sends — src/infra/outbound/outbound-send-service.ts:307-310
Review details

Best possible solution:

Preserve Telegram native quote metadata when presentation sends take the core delivery route, then require inspectable Slack native-chart proof or an explicit maintainer proof waiver before merge.

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

Yes for the review finding: source inspection shows quoteText is a generic message-tool argument, buildSendPayloadParts only copies channelData into the reply payload, and Telegram sendPayload only reads channelData.telegram.quoteText. Not applicable as a bug reproduction for the chart feature itself.

Is this the best way to solve the issue?

No until the Telegram quoteText regression is fixed. The chart architecture is otherwise the right owner boundary: shared presentation owns portable fallback while Slack owns native data_visualization validation and rendering.

Full review comments:

  • [P2] Preserve Telegram quote text on core presentation sends — src/infra/outbound/outbound-send-service.ts:307-310
    When a Telegram message.send includes both presentation and top-level quoteText, this branch can choose the core presentation path here because Telegram has sendPayload but no prepareSendPayload. The payload built by buildSendPayloadParts only carries channelData, while Telegram delivery reads channelData.telegram.quoteText, so the native quote text is silently lost. This is a late ClawSweeper finding on the same reviewed head; carry quoteText into Telegram channelData before core delivery or keep this case on the Telegram action path.
    Confidence: 0.89
    Late finding: first raised on code an earlier review cycle already covered.

Overall correctness: patch is incorrect
Overall confidence: 0.87

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • remove proof: 🎥 video: Current real behavior proof evidence kind is linked_artifact.

Label justifications:

  • P2: This is a normal-priority channel/API feature with bounded delivery impact, not a core outage or security issue.
  • merge-risk: 🚨 compatibility: The PR adds a new portable presentation block and channel capability flag to the plugin SDK-facing surface.
  • merge-risk: 🚨 message-delivery: The PR changes chart presentation routing and currently drops Telegram quote metadata on the core presentation path.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs stronger real behavior proof before merge: Telegram fallback proof exists, but the central native Slack chart behavior is supported only by a private, non-inspectable attestation and needs a redacted Slack artifact or maintainer waiver before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • mantis: telegram-visible-proof: Mantis should capture Telegram visible proof. The PR changes visible Telegram chart fallback text and the remaining quoteText regression is Telegram-visible message behavior.
Evidence reviewed

Acceptance criteria:

  • [P1] pnpm test src/infra/outbound/outbound-send-service.test.ts src/infra/outbound/message-action-runner.plugin-dispatch.test.ts extensions/telegram/src/outbound-adapter.test.ts extensions/slack/src/data-visualization.test.ts extensions/slack/src/outbound-payload.test.ts.
  • [P1] pnpm check:changed -- src/infra/outbound/outbound-send-service.ts extensions/telegram/src/outbound-adapter.ts extensions/slack/src/data-visualization.ts.

What I checked:

  • repository_policy_applied: Read the full root AGENTS.md and relevant scoped guides for docs, extensions, plugin SDK, agents/tools, outbound, channels, plugins, UI, Android, and gateway server methods; plugin SDK and channel delivery changes are compatibility-sensitive. (AGENTS.md:1, 428c68a3c71f)
  • public_chart_contract_added: The PR adds MessagePresentationChartBlock for pie and bar/area/line charts and includes it in the public MessagePresentationBlock union. (src/interactive/payload.ts:185, 4f92d51287df)
  • plugin_capability_surface_added: The PR adds a charts capability flag to ChannelPresentationCapabilities, making this plugin-facing channel contract surface rather than Slack-only private code. (src/channels/plugins/outbound.types.ts:66, 4f92d51287df)
  • slack_native_chart_rendering: Slack rendering validates chart title/label/series limits and maps validated portable charts to data_visualization blocks; Slack's official docs describe data_visualization for line, bar, area, and pie charts with these field-level constraints. (docs.slack.dev) (extensions/slack/src/data-visualization.ts:78, 4f92d51287df)
  • slack_chart_block_limit_and_fallback: Slack presentation rendering emits at most two native data_visualization blocks and falls back to deterministic chart text when a chart cannot render natively. (extensions/slack/src/blocks-render.ts:302, 4f92d51287df)
  • telegram_quote_source_contract: The message tool exposes top-level quoteText as a Telegram reply quote argument, so existing Telegram sends can rely on that public tool parameter. (src/agents/tools/message-tool.ts:540, 428c68a3c71f)

Likely related people:

  • steipete: Recent main history includes typed presentation command actions and presentation capability work, and the PR discussion records them posting API direction plus exact-head evidence. (role: recent presentation/API contributor and PR evidence owner; confidence: high; commits: d641126c1dd6, ad861d4c9df8, 531dacb699f8; files: src/interactive/payload.ts, src/plugin-sdk/interactive-runtime.ts, extensions/slack/src/blocks-render.ts)
  • vincentkoc: History and the linked Slack rich-output issue connect them to outbound action context and shipped Slack Block Kit slices adjacent to this PR's routing and compatibility surface. (role: recent outbound and Slack rich-output contributor; confidence: medium; commits: aa79ab1403e8, a22a1edc8faa, 56a7000b3efa; files: src/infra/outbound/outbound-send-service.ts, src/infra/outbound/message-action-runner.ts, extensions/slack/src/outbound-adapter.ts)
  • ZOOWH: GitHub path history shows the merged Slack native presentation delivery repair that this chart rendering builds on. (role: recent adjacent Slack presentation contributor; confidence: medium; commits: f683c9e9bdb2; files: extensions/slack/src/blocks-render.ts, extensions/slack/src/outbound-adapter.ts)
  • NianJiuZst: Recent Telegram outbound history includes rich-message gating, relevant to Telegram presentation and fallback delivery behavior. (role: adjacent Telegram delivery contributor; confidence: low; commits: a375d6c84963; files: extensions/telegram/src/outbound-adapter.ts)
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.

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.
Review history (5 earlier review cycles)
  • reviewed 2026-07-09T09:58:58.347Z sha e96d49a :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-09T13:17:04.580Z sha 2e5369b :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-09T13:29:19.323Z sha 2e5369b :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-09T14:09:09.416Z sha 4f92d51 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-09T14:16:37.325Z sha 4f92d51 :: needs real behavior proof before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. 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. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels Jul 9, 2026
@clawsweeper
clawsweeper Bot temporarily deployed to qa-live-shared July 9, 2026 10:02 Inactive
@openclaw-mantis

Copy link
Copy Markdown
Contributor

Mantis Telegram Desktop Proof

Summary: Mantis captured native Telegram Desktop before/after GIFs showing chart fallback text in Telegram.

Main This PR
Baseline native Telegram Desktop proof GIF Candidate native Telegram Desktop proof GIF

Motion-trimmed clips:

Raw QA files: https://artifacts.openclaw.ai/mantis/telegram-desktop/pr-102635/run-29010134383-1/index.json

@steipete-oai
steipete-oai force-pushed the codex/slack-native-charts branch from e96d49a to 361e1f8 Compare July 9, 2026 12:40
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Jul 9, 2026
@clawsweeper clawsweeper Bot added proof: 🎥 video Contributor real behavior proof includes video or recording evidence. feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. labels Jul 9, 2026

steipete-oai commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Evidence for exact head 4f92d51287dfa481444ba469ed7f846fc973d6f9:

Maintainer API decision for this PR: accept chart as a portable presentation primitive. Correction: the landing gate reserves CHANGELOG.md for release work, so the entry was removed and release-note context remains in the PR body.

@clawsweeper re-review

@steipete
steipete requested a review from a team as a code owner July 9, 2026 13:54
@openclaw-barnacle openclaw-barnacle Bot added channel: googlechat Channel integration: googlechat channel: msteams Channel integration: msteams app: android App: android app: web-ui App: web-ui gateway Gateway runtime labels Jul 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f92d51287

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/infra/outbound/outbound-send-service.ts
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Final exact-head update for 4f92d51287dfa481444ba469ed7f846fc973d6f9:

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot removed the proof: 🎥 video Contributor real behavior proof includes video or recording evidence. label Jul 9, 2026
@steipete steipete self-assigned this Jul 10, 2026
@steipete-oai
steipete-oai force-pushed the codex/slack-native-charts branch from 4f92d51 to d900510 Compare July 10, 2026 02:51
@openclaw-barnacle openclaw-barnacle Bot removed channel: googlechat Channel integration: googlechat channel: msteams Channel integration: msteams app: android App: android app: web-ui App: web-ui gateway Gateway runtime commands Command implementations channel: qqbot extensions: codex extensions: google labels Jul 10, 2026
@steipete

Copy link
Copy Markdown
Contributor Author

Land-ready evidence for rewritten head d900510883f07ff1e802587d1a8365bf71f50fa2:

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@steipete
steipete merged commit add2c58 into main Jul 10, 2026
108 of 112 checks passed
@steipete
steipete deleted the codex/slack-native-charts branch July 10, 2026 03:05
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

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

Labels

agents Agent runtime and tooling channel: discord Channel integration: discord channel: feishu Channel integration: feishu channel: matrix Channel integration: matrix channel: slack Channel integration: slack channel: telegram Channel integration: telegram cli CLI command changes docs Improvements or additions to documentation feature: ✨ showcase ClawSweeper spotlight: unusually compelling feature idea for maintainer attention. maintainer Maintainer-authored PR 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. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. scripts Repository scripts size: XL 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.

2 participants