TF Feature Edit
Give a region someone else's identity
- levels
- target_tokens
- source_tokens
- source_levels
- levels
- info
This is the pack's headline edit, the one the example workflows build toward. TF Feature Edit replaces the feature vectors of the tokens you selected with a feature sourced from somewhere else. Because semantically similar content sits close together in DINOv2 space, this is effectively identity transfer: the target region takes on the source's meaning - texture, object-ness, whatever the feature encodes - while the spatial structure around it stays put. It's the "change what this region is" primitive, not "move it" (that's TF Shape Edit) and not "resample it" (that's TF Resume From Level).
Everything reduces to the paper's one edit primitive, z_i ← f_src for the selected tokens. Where does f_src come from? Three choices, and they're the whole node. source_mode decides how the source is read: region mean averages the source tokens into one vector and fills the whole target with it - that's the paper's f_src, the classic "make this look like that" - while token cycle copies token-for-token, which preserves the source's internal variation (good when you're transferring texture that shouldn't all be identical). source_levels decides which trajectory the source lives in: unwired means the same trajectory (the common case - move the background's look onto the subject, or borrow from elsewhere in the same image), and wired means a second trajectory entirely, which is the cross-image token exchange: take region A from one generated image and stamp it onto region B of another. source_level then picks which rung of the source's ladder to read from - default -1 reads from the same level as the edit, and the tooltip is honest that a different one is legal and occasionally exactly what you want ("coarse content written into a fine canvas").
level is l*, the hierarchy rung you're editing - default 2, the subparts level. The tradeoff is spelled out in the tooltip: coarser edits cascade through more levels when you resume; finer ones stay local. target_tokens receive the feature, source_tokens supply it, and strength (default 1.0) interpolates toward the source instead of replacing outright - 0.5 is a half-measure, 1.0 is the paper's edit.
Outputs are levels and info. Read the info string once - it tells you how many tokens moved, where the source came from (same trajectory or "class N"), and at what level - because it's the difference between knowing your edit and guessing. Crucially, the output trajectory is edited but not resumed: the node writes the new canvas at l*, and it's flagged dirty until TF Resume From Level re-samples everything above it. An un-resumed edit looks like it did nothing to the fine details, because the levels above l* are still the old ones.
Three traps, all real and all cheap to avoid. An empty target selection does nothing silently - check the what-was-selected preview. A selection snapped to a different level's region map raises the pack's drift error, so keep TF Region Map's level output wired into this node's level. And one before/after image can't tell an edit's effect from the re-sample seed's - that's the exact question TF Sweep Edit answers.
Install
Standard pack install: Manager → search Trajectory Forcing, or git clone https://github.com/korayulusan/ComfyUI-TrajectoryForcing into custom_nodes/. JAX-inside-ComfyUI wants its own Python 3.11 venv on CUDA 12; requirements.txt is empty on purpose, install.py adds the JAX stack or declines with a reason (normal), and the README's env/setup.sh is the fallback. Health check:
cd ComfyUI/custom_nodes/ComfyUI-TrajectoryForcing
python -m tf_nodes.doctor
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| levels | TF_LEVELS | The trajectory being edited. | |
| level | INT | 20–3 | l*, the level whose canvas is edited. Coarser edits cascade through more levels; finer ones stay local. |
| target_tokens | TF_TOKENS | Tokens that receive the new feature. | |
| source_tokens | TF_TOKENS | Tokens the feature is taken from. | |
| source_mode | COMBO | 'region mean' is the paper's f_src: one averaged vector fills the whole target. 'token cycle' copies token-for-token, keeping the source's internal variation. | |
| strength | FLOAT | 1.000–1 | Interpolate towards the source feature instead of replacing outright. 1.0 is the paper's edit. |
| source_level | INT | -1-1–15 | -1 (auto) reads the source from the same level as the edit. Levels share a token grid, so a different one is legal and occasionally what you want -- coarse content written into a fine canvas. |
| source_levelsopt | TF_LEVELS | Take the source feature from a different trajectory -- the cross-image token exchange. Unwired means same trajectory. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| levels | TF_LEVELS | — |
| info | STRING | — |