Add image-gen module: Spring AI ImageModel options on the wire, a moderation gate, and safe storage of generated images in MinIO (sniffed content type, byte and pixel caps, server-chosen keys, capped URL fetcher); per-provider cost table dated 2026-10-28. ImageModel and ModerationModel are hand-written fakes; MinIO is real via Testcontainers; no image provider called.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b7rnC7jppGGdHGESvy
This commit is contained in:
2026-10-28 18:36:40 +00:00
co-authored by Claude Sonnet 5.5
parent 108fc44542
commit aa8b1604ed
48 changed files with 2112 additions and 0 deletions
@@ -0,0 +1,30 @@
package com.ankurm.imagegen;
import java.util.Set;
/**
* Every limit in one place so a test (and a reader) can see them.
*
* @param maxBytes largest image we will accept, decoded
* @param maxPixels largest width x height we will accept, read from the header before decoding
* @param maxPromptChars longest prompt we will send
* @param allowedTypes sniffed MIME types we will store
* @param fetchHosts hosts a provider-returned URL may point at (exact match, https only unless allowInsecure)
* @param allowInsecure allow http:// fetches; only for tests against a local server
*/
public record ImagePolicy(long maxBytes, long maxPixels, int maxPromptChars, Set<String> allowedTypes,
Set<String> fetchHosts, boolean allowInsecure) {
public static ImagePolicy defaults() {
return new ImagePolicy(8L * 1024 * 1024, 16_000_000L, 4000,
Set.of("image/png", "image/jpeg", "image/webp"), Set.of(), false);
}
public ImagePolicy withMaxBytes(long v) {
return new ImagePolicy(v, maxPixels, maxPromptChars, allowedTypes, fetchHosts, allowInsecure);
}
public ImagePolicy withFetch(Set<String> hosts, boolean insecure) {
return new ImagePolicy(maxBytes, maxPixels, maxPromptChars, allowedTypes, hosts, insecure);
}
}