Files

185 lines
9.1 KiB
Markdown

# ComfyUI-Smart-Metadata-Reader
Language / 语言: [中文](README.md) | English
`ComfyUI-Smart-Metadata-Reader` is a Python-only ComfyUI custom node. Its main node, `Smart Metadata Reader`, works as an image loader: it lets you select or upload an image, reads the AI generation metadata already stored inside that image, and outputs the image, mask, real positive/negative prompts, and common generation settings.
## Overview
This node is not an image captioning or prompt guessing tool. It does not look at pixels and infer a prompt. It reads metadata that already exists in the image file, especially the `prompt` and `workflow` JSON saved by ComfyUI PNG outputs.
The core goal is to support complex ComfyUI workflows. The parser starts from the final selected sampler, walks backward through its `positive` and `negative` conditioning chains, and extracts the prompts and settings that actually reached the final generation step.
## What Problem It Solves
Many prompt readers can parse simple A1111 settings or basic ComfyUI images where `CLIPTextEncode.inputs.text` is a plain string. In complex workflows, that field may be a graph link to upstream string functions, cached `ShowText` nodes, translator nodes, ControlNet conditioning, detailers, or other custom node chains.
This project parses ComfyUI metadata as a graph instead of scanning every text field in the workflow.
## Difference From Regular Prompt Readers
- It selects the sampler connected to the final image output when possible.
- It resolves positive and negative prompts only from the selected sampler's conditioning chain.
- It does not scan every `text` field in the workflow.
- It does not mix ControlNet parameters such as image, strength, control_net, or model_name into the prompt.
- It does not treat Gemini / OpenAI / ChatGPT / Claude / LLM fields such as `system_instruction`, `system_prompt`, `prompt`, `instruction`, or `messages` as final prompts.
- When `ShowText|pysssss` has a `text_0` cached display result, that cached result is preferred.
- It does not filter LoRA trigger words, character tags, style tags, NSFW tags, quality tags, translated text, or user-written tags.
## Installation
From your ComfyUI installation:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/CyberShadowX/ComfyUI-Smart-Metadata-Reader.git
cd ComfyUI-Smart-Metadata-Reader
pip install -r requirements.txt
```
Restart ComfyUI after installing.
## Usage
1. Add the `Smart Metadata Reader` node in ComfyUI.
2. Select an image from the ComfyUI `input` directory, or upload one through the image widget.
3. Use the node outputs in your workflow, or inspect the text outputs directly.
## Node Options
- `parameter_index`: Selects which parameter block to use when falling back to multi-parameter A1111 / Forge metadata. Keep this at `0` for normal use.
- `prefer_cached_text`: Prefer cached outputs from nodes such as `ShowText`, which helps avoid treating Gemini / OpenAI `system_instruction` or prompt templates as final prompts. Keep this `true` for normal use.
- `include_raw_json`: Keeps the original `prompt` / `workflow` JSON in the internal parse result. Keep this `true` for normal use.
- `max_depth`: Maximum reverse graph traversal depth, used to prevent cycles. Keep this at `40` for normal use; increase it only for very complex workflows.
## Outputs
The main node outputs:
- `image`
- `mask`
- `positive`
- `negative`
- `seed`
- `steps`
- `cfg`
- `width`
- `height`
- `model_name`
- `filename`
- `setting`
`setting` is human-readable text containing filename, source, model, VAE, LoRA list, seed, steps, CFG, sampler, scheduler, size, status, confidence, and unresolved information when available.
## Supported Metadata
- ComfyUI `prompt` metadata is preferred because it is closest to the executed graph.
- ComfyUI `workflow` metadata is used for UI cache and fallback values, such as `ShowText|pysssss` display cache.
- A1111 / Forge `parameters` metadata is used as fallback when ComfyUI graph parsing cannot start.
- PNG, JPEG, and WEBP metadata are read through Pillow.
If an image was compressed, forwarded through a chat app, or processed by a hosting platform that stripped metadata, this node cannot recover the original prompt. In that case, you need a separate image captioning or prompt inference tool.
## Supported Node Types
Initial Phase 1 support includes:
- `KSampler`
- `KSamplerAdvanced`
- `SamplerCustom`
- `SamplerCustomAdvanced`
- `CLIPTextEncode`
- `CLIPTextEncodeSDXL`
- `StringFunction|pysssss`
- `ShowText|pysssss`
- `DeepTranslatorTextNode`
- `ControlNetApply`
- `ControlNetApplyAdvanced`
- `ConditioningCombine`
- `ConditioningConcat`
- `InpaintModelConditioning`
- `FaceDetailer` and common detailer passthrough patterns
- `CheckpointLoaderSimple`
- `CheckpointLoader`
- `VAELoader`
- `LoraLoader`
- `LoraLoaderModelOnly`
## Important Rules
- `positive` must come from the selected sampler's `positive` conditioning chain.
- `negative` must come from the selected sampler's `negative` conditioning chain.
- The parser does not scan every text node in the workflow.
- Unconnected Gemini, ShowText, StringFunction, PrimitiveString, note text, or old CLIPTextEncode nodes do not contaminate the result.
- ControlNet, Detailer, Inpaint, ConditioningCombine, and ConditioningConcat are treated as passthrough or branch nodes only when they are on the final conditioning chain.
- LoRA loader file names and strengths are extracted separately for settings; LoRA trigger words remain in the prompt if they entered the text chain.
- The parser does not perform content moderation, prompt optimization, or token deletion.
## LLM / ShowText Cache Notes
For Gemini / OpenAI / ChatGPT / Claude / LLM prompt-generation workflows, the plugin can only recover runtime results that were written into metadata and are on the final selected sampler/generator `positive` / `negative` chain.
Recoverable:
- `ShowText|pysssss` cache on the final chain, such as `inputs.text_0` in prompt JSON or `widgets_values[0]` on the same node id in workflow JSON.
- Recursive `SmartMetadataReader` positive / negative output results on the final chain.
- `StringFunction`, text concatenation, `ConditioningCombine`, and `ConditioningConcat` branch results on the final chain.
Not recoverable:
- Runtime LLM output that exists only inside an LLM runtime node and was not embedded into `ShowText` cache.
- `ShowText` caches from other workflow branches that are not connected to the final selected generator, even if they look like prompts.
- Gemini / OpenAI node `prompt`, `system_instruction`, `system_prompt`, `messages`, templates, or API parameters.
In these cases the node returns `PARTIAL` / unresolved. This avoids reading stale branches, fallback branches, UI-only display branches, or LLM instruction templates as final prompts.
## Verified Scenarios
Phase 1 real-world validation and regression tests cover:
- Regular ComfyUI `prompt` / `workflow` metadata.
- Comfyroll `CR Apply ControlNet` positive conditioning passthrough.
- `ShowText|pysssss` cached text.
- `StringFunction|pysssss` prompt concatenation.
- `DeepTranslatorTextNode` text source.
- A1111 / Forge `parameters` fallback.
- PNG / JPEG / WEBP metadata reading.
- UltimateSDUpscale / USDU sampler-like metadata parsing.
- Nested `SmartMetadataReader` output resolution.
- `CLIPTextEncode.text -> ShowText -> SmartMetadataReader positive/negative output`.
- JPEG EXIF `UserComment` / Civitai metadata fallback.
## Current Limitations
- Phase 1 is Python-only. In-node large text boxes and a richer SD Prompt Reader style preview UI are planned for the Phase 2 JavaScript enhancement.
- Some unknown custom conditioning nodes may return `PARTIAL` / unresolved instead of guessing.
- If a custom node did not save its generated result into metadata cache, the parser may not be able to recover it.
- If an upscaled image references its source image, such as `003.png`, and that source image is not present in a resolvable path, the parser returns `PARTIAL` / unresolved; it cannot recover runtime outputs from nowhere.
- The plugin does not globally scan all `ShowText` / `widgets_values` / `text` fields in the workflow. It only resolves the final selected sampler/generator `positive` / `negative` chain.
- Images with stripped metadata cannot provide original generation settings.
## Roadmap
- Phase 2: JS frontend enhancement to show `positive` / `negative` / `setting` text boxes inside the node.
- Phase 3: More sampler adapters, such as Efficient / Impact / custom samplers, added from real failure samples.
- Phase 4: More metadata format compatibility.
## Local Verification
Run these from the plugin directory:
```bash
python -m pytest -q
python -m compileall .
```
The `tests/` directory is for development and regression testing. Regular ComfyUI users do not need to run it manually; it is kept in the repository to prevent future custom node compatibility work from breaking existing behavior.
## Manual ComfyUI Verification
1. Restart ComfyUI.
2. Search for and add `Smart Metadata Reader`.
3. Select or upload an image with metadata.
4. Confirm the node outputs `image`, `mask`, `positive`, `negative`, and `setting`.
5. If the status is `PARTIAL`, inspect unresolved information in `setting` to identify unsupported custom nodes.