mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 03:01:27 -03:00
refactor(metadata): remove vestigial top-level trainedWords field
The field dates back to a development-stage bug in the enrich-metadata (agent) pipeline, which briefly wrote trigger words at the top level of model metadata instead of the established civitai.trainedWords location. The write path was fixed before the feature merged to main (PR #1013) and never shipped in any release, so no writer has existed since. Remove the leftover pieces: - BaseModelMetadata.trainedWords field (py/utils/models.py); sidecars from that dev window now pass the key through _unknown_fields instead - HF download handler's strip-empty-trainedWords special case, reverting to saving the metadata object directly (py/routes/handlers/hf_handlers.py) - trainedWords in the LLM enrichment context (agent_service.py) - matching fallbacks/fixtures in the enrich_hf_validation harness and post-processor test Trigger words continue to live in civitai.trainedWords for all model sources, which is what the UI, agent post-processor, and metadata sync all read and write.
This commit is contained in:
@@ -122,12 +122,8 @@ async def _save_hf_metadata(dest_path: str, repo: str, model_root: str) -> None:
|
|||||||
metadata._unknown_fields["hf_url"] = hf_url
|
metadata._unknown_fields["hf_url"] = hf_url
|
||||||
metadata.from_civitai = False # HF models are not from CivitAI
|
metadata.from_civitai = False # HF models are not from CivitAI
|
||||||
|
|
||||||
metadata_dict = metadata.to_dict()
|
|
||||||
if "trainedWords" in metadata_dict and not metadata_dict["trainedWords"]:
|
|
||||||
del metadata_dict["trainedWords"]
|
|
||||||
|
|
||||||
# 3. Save metadata atomically
|
# 3. Save metadata atomically
|
||||||
await MetadataManager.save_metadata(dest_path, metadata_dict)
|
await MetadataManager.save_metadata(dest_path, metadata)
|
||||||
logger.info("Saved HF metadata (with hf_url) for %s", dest_path)
|
logger.info("Saved HF metadata (with hf_url) for %s", dest_path)
|
||||||
|
|
||||||
# 4. Determine relative folder path for cache
|
# 4. Determine relative folder path for cache
|
||||||
|
|||||||
@@ -407,7 +407,6 @@ class AgentService:
|
|||||||
"base_model": metadata.get("base_model", ""),
|
"base_model": metadata.get("base_model", ""),
|
||||||
"tags": metadata.get("tags", []),
|
"tags": metadata.get("tags", []),
|
||||||
"modelDescription": metadata.get("modelDescription", ""),
|
"modelDescription": metadata.get("modelDescription", ""),
|
||||||
"trainedWords": metadata.get("trainedWords", []),
|
|
||||||
"sha256": (metadata.get("sha256") or "")[:16] + "..." if metadata.get("sha256") else "",
|
"sha256": (metadata.get("sha256") or "")[:16] + "..." if metadata.get("sha256") else "",
|
||||||
"size": metadata.get("size", 0),
|
"size": metadata.get("size", 0),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ class BaseModelMetadata:
|
|||||||
last_checked_at: float = 0 # Last checked timestamp
|
last_checked_at: float = 0 # Last checked timestamp
|
||||||
hash_status: str = "completed" # Hash calculation status: pending | calculating | completed | failed
|
hash_status: str = "completed" # Hash calculation status: pending | calculating | completed | failed
|
||||||
autov3: Optional[str] = None # CivitAI AutoV3 hash (12-char lowercase hex); "" = checked but unavailable, None = not checked
|
autov3: Optional[str] = None # CivitAI AutoV3 hash (12-char lowercase hex); "" = checked but unavailable, None = not checked
|
||||||
trainedWords: List[str] = field(
|
|
||||||
default_factory=list
|
|
||||||
) # Trigger words / activation prompts (source-agnostic)
|
|
||||||
_unknown_fields: Dict[str, Any] = field(
|
_unknown_fields: Dict[str, Any] = field(
|
||||||
default_factory=dict, repr=False, compare=False
|
default_factory=dict, repr=False, compare=False
|
||||||
) # Store unknown fields
|
) # Store unknown fields
|
||||||
@@ -92,9 +89,6 @@ class BaseModelMetadata:
|
|||||||
if self.tags is None:
|
if self.tags is None:
|
||||||
self.tags = []
|
self.tags = []
|
||||||
|
|
||||||
if self.trainedWords is None:
|
|
||||||
self.trainedWords = []
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls, data: Dict[str, Any]) -> "BaseModelMetadata":
|
def from_dict(cls, data: Dict[str, Any]) -> "BaseModelMetadata":
|
||||||
"""Create instance from dictionary"""
|
"""Create instance from dictionary"""
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ def evaluate_model(
|
|||||||
flagged issues.
|
flagged issues.
|
||||||
"""
|
"""
|
||||||
civitai = metadata.get("civitai") or {}
|
civitai = metadata.get("civitai") or {}
|
||||||
trained_words: List[str] = civitai.get("trainedWords") or metadata.get("trainedWords") or []
|
trained_words: List[str] = civitai.get("trainedWords") or []
|
||||||
short_desc: str = civitai.get("description") or ""
|
short_desc: str = civitai.get("description") or ""
|
||||||
tags: List[str] = metadata.get("tags") or []
|
tags: List[str] = metadata.get("tags") or []
|
||||||
notes: str = metadata.get("notes") or ""
|
notes: str = metadata.get("notes") or ""
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ def create_initial_metadata(
|
|||||||
"metadata_source": "",
|
"metadata_source": "",
|
||||||
"last_checked_at": 0,
|
"last_checked_at": 0,
|
||||||
"hash_status": "completed",
|
"hash_status": "completed",
|
||||||
"trainedWords": [],
|
|
||||||
"hf_url": hf_url,
|
"hf_url": hf_url,
|
||||||
"usage_tips": "{}",
|
"usage_tips": "{}",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ class TestEnrichHfMetadata:
|
|||||||
skill_name="enrich_hf_metadata",
|
skill_name="enrich_hf_metadata",
|
||||||
model_path="/p.safetensors",
|
model_path="/p.safetensors",
|
||||||
llm_output=llm,
|
llm_output=llm,
|
||||||
metadata={"trainedWords": []},
|
metadata={},
|
||||||
)
|
)
|
||||||
applied = mock_apply.call_args[0][1]
|
applied = mock_apply.call_args[0][1]
|
||||||
assert applied["civitai"]["trainedWords"] == ["trigger1", "trigger2"]
|
assert applied["civitai"]["trainedWords"] == ["trigger1", "trigger2"]
|
||||||
|
|||||||
Reference in New Issue
Block a user