Per-path cache for resolved local image data URIs. Keyed by absolute
path; stores (len, mtime) for freshness checks ((0, 0) sentinel
= immutable upload). LRU evicts by both entry count and total bytes.
Count image markers that originate from genuine user messages (i.e.
inbound attachments), excluding tool-result carriers (role == "tool" and
[Tool results] user messages).
Like prepare_messages_for_provider but reuses a LocalImageCache
across calls so each unique local image file is read from disk at most
once per session (or once per modification for mutable files).
Replace media markers ([IMAGE:...], [PHOTO:...], [DOCUMENT:...],
[FILE:...], [VIDEO:...], [VOICE:...], [AUDIO:...]) with
[media attachment]. Match is case-insensitive to align with the channel
attachment parsers, which all uppercase the kind before comparing
(crates/zeroclaw-channels/src/util.rs::ATTACHMENT_KINDS,
telegram.rs, discord.rs, qq.rs, whatsapp_web.rs).