Nodes/ComfyUI-TypedDecision/Typed Decision Moment Search
ComfyUI Node

Typed Decision Moment Search

Find the five seconds where the dog shows up, to the frame

By nomadoor·Created 20 days ago·Updated 4 days ago· 11
Typed Decision Moment Search
  • model
  • video
  • images
  • intervals
  • videos
◄instructions►
◄state►
◄window8►
◄threshold0.50►
◄criteria_true►
◄criteria_false►

Moment Search answers one question about a whole video - "is a dog visible?" - and hands back the intervals where the answer is yes, plus the video trimmed to each of them. Frames in, clips out. No scrubbing a timeline to find the eleven seconds you actually wanted.

Captions are the wrong tool here. An in-graph LLM is good at exactly one thing - short structured rewriting, a small obedient model that follows a format and stops - and Typed Decision takes that literally: the model emits a probability over yes/no, and this node spends a few hundred of those.

The three-pass trick that makes it affordable

Reading every frame of a long clip through a 4B model would be miserable, so the node cheats.

It samples at 2 fps - a 60-second clip becomes 120 samples - then works in three steps. First it judges window samples at a time (default 8, so four seconds per judgment) and throws away blocks that fail outright. Second, it judges each sample of the surviving blocks one at a time. Third, for each boundary it goes back to the source frames, full frame rate, and judges everything between the last passing sample and the first failing one to place the edge.

A block only has to prove it holds nothing, so it passes at half your threshold - one strong positive inside can leave the block scoring under the bar as a whole.

Bigger window means fewer forwards. But since every sample is rescaled to the size d3 gives a 2 × window-frame clip, a big window also reads each frame smaller, and small subjects in wide shots are where that bites.

The inputs you'll actually touch

instructions is the whole node, really. Write it as a claim about the video - "A dog is visible." - or a question. criteria_true and criteria_false are optional clarifiers for yes and no.

window and threshold are your speed/recall dials. state takes optional facts as plain text or JSON (128 KB cap); with JSON, instructions can name fields in backticks like `listing.color`.

images is the optional reference slot, and it's why this node earns its place in dataset work: drop in a photo of the person you're hunting and have the model find them across the footage. Big trap, though - ask "The video shows the same person as the image," not "The person in the image is visible." The second is true of the reference itself, so every frame passes and you get one interval covering the whole file.

video is the clip to search, and model comes from Load Typed Decision Model in the same pack.

Outputs

intervals is a JSON string: a list of {start, end, start_frame, end_frame, score} - seconds and source-frame numbers, end_frame exclusive, score the highest probability inside that interval. Good for a cut list, but nothing consumes it unless you parse it.

videos is the one you wire up: a list of the input video trimmed to each interval, feeding a concatenate node and then Save Video. Know the failure mode - when nothing is found this output is blocked and the video nodes after it are skipped. No error, no files, intervals is []. If your run "did nothing," that's why.

Install

Manager, search ComfyUI-TypedDecision, install, restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/nomadoor/ComfyUI-TypedDecision

No requirements.txt, no pip step - pyproject.toml declares an empty dependency list and inference runs on ComfyUI's own text-encoder engine (needs 0.37.0+). The weights are the real install: for d3, one file in models/text_encoders (d3_mini_int8_convrot.safetensors, 5.52 GB, is what the sample workflow uses); for imajev, Qwen3.5-4B plus an imajev-4b folder in models/typed_decision.

Where it goes wrong

imajev can't do video. It takes no videos and at most 2 images, so the node sends window frames as images and window is capped at 2, or 1 with a reference. You lose most of the block-skipping and pay per-sample. Use d3 or Clef-flash here; imajev is for stills.

Motion is not searchable. The question has to be something one frame shows. "A dog is visible" - yes. "The dog is walking left" - no; the model never sees frames as motion.

Short events fall through the grid. At 2 fps anything under half a second can land between samples, and a big window can drop a half-second event with its block - the README says d3-mini and d3-flash start losing those at 16.

Thresholds are opinions. Something half out of frame may already read as gone, so write the question for what you want counted and check the first run's intervals rather than trusting score.

Time. Stages two and three multiply your judgments, and debias in the loader multiplies again. Start with d3-mini int8 on a short clip and watch the three-stage bar. This makes long-video judgement cheaper, not free.

Categorytyped decision

Inputs (9)

NameTypeDefaultDescription
instructionsSTRING—
modelTYPED_DECISION_MODEL—
videoVIDEO—
stateSTRINGWith JSON, instructions can name its fields in `backticks`, e.g. `listing.color`.
windowINT81–64Frames judged together at first, read at 2 fps (8: 4 seconds). The frames of a block that passes are judged one by one. A larger window can drop a half-second event with its block. imajev takes at most 2.
thresholdFLOAT0.500–1A frame passes when the probability of yes reaches this; a block of frames, at half of it.
criteria_trueoptSTRING—
criteria_falseoptSTRING—
imagesoptCOMFY_AUTOGROW_V3Reference images, in slot order, seen before every window of the video, e.g. a person to find. imajev takes 2 images in all: one reference and window 1.

Outputs (2)

NameTypeDescription
intervalsSTRINGJSON list of {start, end (seconds), start_frame, end_frame (end exclusive), score}.
videosVIDEOThe video trimmed to each interval.