Skip to content

Add multi-part / image content support (text-only today; proxy↔WorkflowRunner parity) #116

Description

@antoinezambelli

Summary

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.pyopenai_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

  1. Let Message.content carry structured / multi-part content (not just str).
  2. Teach the per-backend serializers to emit each backend's image wire-shape (OpenAI image_url, Ollama images[] base64, etc.).
  3. 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.

Notes / out of scope here

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions