π Age Range Batch
The JSONL Factory That Drives Your Age-Progression Run
- prompts_jsonl
- ages_csv
- count
AgeRangeBatch is the batch-mode cousin of AgePromptBuilder, and the honest thing to say up front is that it's aimed at the CLI, not the graph. Give it a comma-separated list of ages - 5,15,25,45,65 by default - and it emits one JSONL line per age: {"age": 5, "band": "child", "prompt": "a 5 year old ..."}. That's the whole trick. It's the data generator that the pack's cli/age_shift_cli.py consumes to render an age progression in a single command, and it exists because ComfyUI evaluates one prompt per submission - you can't loop a KSampler inside the graph, so something has to build the batch of prompts for you.
If you're a UI-only user who wants to age one face to one target age, skip this node and use AgePromptBuilder instead. If your goal is "here's a face, give me a 5 β 15 β 25 β 45 β 65 sequence," this is the node whose output the batch script loops over.
How it works
It reuses the exact same ageβfeature lookup table as AgePromptBuilder (that's the pack's _types.py, twenty age ranges of concrete descriptors - "young toddler, round face, big bright eyes" at 5, "deeply weathered and wrinkled face" at 85). It parses your ages_csv, silently dropping anything that isn't a clean integer, maps each age to its band and feature phrase, and joins them into JSONL. Crucially it does not include the anti-drift negative logic that AgePromptBuilder has - it only builds positives, because the CLI composes the full conditioning graph itself.
Inputs and outputs
ages_csv- the only required input. Comma-separated integers,5,15,25,45,65by default. This is what you'll actually edit.subject,gender,style,extra_positive- same knobs as AgePromptBuilder. Defaultgenderisunspecified, and same advice applies: setsubjectto "boy" or "girl" for child ages or you'll get the awkward "male man" phrasing.
Outputs:
prompts_jsonl(STRING) - the newline-separated JSON records; the CLI's data source.ages_csv(STRING) - the cleaned, normalized age list (invalid entries removed).count(INT) - how many valid ages made it through, handy as a quick sanity check.
Running the batch
The CLI talks to a running ComfyUI server over its HTTP + websocket API - including a remote one, which is the point of the --ip flag - so it works from a laptop pointed at a beefy box:
uv run --script cli/age_shift_cli.py face.jpg \
--target-ages 5,15,25,45,65 \
--gender male --subject man \
--pulid-weight 0.95 --guidance 3.0 --steps 28 --seed 42 \
--ip 192.168.1.50 --out ./out
Output lands as ./out/age_005_*.png, age_015_*.png, and so on. The script uses PEP 723 inline dependencies, so uv run --script installs what it needs automatically - and the README calls out the specific trap that the missing module is websocket-client, not websocket (a separate abandoned package that won't satisfy the import).
Install and gotchas
Same pack install as the rest: clone aadebuger/ComfyUI-AgeShift into custom_nodes, uv pip install -r requirements.txt, restart. The batch path additionally needs the full PuLID-Flux + Flux weight stack on the server (see the AgePromptBuilder article for that dance - the InsightFace antelopev2 manual placement is the part people get wrong).
The classic failure is No module named 'websocket' when running the script directly - the README's fix is uv pip install websocket-client, or just lean on uv run --script to let it resolve. The other usual suspects: no --ip (defaults to 127.0.0.1:8188), and forgetting that each age is a separate full generation, so a five-age run is five times the sampling time. Lock the seed across ages or you'll get five different sub-identities instead of one person at five ages - that's the single most common reason a progression looks like a cast, not a life.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| ages_csv | STRING | 5,15,25,45,65 | β |
| subjectopt | STRING | person | β |
| genderopt | COMBO | unspecified | 4 options: unspecified, male, female, non-binary |
| styleopt | STRING | photorealistic portrait, sharp focus, natural lighting | β |
| extra_positiveopt | STRING | same identity | β |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| prompts_jsonl | STRING | β |
| ages_csv | STRING | β |
| count | INT | β |