TrainyThing Wait
The other half of Review, for when the split lives elsewhere
- queue
- images
- latent
- images_b
- accepted
- rejected
- accepted_latent
- images
- labels
- summary
- notes
- accepted_meta
- accepted_indices
What it is
TrainyThing Wait is the second half of TrainyThing Review, broken out. A Send made the queue and moved on; Wait takes that queue's handle, holds the run until the verdicts are in (or the timeout hits), and does the slicing: keepers, rejects, keepers' latents, notes, seeds, indices.
You reach for it when Send and the split can't be the same node: a detour between uploading and slicing, or a send at the end of one branch with the consumer three groups away. Review is one box doing both; Send + Wait is the same machinery with a wire in the middle, at the same cost - while Wait polls, ComfyUI does nothing else.
If nothing needs to happen between them, use Review. If the verdicts can arrive hours later, use Send then Load - the only path here that never holds the queue.
How it works
Wait receives a TRAINYTHING_QUEUE handle from Send: daemon URL, slug, queue id, link, and the refs this run added. It reconnects (TRAINYTHING_URL/TRAINYTHING_TOKEN, then ~/.trainything/config.json, then 127.0.0.1:4747), polls the queue's status and reports "judged N of M" while it waits. A daemon that stops answering or returns a 5xx is retried on a 2, 4, 8 … up-to-30-second backoff; a 401, 403, 404 or 409 fails immediately - right split, since those mean a wrong URL or token.
Everything it needs to slice is checked before it waits. pair without images_b, a B batch of the wrong size, a latent with fewer samples than there are images, an images batch whose size doesn't match the handle's card count - all raise at once, so a miswired node fails in a second instead of ninety minutes later.
Then it slices the batch you wired in - Wait never re-downloads images. And only this run's cards are split, even in a queue five Sends have fed: the handle carries the refs your Send added. That's also why the latent stays a real latent instead of a re-encode.
The inputs and outputs that matter
queue- from Send'squeueoutput. It's a custom socket type, so nothing else fits and you can't type it in.images- the same pictures that went into Send. Wire both nodes off the same VAE Decode.timeout_minutes- 45 by default, up to a week. The queue stays open on the dashboard after a timeout either way.on_timeout-partialgoes on with whatever got judged and calls the restunjudged;blockstops the run so nothing downstream sees a half-reviewed batch.latent(optional) - the KSampler's latent. Wire it andaccepted_latentcarries the keepers' latents onward.images_b(optional) - pair mode only, so winners can come from either side.
Outputs are Review's first nine, minus link and slug: accepted, rejected, accepted_latent, images, labels, summary, notes, accepted_meta, accepted_indices. The images + labels pair feeds TrainyThing Filter when keep/reject isn't the rule you need - unjudged finds the cards a timeout skipped.
Installing it
Same pack, same steps whichever node brought you here:
cd ComfyUI/custom_nodes
git clone https://github.com/ryanrinkel/comfyui-trainything
cd comfyui-trainything
python -m pip install -r requirements.txt # ComfyUI's own python, or python_embeded\python.exe
# restart; the five nodes are under "TrainyThing"
npx -y trainything dashboard # once: starts the daemon, Node >= 22.5
Or ComfyUI Manager, searching "TrainyThing" (comfy node install trainything). Deps are segno, pillow, numpy; no model files. The pack targets ComfyUI's V3 node API and pins 0.39.0+ - on an older build you see one warning line and may get no nodes.
Where people get burned
Wiring the wrong images. The batch has to be the one Send was given, because Wait slices it with this run's refs. There's a guard - batch size against the handle's card count - but a batch of the right size and the wrong content slides straight through.
Cancelling leaves the queue open. Press Cancel and the verdicts aren't lost; they stay in the daemon, and a later TrainyThing Load reads them. You just don't get the split in this run.
A cached Send means Wait waits on an old queue. If ComfyUI skips an unchanged Send, Wait gets last time's handle, and you may be staring at a queue finished hours ago. Change a seed to make the send real.
No daemon, one line, no stack trace. no TrainyThing at http://127.0.0.1:4747; run npx -y trainything dashboard once. On a rented GPU, 127.0.0.1 is not your desktop - set TRAINYTHING_URL to something the box can reach, and remember the token travels with it.
The preview text won't render. On 0.39.0 ui.PreviewText doesn't paint on custom nodes, so the link appears under the QR in the image. Not a you problem.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| queue | TRAINYTHING_QUEUE | Connect from TrainyThing Send's queue output. | |
| images | IMAGE | The same pictures that went into Send, so they can be split into keepers and rejects. | |
| timeout_minutes | FLOAT | 45.00.1–10080 | How long to wait for the phone before the run moves on. The batch stays open on the dashboard either way. |
| on_timeout | COMBO | partial | What happens when the time runs out. partial: carry on with what was judged, the rest counts as unjudged. block: stop here; nothing after this node runs. |
| latentopt | LATENT | Optional: the latent from the KSampler that made these pictures. accepted_latent then carries the keepers' latents to a next step. | |
| images_bopt | IMAGE | pair mode only: the B pictures, so the winners can come from either side. |
Outputs (9)
| Name | Type | Description |
|---|---|---|
| accepted | IMAGE | The pictures the reviewer kept. |
| rejected | IMAGE | The pictures the reviewer rejected. |
| accepted_latent | LATENT | The keepers' latents, cut from the latent you wired in. Nothing flows here if no latent was wired. |
| images | IMAGE | All the pictures, unchanged, in batch order. Wire with labels into TrainyThing Filter. |
| labels | STRING | One line per picture: its verdict, the votes and the notes. Made for TrainyThing Filter. |
| summary | STRING | A short readable report: how many were kept, rejected or contested, and the notes. Wire to a Preview Any node. |
| notes | STRING | The reasons the reviewer typed, one per line, with the picture each one was about. |
| accepted_meta | STRING | For each keeper: its seed, batch position, prompt, checkpoint, LoRAs and sampler settings, as JSON. For reproducing or refining. |
| accepted_indices | INT | The batch positions of the keepers, counting from 0. |