Skip to main content
Image-gen provider plugins register a backend that services every image_generate tool call — DALL·E, gpt-image, Grok, Flux, Imagen, Stable Diffusion, fal, Replicate, a local ComfyUI rig, anything. Built-in providers (OpenAI, OpenAI-Codex, xAI, FAL, Krea, DeepInfra, OpenRouter, Meta Model API) all ship as plugins. You can add a new one, or override a bundled one, by dropping a directory into plugins/image_gen/<name>/.
Image-gen is one of several backend plugins Mibyan supports. The others (with more specialized ABCs) are Memory Provider Plugins, Context Engine Plugins, and Model Provider Plugins. General tool/hook/CLI plugins live in Build a Mibyan Plugin.

How discovery works

Mibyan scans for image-gen backends in three places:
  1. Bundled — <repo>/plugins/image_gen/<name>/ (auto-loaded with kind: backend, always available)
  2. User — ~/.mibyan/plugins/image_gen/<name>/ (opt-in via plugins.enabled)
  3. Pip — packages declaring a mibyan_agent.plugins entry point
Each plugin’s register(ctx) function calls ctx.register_image_gen_provider(...) — that puts it into the registry in agent/image_gen_registry.py. The active provider is picked by image_gen.provider in config.yaml; mibyan tools walks users through selection. The image_generate tool wrapper asks the registry for the active provider and dispatches there. If no provider is registered, the tool surfaces a helpful error pointing at mibyan tools.

Directory structure

A bundled plugin is complete at this point. User plugins at ~/.mibyan/plugins/image_gen/<name>/ need to be added to plugins.enabled in config.yaml (or run mibyan plugins enable <name>).

The ImageGenProvider ABC

Subclass agent.image_gen_provider.ImageGenProvider. The only required members are the name property and the generate() method — everything else has sane defaults:

plugin.yaml

kind: backend is what routes the plugin to the image-gen registration path. requires_env is prompted during mibyan plugins install.

ABC reference

Full contract in agent/image_gen_provider.py. The methods you’ll typically override:

Response format

generate() must return a dict built via success_response() or error_response(). Both live in agent/image_gen_provider.py. Success:
Error:
The tool wrapper JSON-serializes the dict and hands it to the LLM. Errors are surfaced as the tool result; the LLM decides how to explain them to the user.

Handling base64 vs URL output

Some backends return image URLs (fal, Replicate); others return base64 payloads (OpenAI gpt-image-2). For the base64 case, use save_b64_image() — it writes to $mibyan_HOME/cache/images/<prefix>_<timestamp>_<uuid>.<ext> and returns the absolute Path. Pass that path (as str) as image= in success_response(). Gateway delivery (Telegram photo bubble, Discord attachment) recognizes both URLs and absolute paths.

User overrides

Drop a user plugin at ~/.mibyan/plugins/image_gen/<name>/ with the same name property as a bundled one and enable it via mibyan plugins enable <name> — the registry is last-writer-wins, so your version replaces the built-in. Useful for pointing an openai plugin at a private proxy, or swapping in a custom model catalog.

Testing

Or interactively: mibyan tools → “Image Generation” → select my-backend → enter API key if prompted.

Reference implementations

  • plugins/image_gen/openai/__init__.py — gpt-image-2 at low/medium/high tiers as three virtual model IDs sharing one API model with different quality params. Good example of tiered models under a single backend + config.yaml precedence chain.
  • plugins/image_gen/xai/__init__.py — Grok Imagine via xAI. Different shape (URL output, simpler catalog).
  • plugins/image_gen/openai-codex/__init__.py — same catalog as openai, but authenticated with the ChatGPT/Codex OAuth token and posted with plain httpx to the Codex backend’s native images/generations / images/edits endpoints. Good example of a provider that fetches remote source images client-side and inlines them as data URLs, and that reports backend-returned metadata separately from the request.

Distribute via pip

my_backend_imggen_package must expose a top-level register function. See Distribute via pip in the general plugin guide for the full setup.