Document Regional legacy removal windows
This commit is contained in:
@@ -68,6 +68,8 @@ CATEGORY_MODEL_FLUX2_KLEIN = f"{CATEGORY_MODELS}/FLUX.2 Klein 9B"
|
||||
CATEGORY_MODEL_KREA2 = f"{CATEGORY_MODELS}/Krea 2"
|
||||
CATEGORY_MODEL_ANIMA = f"{CATEGORY_MODELS}/Anima"
|
||||
DEFAULT_JSON = json.dumps(default_document(), ensure_ascii=False, separators=(",", ":"))
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA bindings JSON/output.
|
||||
# Remove with the lora_bindings output after saved V2 workflows have passed the compatibility window.
|
||||
DEFAULT_LORA_BINDINGS_JSON = json.dumps(default_bindings(), ensure_ascii=False, separators=(",", ":"))
|
||||
DEFAULT_LORA_V3_JSON = '{"version":3,"entries":[],"steps":[]}'
|
||||
DEFAULT_DETAILER_V3_JSON = '{"version":1,"jobs":[]}'
|
||||
@@ -108,6 +110,8 @@ class BVRegionalPromptNode:
|
||||
),
|
||||
},
|
||||
"optional": {
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Persisted V2 bindings payload.
|
||||
# Remove with the lora_bindings output after workflow migration support expires.
|
||||
"lora_bindings_json": (
|
||||
"STRING",
|
||||
{"default": DEFAULT_LORA_BINDINGS_JSON, "multiline": True, "dynamicPrompts": False},
|
||||
@@ -129,6 +133,7 @@ class BVRegionalPromptNode:
|
||||
},
|
||||
}
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Second output is V2 wiring.
|
||||
RETURN_TYPES = (REGIONAL, BINDINGS)
|
||||
RETURN_NAMES = ("regional", "lora_bindings")
|
||||
FUNCTION = "build"
|
||||
@@ -180,6 +185,8 @@ class BVLoraStackCollectorNode:
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
# BV-LEGACY(marked=2026-08-25, review-after=2026-10-25): V2 stack registry bridge.
|
||||
# Remove only when named stacks expose the V3 provider contract without this adapter.
|
||||
"lora_registry": (REGISTRY, {}),
|
||||
"collector_id": ("STRING", {"default": "", "multiline": False}),
|
||||
}
|
||||
@@ -235,6 +242,8 @@ def _context_lora_scopes(regional):
|
||||
|
||||
|
||||
def _consumer_lora_scopes(regional, document, lora_registry=None, lora_bindings=None):
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Prefer the V3 context capability.
|
||||
# Remove this sidecar fallback together with every lora_registry/lora_bindings consumer port.
|
||||
if lora_registry is not None or lora_bindings is not None:
|
||||
return resolve_scope_stacks(lora_registry, lora_bindings, document)
|
||||
return _context_lora_scopes(regional)
|
||||
@@ -500,6 +509,7 @@ class BVRegionalNativeConditioningNode:
|
||||
},
|
||||
),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -544,6 +554,7 @@ class BVRegionalSDXLAttentionNode:
|
||||
{"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001},
|
||||
),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -588,6 +599,7 @@ class BVRegionalZImageAttentionNode:
|
||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_percent": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -624,6 +636,7 @@ class BVRegionalFlux2KleinAttentionNode:
|
||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_percent": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -667,12 +680,15 @@ class BVRegionalKrea2AttentionNode:
|
||||
"attention_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_percent": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
# BV-LEGACY(marked=2026-08-25, review-after=2026-10-25): Compatibility execution mode.
|
||||
# Remove only after token-gated Krea 2 matches supported published LoRA behavior.
|
||||
"regional_lora_mode": (["multipass_legacy", "token_gated_singlepass"], {
|
||||
"default": "token_gated_singlepass",
|
||||
"tooltip": "Legacy evaluates one masked model pass per distinct LoRA stack. "
|
||||
"Token-gated single-pass is experimental and changes results.",
|
||||
}),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -709,6 +725,7 @@ class BVRegionalKrea2AttentionNode:
|
||||
positive, negative, slots, aspect_ratio = compile_krea2_attention(
|
||||
document, clip, hook_groups
|
||||
)
|
||||
# BV-LEGACY(marked=2026-08-25, review-after=2026-10-25): See the INPUT_TYPES removal gate above.
|
||||
if regional_lora_mode == "multipass_legacy":
|
||||
positive, negative = apply_attention_hook_passes(
|
||||
positive, negative, document, scope_stacks, hook_groups
|
||||
@@ -760,11 +777,14 @@ class BVRegionalAnimaConditioningNode:
|
||||
"base_ratio": ("FLOAT", {"default": 0.1, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"cross_inject_every_n_blocks": ("INT", {"default": 1, "min": 1, "max": 100, "step": 1}),
|
||||
"self_inject_every_n_blocks": ("INT", {"default": 1, "min": 1, "max": 100, "step": 1}),
|
||||
# BV-LEGACY(marked=2026-08-25, review-after=2026-10-25): Compatibility execution mode.
|
||||
# Remove only after token-gated Anima matches supported published LoRA behavior.
|
||||
"regional_lora_mode": (["multipass_legacy", "token_gated_singlepass"], {
|
||||
"default": "multipass_legacy",
|
||||
"tooltip": "Legacy preserves published Anima results. Single-pass is an experimental token-gated model-LoRA path.",
|
||||
}),
|
||||
},
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 LoRA sidecar inputs.
|
||||
"optional": {"lora_registry": (REGISTRY, {}), "lora_bindings": (BINDINGS, {})},
|
||||
}
|
||||
|
||||
@@ -809,6 +829,7 @@ class BVRegionalAnimaConditioningNode:
|
||||
scope_stacks = resolve_stack_paths(_consumer_lora_scopes(regional, document, lora_registry, lora_bindings))
|
||||
hook_groups = create_hook_groups(scope_stacks)
|
||||
positive, negative, regions, background = compile_anima_adapter(document, clip, hook_groups)
|
||||
# BV-LEGACY(marked=2026-08-25, review-after=2026-10-25): See the INPUT_TYPES removal gate above.
|
||||
if regional_lora_mode == "multipass_legacy":
|
||||
positive, negative = apply_attention_hook_passes(
|
||||
positive, negative, document, scope_stacks, hook_groups
|
||||
|
||||
@@ -68,6 +68,8 @@ class BVRegionalDetailerPlanNode:
|
||||
"config_json": ("STRING", {"default": "", "multiline": True}),
|
||||
},
|
||||
"optional": {
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): V2 detector sidecar input.
|
||||
# Remove after migrated plans resolve detectors exclusively through V3 provider links.
|
||||
"detector_registry": (DETECTOR_REGISTRY, {}),
|
||||
"resource_provider": (RUNTIME_PROVIDER, {"forceInput": True}),
|
||||
**{
|
||||
@@ -118,6 +120,7 @@ class BVRegionalDetailerPlanNode:
|
||||
detector_id = job.get("detector_id")
|
||||
if detector_id is not None:
|
||||
resolve_detector(detector_registry, detector_id)
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Preserve V2 executor lookup.
|
||||
plan["detector_registry"] = detector_registry
|
||||
summary = "\n".join(
|
||||
f"{index + 1}. {' + '.join(job['region_names'])}"
|
||||
@@ -161,6 +164,7 @@ class BVRegionalDetailerJobNode:
|
||||
raise ValueError("BV Detailer Loop Job Resolver requires a single IMAGE shaped B,H,W,C")
|
||||
job = detailer_job_at(detailer_plan, job_index)
|
||||
detector_id = job.get("detector_id")
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Execute unmigrated V1/V2 jobs.
|
||||
if "detector_binding" not in job:
|
||||
job["detector_binding"] = (
|
||||
resolve_detector(detailer_plan.get("detector_registry"), detector_id)
|
||||
@@ -231,6 +235,8 @@ class BVDetectorRegistryNode:
|
||||
},
|
||||
}
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): First output is the V2 registry.
|
||||
# Remove it only with the detector_registry plan input; resource_provider is the V3 output.
|
||||
RETURN_TYPES = (DETECTOR_REGISTRY, "INT", "STRING", RUNTIME_PROVIDER)
|
||||
RETURN_NAMES = ("detector_registry", "detector_count", "registry_summary", "resource_provider")
|
||||
FUNCTION = "collect"
|
||||
@@ -252,6 +258,7 @@ class BVDetectorRegistryNode:
|
||||
}
|
||||
except json.JSONDecodeError as error:
|
||||
raise ValueError("detector registry configuration is invalid JSON") from error
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Accept config v1 without collector_id.
|
||||
if not isinstance(parsed, dict) or parsed.get("schema") != "bv.detector_registry_config" or parsed.get("version") not in {1, 2}:
|
||||
raise ValueError("detector registry configuration must be bv.detector_registry_config v1 or v2")
|
||||
collector_id = str(parsed.get("collector_id", "")).strip() if parsed.get("version") == 2 else ""
|
||||
|
||||
@@ -280,6 +280,8 @@ def materialize_detailer_plan(
|
||||
return plan
|
||||
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Legacy plan -> V3 resource bindings.
|
||||
# Remove after saved plans carry explicit same-graph collector_id/resource_id pairs.
|
||||
def migrate_detailer_plan_v1(
|
||||
value: Any,
|
||||
config: Any,
|
||||
|
||||
@@ -249,6 +249,8 @@ def validate_document(document: Any, *, executable: bool = True) -> list[str]:
|
||||
return list(dict.fromkeys(issues))
|
||||
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Regional document v1 -> v2.
|
||||
# Remove only after published/saved v1 workflows have passed the compatibility window.
|
||||
def migrate_document(document: Any) -> dict[str, Any]:
|
||||
migrated = copy.deepcopy(document)
|
||||
if not isinstance(migrated, dict) or migrated.get("schema") != "bv.regional":
|
||||
|
||||
@@ -113,6 +113,8 @@ def validate_lora_capability(payload: dict[str, Any]) -> None:
|
||||
}})
|
||||
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): LoRA capability v1 -> v2.
|
||||
# Remove together with v1 validation/registration after old workflows have migrated.
|
||||
def migrate_lora_capability_v1(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
validate_lora_capability(payload)
|
||||
collector_id = payload["collector_id"]
|
||||
@@ -127,6 +129,8 @@ def migrate_lora_capability_v1(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
return migrated
|
||||
|
||||
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): LoRA capability v2 -> v3.
|
||||
# Remove together with v2 validation/registration after old workflows have migrated.
|
||||
def migrate_lora_capability_v2(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
validate_lora_capability(payload)
|
||||
migrated = {"version": 3, "entries": payload["entries"], "scopes": {}}
|
||||
|
||||
@@ -101,6 +101,8 @@ def _feather(mask: torch.Tensor, amount: float, width: int, height: int) -> torc
|
||||
|
||||
def render_region(region: dict[str, Any], width: int, height: int) -> torch.Tensor:
|
||||
layers: dict[str, list[dict[str, Any]]] = {}
|
||||
# BV-LEGACY(marked=2026-08-25, remove-after=2026-10-25): Pre-layer geometry fallback.
|
||||
# Remove after documents without layer_id are no longer accepted by document migration.
|
||||
legacy_layer = next((shape["id"] for shape in region["geometry"] if "layer_id" not in shape), "__legacy__")
|
||||
for shape in region["geometry"]:
|
||||
layer_id = shape.get("layer_id", legacy_layer)
|
||||
|
||||
Reference in New Issue
Block a user