Images
Image models, sizes, reference editing, prompt enhancement, the task API and adding a model.
Models
The catalog in packages/ai/src/catalog.ts lists image models in display order. DEFAULT_IMAGE_MODEL is flux-2-klein-4b.
| Model | Runs on | Edits references | Ratios | Credits per image |
|---|---|---|---|---|
| FLUX.2 klein 4B | Workers AI | Up to 4 | All five | 2 |
| FLUX.1 schnell | Workers AI | No | 1:1 only | 2 |
| Premium image model | Provider adapter | Up to 3 | All five | 7 |
The five ratios render near one megapixel: 1:1 at 1024×1024, 4:3 at 1024×768, 3:4 at 768×1024, 16:9 at 1280×720 and 9:16 at 720×1280. One request produces 1 to 4 images and is priced per image.
Studio flow
/app/imagesends the prompt, model, ratio, count and optional reference asset ids.- The server validates the model's limits, prices the request and reserves credits together with the task and its outbox message.
- The queue consumer leases the task and calls the provider. Workers AI runs through the
AIbinding. - Each output is verified as an image and written to R2 as
{userId}/ai/{assetId}.webp, then listed in the library. - Success keeps the reservation. A retryable failure is attempted again, up to
ai.maxAttempts; a final failure releases the credits once.
The studio polls GET /api/ai/tasks/{id} until the task finishes. POST /api/ai/tasks/{id}/cancel cancels a queued task and returns its credits.
Task API
{
"requestId": "6f0c1d4e-0d1b-4b64-a8d6-0f7d0c9a2b11",
"model": "flux-2-klein-4b",
"prompt": "A cozy reading nook by a rainy window, cinematic photograph",
"ratio": "4:3",
"count": 4,
"references": []
}requestIdis a UUID you create per action. Repeating it returns the same task without a second charge.promptis 1 to 2,048 characters.referencesholds up to 4 library asset ids, limited further by the model.- The response is
201with the task. Refusals are402(too few credits),429(too many unfinished tasks) and503(daily budget reached).
Reference images and the library
POST /api/ai/uploads accepts PNG, JPEG or WebP up to 10 MiB and stores it in the library as an upload, within ai.uploadLimit per user. References are passed by asset id, so the server re-reads the owner's files rather than trusting client bytes. GET /api/ai/assets/{id}/content streams an owned asset (?download for an attachment) and DELETE /api/ai/assets/{id} removes it from R2 and D1.
Prompt enhancement
POST /api/ai/prompt/enhance with { "prompt": "..." } rewrites a rough idea into a detailed brief through Workers AI. It is free and limited to 20 requests a minute per user.
Add or change a model
- Add an entry to
IMAGE_MODELSwith its key, label, capabilities, credits, prompt and reference limits, ratios, provider, provider model id, estimatedcostUsdand whether it accepts explicit sizes. - Keep the price above cost: the margin check requires
credits × cheapest credit price ≥ costUsd × (1 + ai.minGrossMargin). - For a new provider, implement
ImageProviderinpackages/aiand select it inapps/web/src/modules/ai/mode.ts. - Run
pnpm test:unitand generate once in mock and once in live mode.