How OpenMAIC Handles Media Generation: Images, Video, and Provider Architecture

OpenMAIC generates images and video through a provider-agnostic registry system that dispatches requests to unified generation functions, with specialized handling for classroom automation and built-in security validation.

OpenMAIC (maintained by THU-MAIC) implements a layered, extensible architecture for visual media generation that abstracts multiple third-party providers behind a consistent TypeScript interface. Whether generating AI images for slide decks or creating video content for interactive lessons, the system centralizes configuration, normalizes capabilities across providers, and enforces strict security controls. This article explores the complete flow from HTTP API endpoints down to server-side classroom pipelines.

Provider Registry Architecture

OpenMAIC maintains static provider registries that declare supported capabilities and constraints for each image and video service.

Image Providers

The IMAGE_PROVIDERS map in lib/media/image-providers.ts (lines 33-61) defines each supported image provider—including Seedream, OpenAI, and MiniMax—along with required API keys, default base URLs, available models, and constraints such as supported aspect ratios and resolutions. This registry enables the system to validate requests before dispatching to concrete adapters.

Video Providers

Similarly, VIDEO_PROVIDERS in lib/media/video-providers.ts (lines 22-53) catalogs video generation services with additional metadata for maximum duration limits and resolution tiers. The registry pattern ensures that new providers can be added without modifying downstream consumption code.

Unified Generation Interface

Rather than implementing provider-specific logic in API routes, OpenMAIC exposes two primary dispatcher functions that handle adapter selection internally.

Image Generation Dispatch

The generateImage(config, options) function (implemented in lib/media/image-providers.ts, lines 91-115) receives a configuration object containing the provider ID, API key, and model selection. It uses a switch statement to route the request to the appropriate adapter (e.g., Seedream, OpenAI, or MiniMax) and returns a standardized result object containing either a remote URL or base64-encoded binary data.

import { generateImage, IMAGE_PROVIDERS } from '@/lib/media/image-providers';

const cfg = {
  providerId: 'openai-image' as const,
  apiKey: process.env.OPENAI_API_KEY!,
  baseUrl: undefined,
  model: 'gpt-image-2',
};

const opts = { 
  prompt: 'A futuristic cityscape at sunset', 
  aspectRatio: '16:9' 
};

const result = await generateImage(cfg, opts);
// result.url → remote image URL OR result.base64 → inline PNG data

Video Generation and Option Normalization

Video generation follows a parallel pattern through generateVideo(config, options) in lib/media/video-providers.ts (lines 91-106), but includes an additional validation layer. Before dispatching to the provider adapter, normalizeVideoOptions() (lines 54-88) validates and coerces the requested duration, aspect ratio, and resolution to the first supported value if the client-supplied parameters are missing or incompatible with the selected provider's capabilities.

HTTP API Endpoints

OpenMAIC exposes media generation through RESTful endpoints that handle provider resolution, authentication, and parameter preprocessing.

Image Generation Endpoint

The image endpoint at POST /api/generate/image (implemented in app/api/generate/image/route.ts) performs the following sequence:

  1. Resolves the provider ID from request headers, falling back to server-configured defaults (lines 19-20)
  2. Validates the API key against server-side configuration (lines 47-61)
  3. Optionally derives pixel dimensions from aspect ratio strings (lines 78-84)
  4. Invokes generateImage() with the resolved configuration

Video Generation Endpoint

The video endpoint at POST /api/generate/video (app/api/generate/video/route.ts) follows a similar flow but incorporates option normalization:

  1. Resolves provider, API key, and model from headers or server config (lines 47-61)
  2. Calls normalizeVideoOptions() to validate duration, aspect ratio, and resolution constraints (lines 96-100)
  3. Executes generateVideo() with normalized parameters
curl -X POST https://your-maic-host/api/generate/video \
  -H "Content-Type: application/json" \
  -H "x-video-provider: minimax-video" \
  -d '{
        "prompt": "A dragon flying over mountains",
        "duration": 6,
        "aspectRatio": "16:9",
        "resolution": "720p"
      }'

Server-Side Classroom Media Pipeline

For automated content generation within educational contexts, OpenMAIC implements generateMediaForClassroom() in lib/server/classroom-media-generation.ts (lines 84-138). This function iterates over media generation requests embedded in scene outlines and manages the complete lifecycle:

  • Provider Selection: Picks the first enabled image or video provider, respecting server-wide "disabled" flags (lines 84-102)
  • Configuration Resolution: Retrieves API keys and models from server configuration via lib/server/provider-config.ts
  • Execution: Calls generateImage() or generateVideo() with appropriate parameters
  • Asset Management: Downloads the resulting binary (base64 or URL) and persists it to the classroom's media/ directory (lines 112-138)
  • URL Mapping: Returns a map of element IDs to public serving URLs, enabling client-side replacement of placeholder references

This pipeline powers automated slide deck generation and interactive lesson media without requiring manual file uploads.

Security and Governance Layer

Throughout the media generation stack, OpenMAIC enforces several protective mechanisms according to the source code in THU-MAIC/OpenMAIC:

  • Server Precedence: Force-disabled providers in server configuration cannot be overridden by client headers, ensuring administrative control over available services
  • API Key Validation: Managed providers (server-controlled) ignore client-supplied keys, while unmanaged providers require valid key validation before dispatch
  • SSRF Protection: User-supplied base URLs undergo validation via validateUrlForSSRF() implemented in lib/server/ssrf-guard.ts before any outbound requests in production environments
  • Content Safety: Responses containing "SensitiveContent" errors are caught and returned as specific API error codes, preventing the propagation of policy-violating media

Summary

  • OpenMAIC uses static provider registries (IMAGE_PROVIDERS and VIDEO_PROVIDERS) to declare capabilities and constraints for each supported generation service
  • Unified dispatcher functions generateImage() and generateVideo() abstract provider-specific implementations behind consistent TypeScript interfaces
  • Video generation includes normalizeVideoOptions() to enforce duration, resolution, and aspect ratio constraints before dispatch
  • HTTP endpoints at /api/generate/image and /api/generate/video handle authentication, provider resolution, and parameter preprocessing
  • The generateMediaForClassroom() pipeline automates media creation for educational content, managing download, storage, and URL generation
  • Security layers enforce server-side provider control, API key validation, SSRF protection, and content safety filtering throughout the stack

Frequently Asked Questions

How does OpenMAIC handle unsupported video resolutions or aspect ratios?

OpenMAIC automatically normalizes video parameters through the normalizeVideoOptions() function in lib/media/video-providers.ts. If a client requests a duration, aspect ratio, or resolution that the selected provider does not support, the function coerces the value to the first supported option in the provider's capability list before dispatching the generation request.

Can I use my own API key for media generation in OpenMAIC?

It depends on the provider configuration. For unmanaged providers, OpenMAIC accepts client-supplied API keys via request headers, validated in the route handlers. However, managed providers configured at the server level ignore client-supplied keys and use the server-configured credentials instead, ensuring centralized billing and access control.

Where does OpenMAIC store generated media files for classroom content?

When processing classroom scenes, generateMediaForClassroom() in lib/server/classroom-media-generation.ts downloads the generated binary data (whether returned as base64 or remote URL) and writes files to the classroom's designated media/ directory. The function then returns public serving URLs mapped to element IDs, allowing the frontend to render the assets without direct access to the generation APIs.

What prevents SSRF attacks when specifying custom base URLs for providers?

OpenMAIC implements SSRF protection through validateUrlForSSRF() in lib/server/ssrf-guard.ts. This function validates user-supplied base URLs before they are used for outbound requests, particularly in production environments, preventing the system from making requests to internal network addresses or restricted IP ranges.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →