feat(durable): read returns images, optional Photon image processor

read returns an image file as one image block (programs get an ImageContent) plus an info diagnostic,
instead of an unsupported_image error. Limits are the conversation model's inputLimits.images.resize,
by default 2000x2000 pixels and 4.5 MB of base64.

- Without a processor: PNG, JPEG, GIF, and WebP within the limits pass through undecoded; the byte limit
  is checked before reading the file, dimensions from the header. Larger images and BMP are error results.
- With createCodingTools({ images }): the processor orients by EXIF, converts BMP to PNG, and shrinks to
  fit. ImageProcessor.prepare is async.
- @earendil-works/pi-durable/images: createPhotonImages(wasm) on @silvia-odwyer/photon 0.3.3 (web build);
  /images/node and /images/cloudflare load the wasm. The root and ./tools entries never reach it (enforced
  in check-entry-graphs).
- An image must be read whole: one that changes while read is read again, unlike a growing text file.
- A model without image input gets a diagnostic that it sees a placeholder.
This commit is contained in:
Mario Zechner 2026-10-09 19:38:02 +00:00
parent eba8497395
commit 42a3497d03
20 changed files with 1099 additions and 64 deletions

View file

@ -30,6 +30,24 @@
"import": "./dist/tools/index.js",
"default": "./dist/tools/index.js"
},
"./images": {
"source": "./src/images/index.ts",
"types": "./dist/images/index.d.ts",
"import": "./dist/images/index.js",
"default": "./dist/images/index.js"
},
"./images/node": {
"source": "./src/images/node.ts",
"types": "./dist/images/node.d.ts",
"import": "./dist/images/node.js",
"default": "./dist/images/node.js"
},
"./images/cloudflare": {
"source": "./src/images/cloudflare.ts",
"types": "./dist/images/cloudflare.d.ts",
"import": "./dist/images/cloudflare.js",
"default": "./dist/images/cloudflare.js"
},
"./storage/memory": {
"source": "./src/storage/memory.ts",
"types": "./dist/storage/memory.d.ts",
@ -110,6 +128,7 @@
"dependencies": {
"@earendil-works/chord": "^1.1.0",
"@earendil-works/pi-ai": "^1.1.0",
"@silvia-odwyer/photon": "0.3.3",
"diff": "8.0.4",
"typebox": "1.3.27"
},