3dddbe1671729d4e7736a35fa1d6b683e679d497
proj(a|b) - project a onto the (mean, unit) direction of b reject(a|b) - a minus that projection (orthogonal component) renorm(a|ref)- rescale a so each token's L2 norm matches ref's mean L2 noise(a|std) - a + N(0, std) nearest(e|k) - snap mean(e) to its k nearest vocab tokens (cosine sim) lerp(a|b|t) - alias for avg(a|b|t) All follow the existing MultiArgAction pattern; nearest reuses the embedding-weight cosine machinery the Inspect node uses. Nine new tests cover the math invariants (proj+reject reconstructs input, reject is orthogonal to b, renorm matches ref norm, noise(_, 0) is identity, nearest of a single token returns that token). Relax MultiArgAction/SingleArgAction __init__ type hints to List since SegOrAction now includes WeightedGroup and the Union isn't importable in base.py without a cycle.
KepPromptLang
A small DSL for ComfyUI that lets you do math on CLIP token embeddings before they're fed into the text transformer.
sum(diff(king|man)|woman)
norm(sum(cat | dog | horse | parrot))
A slerp(cat|dog|0.5) is happy
Install
Clone into ComfyUI/custom_nodes/:
cd ComfyUI/custom_nodes
git clone <repo-url> KepPromptLang
pip install -r KepPromptLang/requirements.txt
Usage
- Add a Special CLIP Loader node and feed it the CLIP output from your Load Checkpoint.
- Pass the wrapped CLIP into a standard CLIP Text Encode node.
- Use the DSL syntax in your prompt.
To debug what your DSL is doing, add a PromptLang Inspect node — it shows the per-slot weight, L2 norm, and nearest-vocab words for the resolved embeddings.
See examples/WIP_Example_workflow.json for a working workflow.
Syntax
| Element | Syntax | Example |
|---|---|---|
| Plain word | alphanumeric (with ,_.-) |
cat, dog_face |
| Quoted string | single or double quotes | "hello world", 'it\'s sunny' |
| Weighted | (text:weight) or emph(text|weight) |
(cat:1.3), emph(cat|1.3) |
| Embedding (textual inversion) | embedding:NAME |
embedding:face_vector |
| Function | name(arg | arg | ...) |
sum(king | woman) |
Arguments inside a function are separated by |. Each arg can itself be plain text, an embedding, a quoted string, or another function call.
Quick examples
- Average two prompts:
avg(The cat is | The dog is | 0.5) - Normalize a sum:
norm(sum(cat | dog | horse)) - King − Man + Woman:
sum(diff(king|man)|woman)(orsum(king | neg(man) | woman)) - Negate an embedding:
neg(embedding:body_vector)
Functions
| Display Name | Action Name | Description | Usage Examples |
|---|---|---|---|
| Average | avg | Performs a weighted average between two segments or actions. The recommended weight is 0 - 1. |
|
| Difference | diff | Subtracts the segments in the order they are given. The first segment is subtracted from the second, then the third from the result, and so on. |
|
| Multiply | mult | Multiplies the provided segments or actions by the multiplier. |
|
| Nearest Vocab | nearest | Snaps a computed vector to the k nearest real vocabulary tokens (by cosine similarity), returning their embeddings concatenated. The input is mean-pooled before lookup. |
|
| Negate | neg | Negates the provided segments or actions. |
|
| Noise | noise | Adds Gaussian noise (mean 0, given std) to the embeddings of the first argument. |
|
| Normalize | norm | Normalizes the provided segments or actions. |
|
| Positional Embedding Scale | posScale | Scales (multiplies) the positional embeddings of the provided segments or actions by the multiplier. |
|
| Ignore Positional Embeddings | postPos | Prevents positional embeddings from being applied to the provided segments or actions. |
|
| Project | proj | Projects the first argument onto the direction of the second (mean, unit-normalized). |
|
| Random Embedding | rand | Returns a random embedding of the specified token length, with the values optionally bounded by the second and third arguments. |
|
| Reject | reject | Removes the component of the first argument along the direction of the second (a - proj(a|b)). |
|
| Renormalize | renorm | Rescales the first argument so each token's L2 norm matches the (mean) L2 norm of the reference. |
|
| Scale Dimensions | scaleDims | Scales the specified dimensions of the input embeddings by the specified amount |
|
| Set Dimensions | setDims | Sets the specified dimensions of the input embeddings to the specified value |
|
| Slerp | slerp | Performs a slerp (interpolation) between two segments or actions, with the given weight. The recommended weight is 0 - 1. |
|
| Sum | sum | Adds the embeddings of the provided segments or actions. |
|
lerp(a|b|t) is also accepted as an alias for avg(a|b|t).
Regenerate the table with python tools/build_docs.py.
Development
Tests are pytest-based and don't require ComfyUI:
pip install -e ".[dev]"
python -m pytest
Compatibility
- SD1.x (CLIP-L) and SDXL (CLIP-L + CLIP-G).
- SD2 is not supported.
- Two pooler-output actions (
_exp-pooler,_exp-pooledAvg) from earlier versions were experimental and have been removed; they relied on direct HuggingFace transformer access that is no longer how ComfyUI structures its CLIP encoders.
Languages
Python
100%
