Nodes/ComfyUI_LiteLLM/CreateReflectionFilter
ComfyUI Node

CreateReflectionFilter

Wrap any callable into a reflection filter for the completion loop

By Hopping-Mad-Games·Created 2 years ago·Updated 11 months ago· 7
CreateReflectionFilter
  • CALLABLE
  • args
  • kwargs
  • Reflection filter

CreateReflectionFilter is a tiny adapter node, and it's honest about being tiny. Its whole job is to take a callable (a function), bind some extra arguments to it, and hand back a new callable that fits the exact shape LiteLLMCompletionWithReflectionFilter expects. If that sounds like a functools.partial for a visual graph - it basically is, and it's genuinely handy in a UI where you can't write partial() by hand.

The reflection-filter contract: the loop calls the filter with the completion string, and the filter returns either a new prompt or None (stop). The wrapper guarantees your arbitrary callable is called as CALLABLE(completion, *args, **kwargs), so you can take any function that was built to take the completion first and make it conform.

How it works

You connect the callable you want wrapped into CALLABLE. Optionally feed args (a LIST) and kwargs (a DICT) - these get appended/passed on every invocation, which is how you pre-load extra parameters without touching the function itself. The node returns a reflection_filter closure: when called with a completion, it prepends the completion to your saved args and calls the original callable.

So if you have a completion function that also wants a max_length and a language flag, you drop those into args/kwargs here instead of rebuilding the function.

The inputs

  • CALLABLE (required) - the function to wrap.
  • args (optional, LIST) - positional arguments appended after the completion.
  • kwargs (optional, DICT) - keyword arguments passed along.

Output: Reflection filter (CALLABLE) - exactly what LiteLLMCompletionWithReflectionFilter's reflection_filter input wants. It also plays nice with FirstCodeBlockReflectionFilter, which wraps a callable the same way but extracts the first code fence first; the two can be chained.

Installing

It ships with ComfyUI_LiteLLM. ComfyUI Manager, search "ComfyUI_LiteLLM", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Hopping-Mad-Games/ComfyUI_LiteLLM
cd ComfyUI_LiteLLM
pip install -r requirements.txt

Restart, and it's under ETK/LLM/LiteLLM.

Where people get burned

The classic confusion is expecting this node to do something visible. It doesn't run anything - it manufactures a function that sits in your graph until the loop calls it. If you run the workflow and nothing changes, that's correct behavior; the filter only fires while LiteLLMCompletionWithReflectionFilter is iterating. Second, the CALLABLE input has a default of None, which is a trap dressed as a convenience: if you leave it unconnected, you get a filter that calls None and blows up the moment the loop tries to use it. Always connect a real callable. And remember the stop-signal rule from the loop node - if the wrapped function returns an empty string rather than None, the loop won't stop; it'll just get a blank prompt. If you need the loop to terminate cleanly, make sure whatever you wrap knows to return None when there's nothing left to say.

CategoryETK/LLM/LiteLLM

Inputs (3)

NameTypeDefaultDescription
CALLABLECALLABLE
argsoptLIST
kwargsoptDICT[object Object]

Outputs (1)

NameTypeDescription
Reflection filterCALLABLE