Channel plugins now have a structured way to propagate attachments —
Plexum's host turns each MediaItem into a canonical.ImageBlock content
on the user message. This replaces the F-6 workaround that crammed
local file paths into a markdown footer at the end of the message
text.
internal/inbound/inbound.go:
- Notifier signature gains `media []MediaItem`; MediaItem mirrors
the host's channel.MediaRef (Path/MediaType/Name)
- dispatch downloads attachments (unchanged) then forwards results
as MediaItem to Notify — no more footer appending
- dispatch now also receives guildEndpoint so it can resolve Fabric's
RELATIVE attachment URLs (`/api/files/<id>`) against the guild base.
Previously the downloader received the relative path verbatim and
failed every fetch silently.
cmd/plexum-fabric-channel-plugin/main.go:
- notifier closure pushes media[] in the EmitNotification payload
Live verified: alice uploads blue 32x32 PNG → Fabric guild → plugin
downloads to /tmp/plexum-fabric/<msg>/blue32.png → emits inbound with
media → host routes to kimi agent → Kimi: "Blue".
(MiniMax M2.7 is text-only per openclaw model definitions, so the
same flow against MiniMax returns "I don't see an image" — that's a
model capability limit, not a plugin issue.)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>