Skip to content

feat(channels): batch 2 producers drop media placeholder bodies#111665

Merged
steipete merged 2 commits into
mainfrom
claude/media-placeholder-batch2
Jul 20, 2026
Merged

feat(channels): batch 2 producers drop media placeholder bodies#111665
steipete merged 2 commits into
mainfrom
claude/media-placeholder-batch2

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Batch 2 of the media-placeholder elimination program (PR1 #111315, batch 1 #111447). Discord, Feishu, and MSTeams — the aggregate/expected-count/sticker channels — still minted <media:kind> placeholder bodies for media-only inbound messages and used body-string equality for behavior decisions (Feishu audio preflight, MSTeams unavailable-media selection).

Why This Change Was Made

  • Primary bodies are caption-only; media-only messages carry one ordered structured fact per native resource, with type-only facts for failures/rejections/blocked downloads so counts, kinds, and positions stay aligned (batch-1 contract). Media-only events remain admitted; command routing traced per channel (empty input is non-command by the shared detectors).
  • Discord: stickers travel as native kind: "sticker" (image-compatible MIME makes them non-derivable) — the existing inbound/history kind unions and the formatter vocabulary grow by that one member, no SDK export change. PR1's audio precedence (definitive MIME > voice fields > constrained filename) is preserved and re-tested. Forwarded snapshots, room-event history, and thread starters render facts via formatMediaPlaceholderText; the dead buildDiscordMediaPayload and per-attachment placeholder strings are deleted (guardrails inventory updated for exactly that export). The 1,365-line message-utils test file was split; its stale max-lines baseline entry removed (no cap raised).
  • Feishu: parseMessageContent returns captions/speech-to-text only; the (file_name) annotation is deliberately dropped (only non-derivable annotation, not a stable cross-channel fact). Audio preflight gates on native message type + materialized audio facts instead of content === "<media:audio>".
  • MSTeams: advertised resources (attachments, inline images, HTML/CID-referenced) become one fact each; downloads keep one output position when unavailable/blocked/oversized/failed and replace their slot on success; Graph/Bot Framework subsets reconcile by identity (sourceId) or a sole compatible id-less slot; unavailable notices derive from pathless facts, not body comparison. The dead placeholder payload builder is hard-deleted.

User Impact

Media-only messages from these three channels no longer inject <media:image> (N images)-style text into transcripts, previews, or prompts; captions are exactly what the user typed. Failed/partial downloads keep their existing notices and now preserve attachment kind/count/order to the model. Accepted rendering drift on text carriers: a single item renders as a bare tag (no "(1 image)" annotation).

Evidence

  • Focused suites all green via node scripts/run-vitest.mjs (one file per invocation): Discord 12 files (message-media 33+4, message-text 18, preflight 50, monitor 42, threading 11, audio 5, context/history 16, routing 10, inbound-job 5, message-utils 9), Feishu bot 94 + helpers 14, MSTeams 6 files (123 tests), shared/core formatter 8, inbound-media 7, history 4.
  • Remote full changed-surface proof: check:changed exit 0 on Blacksmith Testbox (run 29716797532) — typechecks, lint, formatting, max-lines ratchet, SDK API baseline, plugin boundaries, dependency guards, import cycles. Two earlier remote rounds caught and fixed a stale max-lines entry and a Feishu test-local type gap before this PR was opened.
  • Static gates: oxfmt clean, oxlint clean (53 files), git diff --check clean, zero <media:*> literals left in the three channels' production code.
  • Autoreview (Codex gpt-5.6-sol): implementation-side review cycles drove the MSTeams identity/CID/opaque-MIME regression tests; final independent pass clean, "patch is correct (0.84)".
  • Documented deviation: channel production TypeScript is net +138 (Discord +2, Feishu −37, MSTeams +173) against a program preference for net-negative — the growth is MSTeams resource-order preservation and identity-safe fallback reconciliation, which the alignment contract genuinely costs on a three-source channel; overall tracked diff is net −908.

Media-placeholder program batch 2: Discord, Feishu, and MSTeams stop
minting <media:kind> placeholder bodies. Primary bodies carry captions
only; native resources produce ordered structured facts with type-only
facts for failures/rejections (batch-1 alignment contract). Discord
stickers travel as native kind "sticker" (not MIME-derivable); text
carriers (forwarded snapshots, room history, thread starters, pending
text) render via formatMediaPlaceholderText. Feishu audio preflight and
MSTeams unavailable selection move from body-string equality to
structured facts; dead placeholder payload builders deleted.
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: msteams Channel integration: msteams channel: feishu Channel integration: feishu labels Jul 20, 2026
@steipete
steipete marked this pull request as ready for review July 20, 2026 05:05
@openclaw-barnacle openclaw-barnacle Bot added size: XL maintainer Maintainer-authored PR labels Jul 20, 2026
@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. 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 20, 2026
@clawsweeper

clawsweeper Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 20, 2026, 1:34 AM ET / 05:34 UTC.

Summary
The branch removes synthetic media-placeholder bodies from Discord, Feishu, and Microsoft Teams inbound messages and carries attachment metadata through ordered structured media facts instead.

PR surface: Source +139, Tests +438, Other -1. Total +576 across 55 files.

Reproducibility: not applicable. This PR changes an established inbound-media representation rather than reporting a standalone current-main failure.

Review metrics: none identified.

Stored data model
Persistent data-model change detected: serialized state: extensions/feishu/src/bot.helpers.test.ts, serialized state: src/auto-reply/reply/history.ts. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

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

Rank-up moves:

  • [P1] Post redacted after-fix ingress evidence for a media-only event in Discord, Feishu, and Microsoft Teams.
  • Include the observed caption text, structured media kind/count result, and a Teams unavailable-media or fallback example if available.
  • [P1] After updating the PR body, let the automatic review refresh or ask a maintainer to comment @clawsweeper re-review if needed.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR reports extensive focused tests, CI, and remote checks, but no inspectable after-fix live channel transcript, recording, terminal output, or redacted runtime log demonstrates the changed ingress behavior; please redact private endpoints, identifiers, and tokens in any evidence. 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] Merging changes existing media-only transcript, preview, and history rendering across three channels; upgrades may expose intentional placeholder-text differences even where attachment delivery remains correct.
  • [P2] The Teams fallback reconciliation and unavailable-media notices are delivery-sensitive: an identity mismatch could preserve the wrong unavailable slot or produce an incorrect attachment count despite green unit coverage.
  • [P1] The provided evidence does not show a real post-fix ingress event from any affected channel, so the reviewed behavior has not yet been demonstrated outside mocks and automated checks.

Maintainer options:

  1. Prove each real ingress path (recommended)
    Before merge, capture redacted after-fix evidence for media-only Discord, Feishu, and Microsoft Teams events, including the Teams unavailable-media path where feasible.
  2. Accept the rendering transition
    Maintainers may merge with the stated transcript rendering drift if they explicitly accept the compatibility change without live proof.
  3. Pause batch two
    Pause or close the branch if cross-channel live proof cannot be produced and the rendering transition is not worth the remaining delivery risk.

Next step before merge

  • [P1] This needs protected-label maintainer approval after contributor-provided real behavior proof, not a separate automated repair PR.

Maintainer decision needed

  • Question: Should this cross-channel transcript and media-fact migration land after the contributor supplies redacted real ingress proof for the affected channel paths?
  • Rationale: The protected maintainer label and intentional compatibility-visible rendering change require an explicit human merge decision after proof confirms the new behavior on real channel ingress.
  • Likely owner: steipete — They authored the merged predecessor contract and this follow-on implementation.
  • Options:
    • Require live ingress proof (recommended): Hold merge until redacted Discord, Feishu, and Microsoft Teams evidence shows media-only messages keep an empty caption while preserving structured media facts and the intended unavailable-media result.
    • Accept automated-only evidence: Merge based on the focused suites and changed-surface checks while accepting that real channel delivery and transcript behavior has not been demonstrated.
    • Pause the migration: Defer this batch if maintainers do not want the remaining placeholder-rendering compatibility change in the current release window.

Security
Cleared: The supplied diff changes media representation and existing fetch-result handling but adds no dependency, workflow, secret, permission, package-resolution, or code-execution surface.

Review details

Best possible solution:

Keep caption text and structured media facts as the single inbound contract, retain formatter output only for text-only history surfaces, and land only after redacted real ingress proof covers media-only behavior in Discord, Feishu, and Microsoft Teams.

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

Not applicable: this PR changes an established inbound-media representation rather than reporting a standalone current-main failure.

Is this the best way to solve the issue?

Yes, conditionally: extending the established structured-media-fact contract is the narrowest maintainable direction, but it needs real ingress proof before the compatibility-visible transition is accepted.

AGENTS.md: found and applied where relevant.

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

Label changes

Label changes:

  • add rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • remove rating: 🦪 silver shellfish: Current PR rating is rating: 🧂 unranked krab, so this older rating label is no longer current.

Label justifications:

  • P2: This is a bounded but user-visible inbound-media behavior change across three bundled channels.
  • merge-risk: 🚨 compatibility: Media-only captions and text-only history rendering intentionally change for existing Discord, Feishu, and Microsoft Teams users.
  • merge-risk: 🚨 message-delivery: The patch changes how native, failed, and fallback-downloaded attachments are represented and reconciled before dispatch.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR reports extensive focused tests, CI, and remote checks, but no inspectable after-fix live channel transcript, recording, terminal output, or redacted runtime log demonstrates the changed ingress behavior; please redact private endpoints, identifiers, and tokens in any evidence. 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.
Evidence reviewed

PR surface:

Source +139, Tests +438, Other -1. Total +576 across 55 files.

View PR surface stats
Area Files Added Removed Net
Source 31 555 416 +139
Tests 23 2003 1565 +438
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 0 1 -1
Total 55 2558 1982 +576

What I checked:

  • Established migration direction: The linked merged media-audio and batch-one migrations already establish structured media facts as the replacement for placeholder-body behavior; this branch extends that contract to Discord, Feishu, and Microsoft Teams. (src/channels/inbound-event/media.ts:24, 83303f1ba874)
  • Discord history boundary: The branch keeps placeholder rendering only for text-only history carriers while primary inbound text remains caption-only, including native sticker classification. (extensions/discord/src/monitor/message-text.ts:53, b987bbc8ea69)
  • Feishu routing boundary: The Feishu change replaces the audio preflight sentinel-body check with native message type and structured media facts, so media-only messages can remain caption-empty without suppressing audio handling. (extensions/feishu/src/bot.ts:132, b987bbc8ea69)
  • Microsoft Teams alignment boundary: The Teams path derives unavailable-media notices from structured native and materialized media facts and reconciles fallback downloads by resource identity, replacing body-string comparisons. (extensions/msteams/src/monitor-handler/inbound-media.ts:34, b987bbc8ea69)
  • Proof status: The PR body reports focused tests, a remote changed-surface check, and static scans, but the supplied discussion contains no inspectable after-fix live transcript, recording, terminal output, or redacted runtime log from Discord, Feishu, or Microsoft Teams. (b987bbc8ea69)

Likely related people:

  • steipete: Authored the two merged predecessor migrations that establish the structured-media contract this branch extends, in addition to the current implementation. (role: feature owner and recent area contributor; confidence: high; commits: e20d4cd450a4, 83303f1ba874; files: src/auto-reply/reply/inbound-media.ts, src/channels/inbound-event/media.ts, extensions/discord/src/monitor/message-text.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 (1 earlier review cycle)
  • reviewed 2026-07-20T05:09:36.879Z sha 941e019 :: needs real behavior proof before merge. :: none

@steipete steipete self-assigned this Jul 20, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels Jul 20, 2026
@steipete

Copy link
Copy Markdown
Contributor Author

Maintainer decision on the current ClawSweeper rank-up moves: accept automated-only evidence for this batch and proceed with landing.

This is the second producers-first migration using the already-landed structured media-fact contract. I explicitly accept the documented compatibility-visible rendering transition: primary inbound bodies are captions only, while text-only history carriers render structured facts. The changed Discord, Feishu, and Microsoft Teams paths have focused success/failure/alignment coverage; independent autoreview is clean; exact-head CI is green; and delegated Blacksmith check:changed is green in https://github.com/openclaw/openclaw/actions/runs/29716797532.

I am therefore not requiring separate live credentials and redacted ingress captures from all three services for this landing. The reported serialized-state items do not require a migration: one is a Feishu test file, and the history media kind change is additive structured metadata rather than a persisted schema-version change.

@steipete
steipete merged commit 6e19c36 into main Jul 20, 2026
128 of 130 checks passed
@steipete
steipete deleted the claude/media-placeholder-batch2 branch July 20, 2026 05:48
@steipete

Copy link
Copy Markdown
Contributor Author

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 20, 2026
…claw#111665)

* feat(channels): batch 2 producers drop media placeholder bodies

Media-placeholder program batch 2: Discord, Feishu, and MSTeams stop
minting <media:kind> placeholder bodies. Primary bodies carry captions
only; native resources produce ordered structured facts with type-only
facts for failures/rejections (batch-1 alignment contract). Discord
stickers travel as native kind "sticker" (not MIME-derivable); text
carriers (forwarded snapshots, room history, thread starters, pending
text) render via formatMediaPlaceholderText. Feishu audio preflight and
MSTeams unavailable selection move from body-string equality to
structured facts; dead placeholder payload builders deleted.

* test(discord): make allowlist policy explicit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord channel: feishu Channel integration: feishu channel: msteams Channel integration: msteams maintainer Maintainer-authored PR 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: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. 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.

1 participant