You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
forge currently supports text-only message content. When a client sends OpenAI multi-part content (content as an array of blocks, e.g. image_url + text), the non-text blocks are silently dropped. This was an intentional text-only starting point; this issue tracks adding real multi-modal (image) support as a deliberate, larger refactor.
Current behavior
Message.content is typed as a plain str — forge's internal message model structurally cannot hold multi-part content.
The converted path (proxy/convert.py → openai_to_messages) flattens multi-part content to text, keeping only type == "text" (and bare-string) blocks; image_url / other blocks are dropped.
On the proxy, raw native-passthrough does preserve multi-part content verbatim for OpenAI-shaped backends (vLLM, llama.cpp) on the clean first attempt — but any retry / compaction falls back to the converted path and drops images. So image preservation today is path-dependent and accidental, not a supported feature.
The Ollama native endpoint takes images via a separate messages[].images: [base64] field, not OpenAI image_url, so even verbatim passthrough would not carry images there. (The recently shipped Ollama content-normalization fix is explicitly text-only and does not add image support — see Ollama client doesn't handle messages.content as an array #115.)
What real support would require
Let Message.content carry structured / multi-part content (not just str).
Teach the per-backend serializers to emit each backend's image wire-shape (OpenAI image_url, Ollama images[] base64, etc.).
Give the WorkflowRunner an input surface that accepts multi-part content (today it takes a plain string user message), so the proxy and WorkflowRunner reach parity on multi-modal handling.
Latent hardening surfaced while scoping: LlamafileClient._merge_consecutive does content + content and would TypeError on multi-part (list) same-role adjacency — worth a guard/test as part of (or alongside) this work.
Summary
forge currently supports text-only message content. When a client sends OpenAI multi-part content (
contentas an array of blocks, e.g.image_url+text), the non-text blocks are silently dropped. This was an intentional text-only starting point; this issue tracks adding real multi-modal (image) support as a deliberate, larger refactor.Current behavior
Message.contentis typed as a plainstr— forge's internal message model structurally cannot hold multi-part content.proxy/convert.py→openai_to_messages) flattens multi-partcontentto text, keeping onlytype == "text"(and bare-string) blocks;image_url/ other blocks are dropped.messages[].images: [base64]field, not OpenAIimage_url, so even verbatim passthrough would not carry images there. (The recently shipped Ollama content-normalization fix is explicitly text-only and does not add image support — see Ollama client doesn't handle messages.content as an array #115.)What real support would require
Message.contentcarry structured / multi-part content (not juststr).image_url, Ollamaimages[]base64, etc.).Notes / out of scope here
LlamafileClient._merge_consecutivedoescontent + contentand wouldTypeErroron multi-part (list) same-role adjacency — worth a guard/test as part of (or alongside) this work.