-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Change Request: Introduce image → imageList adapter + automatic lifting of single-image operators
Context
Before implementing complex grouped / nested pipelines, we need a simpler and more fundamental capability:
Seamless interoperability between image and imageList.
Currently:
imageandimageListare strictly different artifact types.- An operator declared as
image → imagecannot acceptimageList. - Users must manually build pipelines with explicit list-aware operators.
This creates friction and unnecessary duplication.
Goal
Introduce:
- Implicit adapter:
image → imageList - Automatic lifting of single-image operators over
imageList
This enables:
imageList
→ resize (image → image)
→ convertToJpeg (image → image)
→ imagesToPdf (imageList → pdf)
Even though resize and convertToJpeg are defined only for image.
Required Behavior
1️⃣ Adapter: image → imageList
If pipeline start type is image, and next operator expects imageList, then:
image → [image]
i.e. wrap single image into a list of length 1.
This should be transparent.
2️⃣ Operator lifting (map semantics)
If:
- Input artifact is
imageList - Operator is defined as
image → image
Then automatically apply the operator to each element:
imageList [i1, i2, i3]
→ resize
= [ resize(i1), resize(i2), resize(i3) ]
Output type becomes imageList.
This is conceptually:
map(op, imageList)
But should be automatic, not require a separate map operator.
Example Workflow
User selects 5 images:
imageList
→ resize (image → image)
→ convertToJpeg (image → image)
→ imagesToPdf (imageList → pdf)
Expected behavior:
- Each image resized
- Each image converted to JPEG
- Final PDF has N pages
No explicit list-aware resize operator required.
Architectural Proposal
In typing layer
When checking canInsertBetween():
If:
beforeType = imageList
op.input = image
Then allow insertion if:
- op.output = image
Effective result type becomes:
imageList
In runner
Pseudo-logic:
if (input.type === "imageList" && op.io.input === "image") {
const results = input.images.map(img => runOpOnSingle(img));
return { type: "imageList", images: results };
}No changes required in individual operators.
Benefits
- Eliminates need for duplicate operators (
resizeList,jpegList, etc.) - Keeps operator catalogue clean
- Enables natural chaining
- Keeps typing system strong
- No immediate need for DAG / complex pipeline model
Non-Goals (for this phase)
- No nested
imageListofimageList - No grouping yet
- No branching
- No DAG
This is a foundational interoperability layer before complex pipelines.
Acceptance Criteria
- Single
imagecan flow intoimageListoperator via automatic wrapping. imageListcan accept anyimage → imageoperator.- Result remains
imageList. - PDF export correctly produces N pages.
- No regression in existing single-image pipelines.