From 82b34097fbbbda51c5184d7a0fbc4f373a349a98 Mon Sep 17 00:00:00 2001 From: Will Miao Date: Mon, 7 Sep 2026 16:24:15 +0800 Subject: [PATCH] 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. --- py/routes/handlers/hf_handlers.py | 6 +----- py/services/agent/agent_service.py | 1 - py/utils/models.py | 6 ------ tests/enrich_hf_validation/evaluation_engine.py | 2 +- tests/enrich_hf_validation/metadata_constructor.py | 1 - tests/services/test_post_processor.py | 2 +- 6 files changed, 3 insertions(+), 15 deletions(-) diff --git a/py/routes/handlers/hf_handlers.py b/py/routes/handlers/hf_handlers.py index e87016a4..24a3f23e 100644 --- a/py/routes/handlers/hf_handlers.py +++ b/py/routes/handlers/hf_handlers.py @@ -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.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 - 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) # 4. Determine relative folder path for cache diff --git a/py/services/agent/agent_service.py b/py/services/agent/agent_service.py index c7d39e4f..89e792c1 100644 --- a/py/services/agent/agent_service.py +++ b/py/services/agent/agent_service.py @@ -407,7 +407,6 @@ class AgentService: "base_model": metadata.get("base_model", ""), "tags": metadata.get("tags", []), "modelDescription": metadata.get("modelDescription", ""), - "trainedWords": metadata.get("trainedWords", []), "sha256": (metadata.get("sha256") or "")[:16] + "..." if metadata.get("sha256") else "", "size": metadata.get("size", 0), } diff --git a/py/utils/models.py b/py/utils/models.py index cfe96585..8c14b626 100644 --- a/py/utils/models.py +++ b/py/utils/models.py @@ -77,9 +77,6 @@ class BaseModelMetadata: last_checked_at: float = 0 # Last checked timestamp 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 - trainedWords: List[str] = field( - default_factory=list - ) # Trigger words / activation prompts (source-agnostic) _unknown_fields: Dict[str, Any] = field( default_factory=dict, repr=False, compare=False ) # Store unknown fields @@ -92,9 +89,6 @@ class BaseModelMetadata: if self.tags is None: self.tags = [] - if self.trainedWords is None: - self.trainedWords = [] - @classmethod def from_dict(cls, data: Dict[str, Any]) -> "BaseModelMetadata": """Create instance from dictionary""" diff --git a/tests/enrich_hf_validation/evaluation_engine.py b/tests/enrich_hf_validation/evaluation_engine.py index 9f3fe153..74181e85 100644 --- a/tests/enrich_hf_validation/evaluation_engine.py +++ b/tests/enrich_hf_validation/evaluation_engine.py @@ -100,7 +100,7 @@ def evaluate_model( flagged issues. """ 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 "" tags: List[str] = metadata.get("tags") or [] notes: str = metadata.get("notes") or "" diff --git a/tests/enrich_hf_validation/metadata_constructor.py b/tests/enrich_hf_validation/metadata_constructor.py index 17ac9517..feeef367 100644 --- a/tests/enrich_hf_validation/metadata_constructor.py +++ b/tests/enrich_hf_validation/metadata_constructor.py @@ -149,7 +149,6 @@ def create_initial_metadata( "metadata_source": "", "last_checked_at": 0, "hash_status": "completed", - "trainedWords": [], "hf_url": hf_url, "usage_tips": "{}", } diff --git a/tests/services/test_post_processor.py b/tests/services/test_post_processor.py index 3779fe30..8da7a431 100644 --- a/tests/services/test_post_processor.py +++ b/tests/services/test_post_processor.py @@ -164,7 +164,7 @@ class TestEnrichHfMetadata: skill_name="enrich_hf_metadata", model_path="/p.safetensors", llm_output=llm, - metadata={"trainedWords": []}, + metadata={}, ) applied = mock_apply.call_args[0][1] assert applied["civitai"]["trainedWords"] == ["trigger1", "trigger2"]