The adapter stripped all HTML tags via _strip_html() before the
gateway could see image references, and always sent MessageType.TEXT.
Uploaded files (PNG, PDF, audio, etc.) arrived as <img> or
markdown-style references to /user_uploads/... paths that were
never downloaded locally — so vision_analyze had no file to read.
Changes:
- Add _extract_inline_media(): finds /user_uploads/... references in
message text, downloads them via httpx, caches locally
- Add _extract_event_attachments(): handles message.attachments
from Zulip UI file uploads (structured event data)
- Add _cache_attachment(): routes image/audio/document bytes to
Hermes media storage via cache_image_from_bytes / cache_audio_from_bytes
/ cache_document_from_bytes
- Update _route_message() to extract media and set MessageType.PHOTO,
VOICE, or DOCUMENT when attachments are present (was always TEXT)
- Pass media_urls and media_types to MessageEvent so the gateway
delivery pipeline can attach local file paths to the conversation
Ported from hermes-zulip-plugin (deprecated) and adapted for the
httpx-based platform adapter.