Files
imi 3db87dc406 Improve autocomplete, wildcard handling, and prompt previews
- Add autocomplete caching, tag prefix indexing, and stronger usage ranking
- Add bundled merged Danbooru/e621 tag data
- Estimate max wildcard and dynamic-prompt token counts
- Store original/resolved prompt metadata and restore resolved previews
- Insert short wildcard leaf names when unambiguous
- Harden prompt preview toggles and textarea rebinding
- Expand tests for autocomplete, metadata, tokenization, and wildcards
2026-07-18 00:32:40 +02:00

86 lines
2.6 KiB
Python

"""Helpers for writing A1111 prompt metadata into ComfyUI PNG info."""
from __future__ import annotations
import json
from typing import Any, Dict, Optional
METADATA_KEY = "a1111_prompt_node"
RESOLVED_PROMPT_PROPERTY = "a1111_resolved_prompt"
RESOLVED_PROMPT_EXPANDED_PROPERTY = "a1111_resolved_prompt_expanded"
RESOLVED_PROMPT_SOURCE_PROPERTY = "a1111_resolved_prompt_source"
def _coerce_workflow(extra_pnginfo: Dict[str, Any]) -> Optional[Dict[str, Any]]:
workflow = extra_pnginfo.get("workflow")
if isinstance(workflow, dict):
return workflow
if isinstance(workflow, str):
try:
parsed = json.loads(workflow)
except json.JSONDecodeError:
return None
if isinstance(parsed, dict):
extra_pnginfo["workflow"] = parsed
return parsed
return None
def _update_workflow_preview(
extra_pnginfo: Dict[str, Any],
node_id: str,
original_prompt: str,
resolved_prompt: str,
) -> None:
workflow = _coerce_workflow(extra_pnginfo)
if workflow is None:
return
nodes = workflow.get("nodes")
if not isinstance(nodes, list):
return
for node in nodes:
if not isinstance(node, dict) or str(node.get("id")) != node_id:
continue
properties = node.setdefault("properties", {})
if not isinstance(properties, dict):
properties = {}
node["properties"] = properties
if original_prompt != resolved_prompt:
properties[RESOLVED_PROMPT_PROPERTY] = resolved_prompt
properties[RESOLVED_PROMPT_SOURCE_PROPERTY] = original_prompt
properties.setdefault(RESOLVED_PROMPT_EXPANDED_PROPERTY, False)
else:
properties.pop(RESOLVED_PROMPT_PROPERTY, None)
properties.pop(RESOLVED_PROMPT_EXPANDED_PROPERTY, None)
properties.pop(RESOLVED_PROMPT_SOURCE_PROPERTY, None)
return
def record_prompt_metadata(
extra_pnginfo: Optional[Dict[str, Any]],
node_id: Optional[str],
node_type: str,
original_prompt: str,
resolved_prompt: str,
) -> None:
"""Store original/resolved prompt text in ComfyUI's extra PNG metadata."""
if extra_pnginfo is None or node_id is None:
return
key = str(node_id)
_update_workflow_preview(extra_pnginfo, key, original_prompt, resolved_prompt)
metadata = extra_pnginfo.setdefault(METADATA_KEY, {"nodes": {}})
nodes = metadata.setdefault("nodes", {})
nodes[key] = {
"node_id": key,
"type": node_type,
"original_prompt": original_prompt,
"resolved_prompt": resolved_prompt,
"changed": original_prompt != resolved_prompt,
}