Files
Enferlain-ComfyUI-A1111-cond/encoding/base.py
T

53 lines
1.9 KiB
Python

"""Contract between prompt orchestration and a conditioning implementation."""
import re
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass(frozen=True)
class EncoderCapabilities:
breaks: bool
scheduling: bool
normalization: bool
class PromptEncoder(ABC):
"""Return (conditioning tensor, complete metadata) without retaining state.
Implementations own tokenization, weighting, segmentation and the metadata
required by the consuming model. Nodes own parsing, caching and schedules.
"""
name: str
capabilities: EncoderCapabilities
@abstractmethod
def matches(self, clip, streams):
"""Whether the encoder/model contract supports these token streams."""
def validate_request(self, text="", *, normalization=False, scheduled=False):
if re.search(r"\bBREAK\b", text) and not self.capabilities.breaks:
raise ValueError(f"{self.name} BREAK is not supported. Use an unsplit prompt.")
if scheduled and not self.capabilities.scheduling:
raise ValueError(
f"{self.name} scheduling/alternation is not supported. Use a static prompt."
)
if normalization and not self.capabilities.normalization:
raise ValueError(
f"{self.name} normalization is not supported. Disable normalization."
)
def validate_schedule_metadata(self, metadata):
# The shared hook swaps the embedding tensor only. pooled_output is
# permitted for compatibility but stays pinned to the first prompt.
if set(metadata) - {"pooled_output"}:
raise ValueError(
"Prompt scheduling cannot swap this encoder's auxiliary "
"conditioning fields yet. Use a static prompt."
)
@abstractmethod
def encode(self, clip, text, normalization=False, debug=False):
"""Encode text after validating supported operations; preserve metadata."""