Layered photo editor with a JSON command surface for agents.

Photo editor

An interactive, layered photo editor that runs in the browser and can be driven by hand, from Python, or by an AI agent. Open it at /editor.

What you can do

and gamma, or apply a look (grayscale, sepia, invert, vintage, kodachrome, technicolor, polaroid, black and white, brownie). Original pixels are never modified; effects are re-applied on render and export.

Enter applies and Escape cancels. The layer keeps its place on the artboard; only its visible pixels change.

turn as one undo step, and looks at a rendered preview of the canvas before deciding it is done. It is a conversation: answer its questions in the same box and it carries on with everything it has seen so far.

document keeps the string, the engine paints it across the layer's box.

Exporting

PNG, JPEG, WebP and SVG are rendered in the browser. TIFF, PDF, AVIF, GIF, BMP and ICO are transcoded by the server. Each export can go to a browser download, a server directory, or a Cloudflare R2 bucket, at 0.5x, 1x, 2x or 4x scale, for the whole canvas or only the selected layers.

For agents

Every operation is a JSON command of the form {"id", "type", "payload"}, submitted through the command prop of the DashPhotoCanvas component and acknowledged on commandResult. Commands run in order, each id runs once, and the batch command applies several edits as a single undo step. An export with preview: true returns a small JPEG so a vision model can look at the result and correct it.

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: