platforms.media_common module

Shared media-to-content-part conversion for all platforms.

Converts raw bytes + MIME type into the multimodal content-part format expected by the OpenRouter chat-completions API. Platform-specific download logic lives in each adapter; this module only handles the format conversion.

Office / ODF / EPUB documents whose MIME types are not supported by the downstream LLM are automatically converted to PDF via LibreOffice headless before being embedded as content parts.

GIF and animated WebP images are automatically re-encoded as MP4 (H.264 baseline) so the Gemini API receives a well-supported video format instead of GIF/animated-WebP.

async platforms.media_common.maybe_reencode_gif(data, mimetype, filename)[source]

Re-encode GIF or animated WebP as MP4 for the Gemini API.

For animated WebP: Pillow converts WebP->GIF (no ffmpeg libwebp needed), then the GIF is converted to MP4 via ffmpeg.

For GIF: directly converted to MP4 via ffmpeg.

Returns (data, mimetype, filename) – either the converted MP4 or the original inputs unchanged if conversion fails, the input is not a GIF, or the WebP is not animated (static WebP passes through as a normal image).

Return type:

tuple[bytes, str, str]

Parameters:
async platforms.media_common.media_to_content_parts(data, mimetype, filename, body_text=None)[source]

Build an OpenRouter multimodal content-parts list from raw media.

Office / ODF documents are transparently converted to PDF via LibreOffice so the LLM never sees an unsupported MIME type.

Parameters:
  • data (bytes) – The raw file bytes.

  • mimetype (str) – MIME type of the file (e.g. "image/png").

  • filename (str) – Human-readable filename.

  • body_text (str | None) – Optional caption / message body text to include alongside the media. When present it is prepended as a text content part.

Returns:

A list of content-part dicts suitable for the content field of an OpenRouter user message.

Return type:

list[dict[str, Any]]