Skip to content

feat(channels): batch 3 producers drop media placeholder bodies#111800

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

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

Conversation

@steipete

Copy link
Copy Markdown
Contributor

What Problem This Solves

Batch 3 of the media-placeholder elimination program (PR1 #111315; batches #111447, #111665). iMessage, Signal, and WhatsApp still minted <media:kind> bodies — and, distinctively, cached rendered placeholder text in echo/dedupe, quote-preview, and pending-history records, losing the media fact once stored.

Why This Change Was Made

  • Primary bodies are caption-only; media-only messages carry one aligned structured fact per native attachment (type-only for missing/rejected/oversized/out-of-root — the established alignment contract). Media-only events stay admitted; command routing traced per channel.
  • Record schemas gain structured facts before placeholders go: iMessage in-memory + persisted echo caches add {kind, contentType} (additive, no store version bump; kind-level fallback tolerates MIME transcoding, explicit message-ID conflicts prevent false drops); Signal durable reply-author records add media[]; WhatsApp reply contexts and quote-cache metadata add one fact. Text renders only where text is the carrier, via formatMediaPlaceholderText (Signal deliberately keeps its established multi-attachment [N … attached] form).
  • Signal outbound improvement, dependency-proven: direct inspection of sibling signal-cli source (c26e0632c51, SendCommand.java:158-174/242-263 + JSON-RPC man page) shows attachment-only sends with message: "" are valid — the outbound placeholder body is dropped entirely, so remote Signal recipients now see just the media instead of literal <media:image> text.
  • WhatsApp audio preflight gates on structured facts + empty caption instead of audio/* plus exact <media:audio> body (Feishu batch-2 pattern). WhatsApp gif maps to video (GIF playback is a presentation mode; nothing consumes gif-ness — no kind-union growth). The qa-lab mock-openai <media:sticker> recognizer moves to structured sticker facts per the audit's assignment.

User Impact

Media-only messages from these three channels no longer show placeholder text anywhere; captions are exactly what users typed. Signal media-only sends from OpenClaw no longer deliver literal <media:image> text to recipients. Echo/dedupe and quote previews keep working through the structured records.

Evidence

  • 901 focused tests green via node scripts/run-vitest.mjs (one file per invocation) across iMessage (send, behavior, media-policy, inbound-processing, self-chat-dedupe, deliver), Signal (event-handler, media-text, reply-authors), WhatsApp (extract, monitor-inbox suites, on-message/process-message preflight), qa-lab, and core consumers.
  • Remote full changed-surface check:changed exit 0 on Blacksmith Testbox (run 29735312394): typechecks, lint, formatting, max-lines, SDK API baseline, plugin boundaries, dependency guards, import cycles.
  • oxfmt/oxlint/git diff --check clean; zero <media:*> production literals remain in the three channels.
  • Autoreview: implementation-side cycles clean; independent final pass raised one P2 asking to keep a compatibility alias for the deleted internal extractMediaPlaceholder re-export — consciously rejected: zero references remain in-tree, it was never exposed via openclaw/plugin-sdk/* (the only supported external import surface), bundled-plugin runtime-api.ts barrels are internal core↔bundled seams, and batch 2 (feat(channels): batch 2 producers drop media placeholder bodies #111665) deleted buildDiscordMediaPayload from the same barrel class. Two implementation-side compat suggestions (12-hour transient echo-cache recognizer; same export) were likewise rejected under the program's hard-delete policy — transient caches are rebuildable state.
  • Documented deviation: tracked diff net +382 (+432 with new Signal files) — the cost of adding structured facts to echo/quote/pending-history record schemas, which is this batch's entire point; placeholder builders and string comparisons were deleted in exchange.

Media-placeholder program batch 3: iMessage, Signal, and WhatsApp stop
minting <media:kind> placeholder bodies. Primary bodies carry captions
only with one aligned structured fact per native attachment (type-only
for missing/rejected/oversized). Echo, quote, and pending-history
records gain structured media facts so dedupe and previews work without
rendered text. Signal media-only outbound sends drop the placeholder
body entirely (signal-cli accepts attachment-only sends; recipients now
see just the media). WhatsApp audio preflight de-stringed; qa-lab
sticker recognizer moved to structured facts; WhatsApp gif maps to
video (presentation mode, no behavioral consumer).
@openclaw-barnacle openclaw-barnacle Bot added channel: imessage Channel integration: imessage channel: signal Channel integration: signal channel: whatsapp-web Channel integration: whatsapp-web extensions: qa-lab size: XL labels Jul 20, 2026
@steipete
steipete marked this pull request as ready for review July 20, 2026 11:00
@openclaw-barnacle openclaw-barnacle Bot added the maintainer Maintainer-authored PR label Jul 20, 2026
@steipete steipete self-assigned this Jul 20, 2026
@steipete
steipete merged commit 0ac7b24 into main Jul 20, 2026
117 checks passed
@steipete
steipete deleted the claude/media-placeholder-batch3 branch July 20, 2026 11:22
@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 21, 2026
…claw#111800)

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

Media-placeholder program batch 3: iMessage, Signal, and WhatsApp stop
minting <media:kind> placeholder bodies. Primary bodies carry captions
only with one aligned structured fact per native attachment (type-only
for missing/rejected/oversized). Echo, quote, and pending-history
records gain structured media facts so dedupe and previews work without
rendered text. Signal media-only outbound sends drop the placeholder
body entirely (signal-cli accepts attachment-only sends; recipients now
see just the media). WhatsApp audio preflight de-stringed; qa-lab
sticker recognizer moved to structured facts; WhatsApp gif maps to
video (presentation mode, no behavioral consumer).

* test(whatsapp): keep media classifier private
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: imessage Channel integration: imessage channel: signal Channel integration: signal channel: whatsapp-web Channel integration: whatsapp-web extensions: qa-lab maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant