diff --git a/tests/fixtures/local-inspect/resolver-vectors.json b/tests/fixtures/local-inspect/resolver-vectors.json new file mode 100644 index 00000000..dcece2f6 --- /dev/null +++ b/tests/fixtures/local-inspect/resolver-vectors.json @@ -0,0 +1 @@ +{"vectors": [{"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "encode", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "empty-positive", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \" …\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": ""}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "feff-positive", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "no-negative", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": null, \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "absent", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "Negative input is absent", "reason_code": null, "sampler_id": "3", "state": "absent"}}, "gap": false, "name": "negative-missing-input", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "float-slot", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0.0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "bool-slot", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", true], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "int-id", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [6, 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "dangling", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"60\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "CLIPTextEncode", "id": "6"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "wrong-slot", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 3], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Cyclic prompt graph", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "cycle", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"8\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Reroute input is not uniquely identifiable", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "reroute-ambiguous", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"6\", 0], \"in\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "last wins"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "duplicate-key", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"last wins\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "nan-input", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": NaN, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": null, "id": "6"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "class-type-number", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": 1.5, \"inputs\": {\"text\": \"x\"}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": null, "id": "6"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "class-type-missing", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"inputs\": {\"text\": \"x\"}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "inputs-list", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": [\"x\"]}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "API graph is missing or malformed", "reason_code": "malformed", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "prompt-list", "records": {"prompt": "[1, 2]"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "API graph is missing or malformed", "reason_code": "malformed", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "prompt-empty", "records": {"prompt": "{}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Prompt evidence is malformed", "reason_code": "malformed", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "prompt-bom", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Prompt evidence is malformed", "reason_code": "malformed", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "huge-int", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Prompt evidence is malformed", "reason_code": "malformed", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "only-execution", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "No supported sampler pair found (saw XSampler, YGuider)", "reason_code": "no-sampler", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "no-sampler", "records": {"prompt": "{\"1\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"x\", \"clip\": [\"4\", 1]}}, \"2\": {\"class_type\": \"XSampler\", \"inputs\": {\"positive\": [\"1\", 0]}}, \"9\": {\"class_type\": \"YGuider\", \"inputs\": {\"guider\": [\"1\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "No supported sampler pair found", "reason_code": "no-sampler", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "no-sampler-plain", "records": {"prompt": "{\"1\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"x\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "sdxl-equal", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"a\", \"text_l\": \"a\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "sdxl-one", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"a\", \"text_l\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "CLIPTextEncodeSDXL", "id": "8"}, "reason": "Encoder parts have different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "sdxl-differ", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"a\", \"text_l\": \"b\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "t"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "smz-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"smZ CLIPTextEncode\", \"inputs\": {\"text\": \"t\", \"text_g\": \"g\", \"text_l\": \"g\", \"with_SDXL\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (smZ CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt is chosen at run time (smZ CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "smZ CLIPTextEncode", "id": "8"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "smz-true", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"smZ CLIPTextEncode\", \"inputs\": {\"text\": \"t\", \"text_g\": \"g\", \"text_l\": \"g\", \"with_SDXL\": true}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "smz-1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"smZ CLIPTextEncode\", \"inputs\": {\"text\": \"t\", \"text_g\": \"g\", \"text_l\": \"g\", \"with_SDXL\": 1}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (smZ CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (smZ CLIPTextEncode).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "smZ CLIPTextEncode", "id": "8"}, "reason": "Linked string node setting", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "smz-[\"9\", 0]", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"smZ CLIPTextEncode\", \"inputs\": {\"text\": \"t\", \"text_g\": \"g\", \"text_l\": \"g\", \"with_SDXL\": [\"9\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "zeroed-conditioning", "status": "resolved", "text": ""}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "zeroed", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"8\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "passthrough", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"6\", 0], \"guidance\": 3.5}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "controlnet-slot1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"ControlNetApplyAdvanced\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "combine-equal", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"6\", 0], \"conditioning_2\": [\"9\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "ConditioningCombine", "id": "8"}, "reason": "Combined conditioning has different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "combine-differ", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"6\", 0], \"conditioning_2\": [\"7\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "neg"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "select-true", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"10\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"10\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"neg\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"PrimitiveBoolean\", \"inputs\": {\"value\": true}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "neg"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "select-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"10\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"10\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"neg\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"PrimitiveBoolean\", \"inputs\": {\"value\": true}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "ambiguous", "text": null}, "positive": {"source": null, "status": "ambiguous", "text": null}}, "resolution": {"node": null, "reason": "Selector branches have different prompts", "reason_code": null, "sampler_id": "3", "state": "ambiguous"}}, "gap": false, "name": "select-[\"9\", 0]", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"10\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"9\", 0], \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"10\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"neg\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"PrimitiveBoolean\", \"inputs\": {\"value\": true}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed selector condition", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "select-1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"10\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": 1, \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"10\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"neg\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"PrimitiveBoolean\", \"inputs\": {\"value\": true}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed selector condition", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "select-\"true\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"10\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": \"true\", \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"10\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"neg\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"PrimitiveBoolean\", \"inputs\": {\"value\": true}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "select-converge", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"9\", 0], \"on_true\": [\"6\", 0], \"on_false\": [\"11\", 0]}}, \"11\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "ambiguous", "text": null}, "positive": {"source": null, "status": "ambiguous", "text": null}}, "resolution": {"node": null, "reason": "Selector branches have different prompts", "reason_code": null, "sampler_id": "3", "state": "ambiguous"}}, "gap": false, "name": "select-shared", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"12\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"9\", 0], \"on_true\": [\"6\", 0], \"on_false\": [\"7\", 0]}}, \"12\": {\"class_type\": \"Switch conditioning [Crystools]\", \"inputs\": {\"boolean\": [\"9\", 0], \"on_true\": [\"7\", 0], \"on_false\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "8"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "runtime", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptSearchList\", \"inputs\": {}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoderxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoderxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoderxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "id": "8"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "unknown-encoder", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"FancyEncoderxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\", \"inputs\": {\"text\": \"x\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": " multi\nline "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "primitive", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \" multi\\nline \"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Output slot has an incompatible type", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "string-kind-mismatch", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"x\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": " a , "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "string-concatenate", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \" a \", \"string_b\": \"\", \"delimiter\": \", \"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a b"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "text-concatenate-\"true\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \" b \", \"text_a\": \" a\", \"text_aa\": \"x\", \"text_c\": \"\", \"clean_whitespace\": \"true\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": " a b "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "text-concatenate-\"False\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \" b \", \"text_a\": \" a\", \"text_aa\": \"x\", \"text_c\": \"\", \"clean_whitespace\": \"False\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a b"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "text-concatenate-true", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \" b \", \"text_a\": \" a\", \"text_aa\": \"x\", \"text_c\": \"\", \"clean_whitespace\": true}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a b"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "text-concatenate-\"TRUE\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \" b \", \"text_a\": \" a\", \"text_aa\": \"x\", \"text_c\": \"\", \"clean_whitespace\": \"TRUE\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": " a b "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "text-concatenate-0", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \" b \", \"text_a\": \" a\", \"text_aa\": \"x\", \"text_c\": \"\", \"clean_whitespace\": 0}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "ab"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "strip-newlines-true", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\n a\\nb \\n\", \"strip_newlines\": true}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "\n a\nb \n"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "strip-newlines-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\n a\\nb \\n\", \"strip_newlines\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "strip-newlines-1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\n a\\nb \\n\", \"strip_newlines\": 1}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": " | b"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "join-multi-3-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 3, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-1-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 1, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-0-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 0, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-1001-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 1001, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (JoinStringMulti).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt is chosen at run time (JoinStringMulti).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "JoinStringMulti", "id": "8"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-2-true", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 2, \"delimiter\": \" | \", \"return_list\": true}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-2.0-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": 2.0, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed string node setting", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "join-multi-true-false", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"8\", 0], \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\", \"string_2\": \"b\", \"string_3\": \"\", \"string_4\": \"d\", \"inputcount\": true, \"delimiter\": \" | \", \"return_list\": false}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "before main"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "prompt-manager", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"main\", \"prepend_text\": \" before \", \"append_text\": \"\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "prompt-manager-null-prepend", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"main\", \"prepend_text\": null, \"append_text\": \"\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "lead,main"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "historical-PromptManagerV2-0", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \" main \", \"negative_text\": \" neg \", \"prepend_text\": \"lead,\", \"append_text\": null}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "neg"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "historical-PromptManagerV2-1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 1], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \" main \", \"negative_text\": \" neg \", \"prepend_text\": \"lead,\", \"append_text\": null}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "lead,main"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "historical-PromptManagerPositive-0", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \" main \", \"negative_text\": \" neg \", \"prepend_text\": \"lead,\", \"append_text\": null}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "main"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "historical-PromptManagerNegative-0", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerNegative\", \"inputs\": {\"text\": \" main \", \"negative_text\": \" neg \", \"prepend_text\": \"lead,\", \"append_text\": null}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blur"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-graph", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "execution", "status": "resolved", "text": "blur"}, "positive": {"source": "execution", "status": "resolved", "text": "fox executed"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blur"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution-other-node", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"99\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Execution evidence does not match recorded node inputs", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "pair-execution-mismatch", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"other\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Negative execution text must be unchanged", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "pair-execution-negative-changed", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"x\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "execution", "status": "resolved", "text": "blur"}, "positive": {"source": "execution", "status": "resolved", "text": "fox executed"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution-version-true", "records": {"comfyassets_prompt_pairs": "{\"version\": true, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "execution", "status": "resolved", "text": "blur"}, "positive": {"source": "execution", "status": "resolved", "text": "fox executed"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution-version-float", "records": {"comfyassets_prompt_pairs": "{\"version\": 1.0, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "execution", "status": "resolved", "text": "blur"}, "positive": {"source": "execution", "status": "resolved", "text": "fox executed"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution-truncated", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"truncated\": [], \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Malformed execution evidence JSON", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "pair-execution-bad-json", "records": {"comfyassets_prompt_pairs": "{nope", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Multiple distinct executions have no image anchor", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "pair-execution-two-records", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}, {\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"other\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"fox\", \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "execution", "status": "resolved", "text": "blur"}, "positive": {"source": "execution", "status": "resolved", "text": "fox executed"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "pair-execution-runtime-input", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": [\"9\", 0], \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}, \"9\": {\"class_type\": \"PromptSearchList\", \"inputs\": {}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (PromptManagerText).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (PromptManagerText).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "PromptManagerText", "id": "9"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "pair-execution-runtime-wrong-slot", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"8\": {\"records\": [{\"text\": \"fox\", \"negative_text\": \"blur\", \"positive_text\": \"fox executed\", \"negative_effective_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"8\", 0], \"negative\": [\"8\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"8\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": [\"9\", 2], \"negative_text\": \"blur\", \"prepend_text\": \"\", \"append_text\": \"\"}}, \"9\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \"x\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "custom-cfg", "records": {"prompt": "{\"3\": {\"class_type\": \"SamplerCustomAdvanced\", \"inputs\": {\"noise\": [\"20\", 0], \"guider\": [\"21\", 0], \"sampler\": [\"22\", 0], \"sigmas\": [\"23\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"21\": {\"class_type\": \"CFGGuider\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"model\": [\"4\", 0], \"cfg\": 5}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "absent", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "Guider has no negative input", "reason_code": null, "sampler_id": "3", "state": "absent"}}, "gap": false, "name": "custom-basic", "records": {"prompt": "{\"3\": {\"class_type\": \"SamplerCustomAdvanced\", \"inputs\": {\"noise\": [\"20\", 0], \"guider\": [\"21\", 0], \"sampler\": [\"22\", 0], \"sigmas\": [\"23\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"21\": {\"class_type\": \"BasicGuider\", \"inputs\": {\"conditioning\": [\"6\", 0], \"model\": [\"4\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "absent", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "Guider has no negative input", "reason_code": null, "sampler_id": "3", "state": "absent"}}, "gap": false, "name": "custom-reroute-guider", "records": {"prompt": "{\"3\": {\"class_type\": \"SamplerCustomAdvanced\", \"inputs\": {\"noise\": [\"20\", 0], \"guider\": [\"21\", 0], \"sampler\": [\"22\", 0], \"sigmas\": [\"23\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"21\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"24\", 0]}}, \"24\": {\"class_type\": \"BasicGuider\", \"inputs\": {\"conditioning\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (DualCFGGuider).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (DualCFGGuider).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "DualCFGGuider", "id": "21"}, "reason": "Unsupported guider", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "custom-unknown-guider", "records": {"prompt": "{\"3\": {\"class_type\": \"SamplerCustomAdvanced\", \"inputs\": {\"noise\": [\"20\", 0], \"guider\": [\"21\", 0], \"sampler\": [\"22\", 0], \"sigmas\": [\"23\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"21\": {\"class_type\": \"DualCFGGuider\", \"inputs\": {\"cond1\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (KSamplerPreview).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (KSamplerPreview).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "KSamplerPreview", "id": "30"}, "reason": "Unsupported latent ancestry", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "latent-stage", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"LatentUpscale\", \"inputs\": {\"samples\": [\"30\", 0]}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"30\": {\"class_type\": \"KSamplerPreview\", \"inputs\": {\"model\": [\"4\", 0], \"positive\": [\"6\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "latent-encode", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"VAEEncode\", \"inputs\": {\"pixels\": [\"31\", 0], \"vae\": [\"4\", 2]}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"31\": {\"class_type\": \"LoadImage\", \"inputs\": {\"image\": \"x.png\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Cyclic latent ancestry", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "latent-cycle", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"LatentUpscale\", \"inputs\": {\"samples\": [\"3\", 0]}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "override-ignored-\"\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0], \"wildcard\": \"\"}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "override-ignored-\"wild\"", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0], \"wildcard\": \"wild\"}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "override-ignored-[\"6\", 0]", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0], \"wildcard\": [\"6\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt exceeds inspection limits.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt exceeds inspection limits.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Resolution depth limit reached", "reason_code": "depth-limit", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "depth-limit", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"r69\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"deep\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"r0\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"6\", 0]}}, \"r1\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r0\", 0]}}, \"r2\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r1\", 0]}}, \"r3\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r2\", 0]}}, \"r4\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r3\", 0]}}, \"r5\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r4\", 0]}}, \"r6\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r5\", 0]}}, \"r7\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r6\", 0]}}, \"r8\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r7\", 0]}}, \"r9\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r8\", 0]}}, \"r10\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r9\", 0]}}, \"r11\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r10\", 0]}}, \"r12\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r11\", 0]}}, \"r13\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r12\", 0]}}, \"r14\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r13\", 0]}}, \"r15\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r14\", 0]}}, \"r16\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r15\", 0]}}, \"r17\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r16\", 0]}}, \"r18\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r17\", 0]}}, \"r19\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r18\", 0]}}, \"r20\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r19\", 0]}}, \"r21\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r20\", 0]}}, \"r22\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r21\", 0]}}, \"r23\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r22\", 0]}}, \"r24\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r23\", 0]}}, \"r25\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r24\", 0]}}, \"r26\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r25\", 0]}}, \"r27\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r26\", 0]}}, \"r28\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r27\", 0]}}, \"r29\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r28\", 0]}}, \"r30\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r29\", 0]}}, \"r31\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r30\", 0]}}, \"r32\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r31\", 0]}}, \"r33\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r32\", 0]}}, \"r34\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r33\", 0]}}, \"r35\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r34\", 0]}}, \"r36\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r35\", 0]}}, \"r37\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r36\", 0]}}, \"r38\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r37\", 0]}}, \"r39\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r38\", 0]}}, \"r40\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r39\", 0]}}, \"r41\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r40\", 0]}}, \"r42\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r41\", 0]}}, \"r43\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r42\", 0]}}, \"r44\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r43\", 0]}}, \"r45\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r44\", 0]}}, \"r46\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r45\", 0]}}, \"r47\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r46\", 0]}}, \"r48\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r47\", 0]}}, \"r49\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r48\", 0]}}, \"r50\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r49\", 0]}}, \"r51\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r50\", 0]}}, \"r52\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r51\", 0]}}, \"r53\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r52\", 0]}}, \"r54\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r53\", 0]}}, \"r55\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r54\", 0]}}, \"r56\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r55\", 0]}}, \"r57\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r56\", 0]}}, \"r58\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r57\", 0]}}, \"r59\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r58\", 0]}}, \"r60\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r59\", 0]}}, \"r61\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r60\", 0]}}, \"r62\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r61\", 0]}}, \"r63\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r62\", 0]}}, \"r64\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r63\", 0]}}, \"r65\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r64\", 0]}}, \"r66\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r65\", 0]}}, \"r67\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r66\", 0]}}, \"r68\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r67\", 0]}}, \"r69\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r68\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "deep"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "depth-near", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"r60\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"deep\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"r0\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"6\", 0]}}, \"r1\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r0\", 0]}}, \"r2\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r1\", 0]}}, \"r3\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r2\", 0]}}, \"r4\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r3\", 0]}}, \"r5\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r4\", 0]}}, \"r6\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r5\", 0]}}, \"r7\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r6\", 0]}}, \"r8\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r7\", 0]}}, \"r9\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r8\", 0]}}, \"r10\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r9\", 0]}}, \"r11\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r10\", 0]}}, \"r12\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r11\", 0]}}, \"r13\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r12\", 0]}}, \"r14\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r13\", 0]}}, \"r15\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r14\", 0]}}, \"r16\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r15\", 0]}}, \"r17\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r16\", 0]}}, \"r18\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r17\", 0]}}, \"r19\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r18\", 0]}}, \"r20\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r19\", 0]}}, \"r21\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r20\", 0]}}, \"r22\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r21\", 0]}}, \"r23\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r22\", 0]}}, \"r24\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r23\", 0]}}, \"r25\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r24\", 0]}}, \"r26\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r25\", 0]}}, \"r27\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r26\", 0]}}, \"r28\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r27\", 0]}}, \"r29\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r28\", 0]}}, \"r30\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r29\", 0]}}, \"r31\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r30\", 0]}}, \"r32\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r31\", 0]}}, \"r33\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r32\", 0]}}, \"r34\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r33\", 0]}}, \"r35\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r34\", 0]}}, \"r36\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r35\", 0]}}, \"r37\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r36\", 0]}}, \"r38\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r37\", 0]}}, \"r39\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r38\", 0]}}, \"r40\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r39\", 0]}}, \"r41\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r40\", 0]}}, \"r42\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r41\", 0]}}, \"r43\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r42\", 0]}}, \"r44\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r43\", 0]}}, \"r45\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r44\", 0]}}, \"r46\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r45\", 0]}}, \"r47\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r46\", 0]}}, \"r48\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r47\", 0]}}, \"r49\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r48\", 0]}}, \"r50\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r49\", 0]}}, \"r51\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r50\", 0]}}, \"r52\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r51\", 0]}}, \"r53\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r52\", 0]}}, \"r54\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r53\", 0]}}, \"r55\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r54\", 0]}}, \"r56\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r55\", 0]}}, \"r57\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r56\", 0]}}, \"r58\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r57\", 0]}}, \"r59\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r58\", 0]}}, \"r60\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"r59\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Saved PromptManager text was overwritten by another node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "overwritten", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"shared\", \"clip\": [\"4\", 1], \"search_text\": \"\"}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"shared\", \"clip\": [\"4\", 1]}}}", "workflow": "{\"nodes\": [{\"id\": 6, \"type\": \"PromptManager\", \"widgets_values\": [\"own text\"]}, {\"id\": 7, \"type\": \"PromptManager\", \"widgets_values\": [\"other text\"]}]}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Saved PromptManager text was overwritten by another node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "overwritten-subgraph", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"1:6\", 0], \"negative\": [\"1:7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"1:6\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"same\", \"clip\": [\"4\", 1]}}, \"1:7\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"same\"}}}", "workflow": "{\"nodes\": [{\"id\": 1, \"type\": \"sub-a\", \"widgets_values\": []}], \"definitions\": {\"subgraphs\": [{\"id\": \"sub-a\", \"nodes\": [{\"id\": 6, \"type\": \"PromptManagerFocused\", \"widgets_values\": {\"text\": \"a\"}}, {\"id\": 7, \"type\": \"PromptManagerFocused\", \"widgets_values\": [\"b\"]}]}]}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "shared"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "shared"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "overwritten-bad-workflow", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"shared\", \"clip\": [\"4\", 1], \"search_text\": \"\"}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"shared\", \"clip\": [\"4\", 1]}}}", "workflow": "{bad"}}, {"evidence": null, "gap": true, "name": "several-samplers", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}, \"9\": {\"class_type\": \"KSampler\", \"inputs\": {\"positive\": [\"6\", 0], \"negative\": [\"7\", 0]}}}"}}, {"evidence": null, "gap": true, "name": "detailer", "records": {"prompt": "{\"3\": {\"class_type\": \"FaceDetailer\", \"inputs\": {\"image\": [\"5\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"wildcard\": \"\"}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": null, "gap": true, "name": "parameters-only", "records": {"parameters": "a fox\nNegative prompt: blur\nSteps: 20, Sampler: euler"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "blurry"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "prompt-and-parameters", "records": {"parameters": "ignored", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"6\", 0], \"negative\": [\"7\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"6\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"a fox\", \"clip\": [\"4\", 1]}}, \"7\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"blurry\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "
   café\u001csnow"}}, "resolution": {"node": {"class_type": "ConditioningCombine", "id": "102"}, "reason": "Combined conditioning has different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-0", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"103\": {\"records\": [{\"text\": \"\\u001csnow \", \"negative_text\": \"\\u0085\\u2028 detailed fur\", \"prepend_text\": \"\\u732b\", \"append_text\": \"\\ud83d\\ude00\", \"positive_text\": \"snow\\u3000\", \"negative_effective_text\": \"\\u0085\\u2028 detailed fur\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"
  \", \"prepend_text\": \"\\u001c…\", \"append_text\": \"\\ncafé\\u001csnow\", \"clip\": [\"4\", 1]}}, \"103\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\u001csnow \", \"negative_text\": \"…
 detailed fur\", \"prepend_text\": \"…猫
 \", \"append_text\": \"
 😀\"}}, \"105\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"…snow\\n\", \"prepend_text\": \"\\n猫\\t\", \"negative_text\": \"snow \"}}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 0], \"conditioning_2\": [\"104\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "zeroed-conditioning", "status": "resolved", "text": ""}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "猫, snow"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-1", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \"\\u001csnow
 \", \"prepend_text\": \"
 猫
 \", \"negative_text\": \"snow \"}}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u001c café\", \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"105\", 0]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"102\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"103\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-2", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"105\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \" a, \"}}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"103\": {\"class_type\": \"TextInput\", \"inputs\": {\"text\": [\"104\", 0]}}, \"102\": {\"class_type\": \"TextInput\", \"inputs\": {\"string\": [\"103\", 0]}}, \"101\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"102\", 0], \"text_l\": \"\"}}, \"108\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\t猫\", \"clip\": [\"4\", 1]}}, \"109\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"snow\\n\"}}, \"107\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 1], \"on_true\": [\"108\", 0], \"on_false\": [\"109\", 0]}}, \"111\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"…snow\", \"text_l\": \"…snow\"}}, \"110\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"111\", 0]}}, \"106\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"107\", 0], \"on_false\": [\"110\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "café, 😀"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "café, snow\u001c \tfox
  猫"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-3", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\nsnow\\u001c\", \"string_b\": \"\\tfox\\u2028 \", \"delimiter\": \" \"}}, \"103\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"104\", 0], \"string_b\": \"\\u3000\\u732b\\u001c\", \"delimiter\": \" \"}}, \"102\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"\\ufeffcaf\\u00e9\\n\", \"negative_text\": \"caf\\u00e9\\t\"}}, \"106\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \"\\u3000\\ud83d\\ude00\\u0085\", \"prepend_text\": \"\\u001ccaf\\u00e9\\u2028 \", \"negative_text\": \"\\ufeffsnow\\u0085\"}}, \"105\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"106\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-4", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"107\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConcatenate\"}, \"105\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_a\": \"\\t\\u2028 \", \"text_b\": \"\\u2028 fox\", \"clean_whitespace\": \"false\"}}, \"106\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \"\\nsnow\\t\"}}, \"103\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_c\": [\"104\", 0], \"text_b\": [\"105\", 0], \"text_d\": [\"106\", 0], \"clean_whitespace\": \"false\"}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"\\u3000a,fox\", \"negative_text\": \"\\u2028 snow\\n\\u732b\"}}, \"110\": {\"class_type\": \"StringConstant\", \"inputs\": {\"string\": \"\\u001c \"}}, \"109\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"110\", 0], \"text_l\": [\"110\", 0]}}, \"108\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"109\", 0]}}, \"111\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \" caf\\u00e9\\u001c\"}}, \"107\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"108\", 0], \"conditioning_2\": [\"111\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "ambiguous", "text": null}, "positive": {"source": null, "status": "ambiguous", "text": null}}, "resolution": {"node": null, "reason": "Selector branches have different prompts", "reason_code": null, "sampler_id": "3", "state": "ambiguous"}}, "gap": false, "name": "fuzz-0-5", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"112\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \"\\ufeffdetailed fur\\u0085\", \"prepend_text\": \"\\t\\u732b\\u3000\", \"append_text\": \"caf\\u00e9\\ta,\"}}, \"103\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"104\", 0], \"clip\": [\"4\", 1]}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"107\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u001ccaf\\u00e9\\t\", \"clip\": [\"4\", 1]}}, \"109\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u0085detailed fur\\u2028 snow\", \"clip\": [\"4\", 1]}}, \"108\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"109\", -1], \"conditioning_2\": [\"109\", -1]}}, \"106\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"107\", 0], \"on_false\": [\"108\", 0]}}, \"111\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u001ccaf\\u00e9\\u2028 \", \"clip\": [\"4\", 1]}}, \"110\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"111\", 0]}}, \"105\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"106\", 0], \"on_false\": [\"110\", 0]}}, \"101\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 0], \"on_true\": [\"102\", 0], \"on_false\": [\"105\", 0]}}, \"113\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"\\ufeff\\u0085\", \"prepend_text\": \"\\u0085snow\\ufeff\", \"append_text\": \"\\u3000fox\\u001c\", \"clip\": [\"4\", 1]}}, \"114\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\tdetailed fur snow\"}}, \"112\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 0], \"on_true\": [\"113\", 0], \"on_false\": [\"114\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "a, 猫\t"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "…猫\u001c"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-6", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 1], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ufeff\\n\", \"negative_text\": \"\\u0085\\u732b\\u001c\", \"prepend_text\": \"\\tdetailed fur\\n\", \"append_text\": \" fox\\u2028 \"}}, \"102\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"\\u732b\\t\", \"prepend_text\": \"\\u3000a,\\u2028 \", \"append_text\": \" \\t\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "😀"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "\n猫"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-7", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 1], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"…\", \"negative_text\": \"\\n猫\", \"prepend_text\": \"…a,\", \"append_text\": \"\\u001ccafé \"}}, \"103\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"😀\"}}, \"102\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"103\", 0], \"text_l\": [\"103\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "101"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-8", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"…detailed fur
 \"}}, \"102\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \" 猫\\u001c\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "fox, snow  detailed fur café"}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-9", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"…snow\", \"string_3\": \" detailed fur café\", \"inputcount\": 3, \"delimiter\": \" \", \"return_list\": false}}, \"103\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": [\"104\", 0]}}, \"102\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": [\"103\", 0], \"strip_newlines\": false}}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"fox\", \"negative_text\": \"snow\\t\"}}, \"106\": {\"class_type\": \"TextInput\"}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"106\", 0], \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "101"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-10", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\ndetailed fur\\ufefffox\"}}, \"105\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"detailed fur\\ufeff\", \"strip_newlines\": true}}, \"104\": {\"class_type\": \"TextInput\", \"inputs\": {\"string\": [\"105\", 0]}}, \"107\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \"\\u001cfox\\u2028 \"}}, \"108\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\nsnow\\u2028 \", \"strip_newlines\": false}}, \"106\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"107\", 0], \"string_b\": [\"108\", 0], \"delimiter\": \" \"}}, \"103\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": [\"104\", 0], \"string_2\": [\"106\", 0], \"inputcount\": 2, \"delimiter\": \",\", \"return_list\": false}}, \"102\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"103\", 0], \"prepend_text\": \"\\tdetailed fur\\u3000\", \"negative_text\": \" detailed fur caf\\u00e9\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Cyclic prompt graph", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-11", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\u0085snow \", \"string_b\": \"a,\\u0085\\u732b\", \"delimiter\": \", \"}}, \"103\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"104\", 0]}}, \"102\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": [\"102\", 0]}}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \" caf\\u00e9\\nsnow\", \"negative_text\": \"\\ud83d\\ude00\\u0085\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-12", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"105\": {\"class_type\": \"PrimitiveString\"}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"103\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"104\", 0], \"clip\": [\"4\", 1]}}, \"102\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"103\", 0]}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0], \"conditioning_2\": [\"102\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-13", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"107\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\"}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\ncaf\\u00e9\\u001c\", \"clip\": [\"4\", 1]}}, \"106\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"caf\\u00e9\", \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"105\", 0], \"on_false\": [\"106\", 0]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"102\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"103\", 0]}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"110\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\tsnow\\u001ccaf\\u00e9\", \"string_b\": \"\\ufeffdetailed fur\\t\", \"delimiter\": \", \"}}, \"109\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_d\": \"\\ufeffa,\\u2028 detailed fur\", \"text_b\": \"\\u0085\\n\", \"text_c\": [\"110\", 0], \"clean_whitespace\": \"true\"}}, \"108\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": [\"109\", 0], \"prepend_text\": \"\\n\\u0085\", \"append_text\": \"\\ta,\\ufeff\", \"clip\": [\"4\", 1]}}, \"107\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"108\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-14", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\"}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"\\u001csnow\\u001c\", \"prepend_text\": \"\\tdetailed fur\\ufeff\", \"negative_text\": \"\\ndetailed fur\\u001c\"}}, \"103\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\ud83d\\ude00\\u3000\"}}, \"104\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"\\u001ca,\\u001c\", \"prepend_text\": \"\\nsnow\\ud83d\\ude00\", \"append_text\": \"\\u001ca, \", \"clip\": [\"4\", 1]}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 0], \"conditioning_2\": [\"104\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "ConditioningCombine", "id": "101"}, "reason": "Combined conditioning has different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-15", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"103\": {\"records\": [{\"text\": \"\\u2028 \\u732b\\u2028 detailed fur\", \"negative_text\": \"\\u001c\\ud83d\\ude00\\ufeff\", \"prepend_text\": \"caf\\u00e9\", \"append_text\": \"detailed fur\\ufeff\\ud83d\\ude00\", \"positive_text\": \"\\ufeffdetailed fur\\n\", \"negative_effective_text\": \"\\u001c\\ud83d\\ude00\\ufeff\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\u2028 \\u732b\\u2028 detailed fur\", \"negative_text\": \"\\u001c\\ud83d\\ude00\\ufeff\", \"prepend_text\": \"\\tcaf\\u00e9 \", \"append_text\": \"\\u3000detailed fur\\ufeff\\ud83d\\ude00\"}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 0], \"conditioning_2\": [\"103\", 0]}}, \"104\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\t\", \"clip\": [\"4\", 1]}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0], \"conditioning_2\": [\"104\", 0]}}, \"108\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\u3000fox\\u0085fox\", \"string_b\": \"\\u001c\\ud83d\\ude00\\n\\ud83d\\ude00\", \"delimiter\": \"\"}}, \"107\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"108\", 0], \"string_b\": \"\\ufeffa,\\u3000detailed fur\", \"delimiter\": \" \"}}, \"106\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": [\"107\", 0], \"prepend_text\": \"\\u3000caf\\u00e9\\ufeff\", \"append_text\": \"\\ta,\\tcaf\\u00e9\", \"clip\": [\"4\", 1]}}, \"110\": {\"class_type\": \"TextInput\", \"inputs\": {\"text\": \"\\n\\u732b\\ufeff\"}}, \"109\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"110\", 0], \"prepend_text\": \"detailed fursnow\", \"negative_text\": \"\\ta,\"}}, \"105\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 1], \"on_true\": [\"106\", 0], \"on_false\": [\"109\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (Unknown).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (Unknown).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "Unknown", "id": "104"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-16", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"Unknown\", \"inputs\": {\"string_1\": \" \", \"string_2\": \"
 detailed fur\", \"string_3\": \"\\na,\\u001cfox\", \"inputcount\": 3, \"delimiter\": \" \", \"return_list\": false}}, \"103\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"104\", 0], \"text_l\": [\"104\", 0]}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0], \"conditioning_2\": [\"102\", 0]}}, \"106\": {\"class_type\": \"StringConstant\", \"inputs\": {\"text\": \" snow…\"}}, \"105\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": [\"106\", 0], \"prepend_text\": \"a,\\u001cfox\", \"append_text\": \"\\na, a,\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "ConditioningCombine", "id": "102"}, "reason": "Combined conditioning has different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-17", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"103\": {\"records\": [{\"text\": \"\\u001c\\u0085\", \"negative_text\": \"\\nfox\\u001c\", \"prepend_text\": \"fox\\ufeff\", \"append_text\": \"\\ufefffox\", \"positive_text\": \" snow caf\\u00e9\", \"negative_effective_text\": \"\\nfox\\u001c\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"107\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\u001c\\u0085\", \"negative_text\": \"\\nfox\\u001c\", \"prepend_text\": \" fox\\ufeff\", \"append_text\": \"\\ufefffox\\u3000\"}}, \"105\": {\"class_type\": \"StringConstant\", \"inputs\": {\"string\": \"\\n\\n\\ud83d\\ude00\"}}, \"104\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": [\"105\", 0], \"prepend_text\": \"\\u0085a,\\u3000\\ud83d\\ude00\", \"negative_text\": \"\\u2028 \\u732b\\u001c\"}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 1], \"conditioning_2\": [\"104\", 0]}}, \"106\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"snow detailed fur\", \"prepend_text\": \"\\n\\u732b\\u001c\", \"negative_text\": \"detailed fur\\ud83d\\ude00\"}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0]}}, \"109\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\n\\u732b \"}}, \"110\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\na,\\ufeffcaf\\u00e9\"}}, \"108\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"109\", 0], \"on_false\": [\"110\", 0]}}, \"107\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"108\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "101"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-18", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\tdetailed fur\\t\"}}, \"102\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"\\n\\ncaf\\u00e9\", \"text_l\": \"\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a, detailed fur, café"}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "105"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-19", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"\\ncafé\", \"prepend_text\": \"a, detailed fur\", \"negative_text\": \"\\na,\\u001c\"}}, \"104\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"…猫…\", \"clip\": [\"4\", 1]}}, \"102\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 1], \"on_true\": [\"103\", 0], \"on_false\": [\"104\", 0]}}, \"101\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"102\", 0]}}, \"105\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\u001ca,\\t\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "101"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-20", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\u0085fox\\ufeff\"}}, \"102\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u0085snow\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-21", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"103\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"\\u001ccaf\\u00e9\\u0085\", \"prepend_text\": \"\\u3000detailed fur\", \"negative_text\": \"\\u001c\"}}, \"101\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"103\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"\\tcaf\\u00e9 \", \"prepend_text\": \"\\t\\u732b\", \"append_text\": \"\\tcaf\\u00e9 \", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "101"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-22", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\tfox\\u001c\"}}, \"103\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \"\\u001ccaf\\u00e9\\ufeffa,\"}}, \"102\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": [\"103\", 0], \"prepend_text\": \"\\tdetailed fur\\u0085\", \"append_text\": \"\\u3000fox\\u001c\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "\u001c😀…"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "foxfox, \u001c猫
 "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-23", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"104\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\ufefffoxfox\", \"string_b\": \"\\u001c\\u732b\\u2028 \", \"delimiter\": \", \"}}, \"102\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": [\"103\", 0], \"inputcount\": 1, \"delimiter\": \",\", \"return_list\": false}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"102\", 0], \"clip\": [\"4\", 1]}}, \"106\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\tcaf\\u00e9\\u0085\"}}, \"105\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"106\", 0]}}, \"110\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"\\u001c\\ud83d\\ude00\\u0085\"}}, \"109\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"110\", 0]}}, \"108\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": [\"109\", 0]}}, \"107\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"108\", 0], \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"105\", 0], \"on_false\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-24", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"104\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \"\\u001c\"}}, \"102\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"103\", 0], \"clip\": [\"4\", 1]}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"104\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\u001ccafé
 café\", \"negative_text\": \" detailed fur 😀\", \"prepend_text\": \"detailed fur\\u001c\", \"append_text\": \"
 a,…detailed fur\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "102"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-25", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"103\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"…\"}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\t猫…\", \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"105\", 0]}}, \"103\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"104\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-26", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\tdetailed fur \", \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"105\", 0], \"conditioning_2\": [\"105\", 0]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"106\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ncaf\\u00e9\\ufeff\", \"negative_text\": \"\\u3000detailed fur\\u001ca,\", \"prepend_text\": \"\\u0085snow\\u001cfox\", \"append_text\": \"\\u001c\\u732b\\u3000\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-27", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"105\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"a, \"}}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"103\": {\"class_type\": \"Text Concatenate\", \"inputs\": []}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"102\", 0], \"clip\": [\"4\", 1]}}, \"106\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\tdetailed fur\\u001c\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-28", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\"}, \"101\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"
 detailed fur\\t\", \"negative_text\": \" snow
 😀\", \"prepend_text\": \"\\n😀…\", \"append_text\": \"\\u001c😀
 \"}}, \"102\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \"\\tfox…\", \"prepend_text\": \" 猫\", \"negative_text\": \"café…\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-29", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 1], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"snow \", \"negative_text\": \"\\u0085\\u0085\", \"prepend_text\": \"\\u2028 a, fox\", \"append_text\": \"\\tcaf\\u00e9\"}}, \"102\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\u001cdetailed fur\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "fox…detailed fur \u001c猫 snow a,"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "a,\u001c"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-30", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"a,\\u001c\", \"text_l\": \"a,\\u001c\"}}, \"102\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"\\u001c猫 snow\", \"prepend_text\": \" fox…detailed fur\", \"append_text\": \"a,\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-31", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"\\u0085a, \", \"string_b\": \"caf\\u00e9\\u2028 \", \"delimiter\": \", \"}}, \"105\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": \"\\u0085caf\\u00e9\\u2028 \"}}, \"103\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"104\", 0], \"string_b\": [\"105\", 0], \"delimiter\": \"\"}}, \"102\": {\"class_type\": \"TextInput\", \"inputs\": {\"string\": [\"103\", 0]}}, \"101\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"\\tcaf\\u00e9\\n\", \"negative_text\": \"\\u0085fox\\ufeff\"}}, \"106\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"\\u001ca,\\t\", \"prepend_text\": \"\\u0085\\u732b\\t\", \"append_text\": \"\\ufeffa,\\t\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "foxsnow"}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "105"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-32", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"104\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_a\": \"…foxsnow\", \"clean_whitespace\": true}}, \"102\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"103\", 0], \"clip\": [\"4\", 1]}}, \"101\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"102\", 0]}}, \"105\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"detailed fur \"}}, \"104\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"105\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "fox fox 猫 café…fox …a,\t fox café\ta, snow"}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "snow, fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-33", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"103\": {\"records\": [{\"text\": \" caf\\u00e9\\u3000!\", \"negative_text\": \"\\u0085snow\\u3000\", \"prepend_text\": \"detailed fur\", \"append_text\": \"\", \"positive_text\": \"\\u001c\\ud83d\\ude00\\u2028 \", \"negative_effective_text\": \"\\u0085snow\\u3000\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \" café \", \"negative_text\": \"…snow \", \"prepend_text\": \"\\n detailed fur\", \"append_text\": \"\\n \"}}, \"105\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \"\\u001cfox…\", \"prepend_text\": \" snow
 \", \"negative_text\": \"café detailed fur\"}}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"102\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"103\", 1], \"on_false\": [\"104\", 0]}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"109\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_c\": \"…a,\\t\", \"text_d\": \"fox\\n\", \"text_a\": \"\\u001ccafé…fox\", \"clean_whitespace\": \"false\"}}, \"108\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_c\": [\"109\", 0], \"clean_whitespace\": true}}, \"107\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": [\"108\", 0], \"prepend_text\": \" fox 猫\", \"append_text\": \"…café\\ta,\"}}, \"106\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": [\"107\", 0], \"prepend_text\": \"\\tfox \", \"append_text\": \"snow \", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-34", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"111\": {\"records\": [{\"text\": \"\\nsnow\\u001c\", \"negative_text\": \"\\tdetailed fur \", \"prepend_text\": \"snow\", \"append_text\": \"\\ufeffa,\", \"positive_text\": \"\\u001c\\n\", \"negative_effective_text\": \"\\tdetailed fur \"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"105\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\nfox\\u2028 \", \"clip\": [\"4\", 1]}}, \"104\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"105\", 0]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"102\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"103\", 0]}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"109\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"\\ta,\\u2028 \", \"prepend_text\": \"\\u2028 caf\\u00e9\\u3000\", \"append_text\": \"\\u2028 \\ud83d\\ude00\\n\", \"clip\": [\"4\", 1]}}, \"110\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"\\u3000\\u2028 \", \"prepend_text\": \"\\u3000detailed fur \", \"append_text\": \"\\tcaf\\u00e9\", \"clip\": [\"4\", 1]}}, \"108\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"109\", 0], \"on_false\": [\"110\", 0]}}, \"111\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\nsnow\\u001c\", \"negative_text\": \"\\tdetailed fur \", \"prepend_text\": \"snow\\u0085\", \"append_text\": \"\\ufeffa, \"}}, \"107\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"108\", 0], \"conditioning_2\": [\"111\", 0]}}, \"106\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "\t😀\t"}, "positive": {"source": "execution", "status": "resolved", "text": "fox"}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-35", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"101\": {\"records\": [{\"text\": \"caf\\u00e9\\u2028 \", \"negative_text\": \"\\n\\u3000caf\\u00e9\", \"prepend_text\": \"caf\\u00e9\\ufeff\", \"append_text\": \"snow\", \"positive_text\": \"\\ufefffox\\ufeff\", \"negative_effective_text\": \"\\n\\u3000caf\\u00e9\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"caf\\u00e9\\u2028 \", \"negative_text\": \"\\n\\u3000caf\\u00e9\", \"prepend_text\": \"\\u3000caf\\u00e9\\ufeff\", \"append_text\": \"\\u3000snow\\u3000\"}}, \"102\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ufeff\\ud83d\\ude00\\ta,\", \"negative_text\": \"\\t\\ud83d\\ude00\\t\", \"prepend_text\": \" \\u3000\", \"append_text\": \"\\u3000snow\\u001c\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "CLIPTextEncodeSDXL", "id": "101"}, "reason": "Encoder parts have different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-36", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"café
 fox\", \"text_l\": \"
 \"}}, \"103\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\n猫\"}}, \"107\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"…\", \"clip\": [\"4\", 1]}}, \"106\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"107\", 0]}}, \"109\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \" 😀 a,\", \"clip\": [\"4\", 1]}}, \"110\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \" café\\n猫\", \"clip\": [\"4\", 1]}}, \"108\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"109\", 0], \"on_false\": [\"110\", 0]}}, \"105\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"106\", 0], \"conditioning_2\": [\"108\", 0]}}, \"111\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": \"\\tsnow \", \"prepend_text\": \"猫…\", \"negative_text\": \"…detailed fur\\u001c\"}}, \"104\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"105\", 0], \"conditioning_2\": [\"111\", 0]}}, \"102\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": true, \"on_true\": [\"103\", 0], \"on_false\": [\"104\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "…猫\t"}}, "resolution": {"node": null, "reason": "Execution evidence does not match recorded node inputs", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-37", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"104\": {\"records\": [{\"text\": \"\\ndetailed fur\\u2028 !\", \"negative_text\": \"\\na,\\u2028 \", \"prepend_text\": \"\", \"append_text\": \"detailed fur\", \"positive_text\": \" \\ud83d\\ude00\\n\", \"negative_effective_text\": \"\\na,\\u2028 \"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"104\", 1], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": null, \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \"\\u0085\\u732b\\t\", \"inputcount\": 1, \"delimiter\": \",\", \"return_list\": false}}, \"102\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"103\", 0], \"text_l\": [\"103\", 0]}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0], \"conditioning_2\": [\"102\", 0]}}, \"104\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ndetailed fur\\u2028 \", \"negative_text\": \"\\na,\\u2028 \", \"prepend_text\": \" \\u0085\", \"append_text\": \"\\ndetailed fur\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "
 fox\t猫"}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-38", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\u2028 fox\\t\\u732b\", \"clip\": [\"4\", 1]}}, \"105\": {\"class_type\": \"TextInput\", \"inputs\": {\"string\": \"\\u3000\\u732b\\u3000\"}}, \"104\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": [\"105\", 0], \"strip_newlines\": true}}, \"103\": {\"class_type\": \"StringConstant\", \"inputs\": {\"string\": [\"104\", 0]}}, \"102\": {\"class_type\": \"PromptManagerV2\"}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (Unknown).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "
 snow
 \t"}}, "resolution": {"node": {"class_type": "Unknown", "id": "105"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-39", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"\\u2028 snow\\u2028 \"}}, \"103\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"104\", 0]}}, \"102\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": [\"103\", 0], \"text_c\": \"\\ufeff\\t\", \"clean_whitespace\": \"false\"}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"102\", 0], \"clip\": [\"4\", 1]}}, \"108\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\ufeff\\u732b\\u0085\", \"strip_newlines\": false}}, \"107\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"108\", 0]}}, \"106\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": [\"107\", 0], \"prepend_text\": \"\", \"append_text\": \"\\ufeff\\u732b\\u3000\", \"clip\": [\"4\", 1]}}, \"105\": {\"class_type\": \"Unknown\", \"inputs\": {\"conditioning_1\": [\"106\", 0], \"conditioning_2\": [\"106\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Execution evidence does not match recorded node inputs", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-40", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"102\": {\"records\": [{\"text\": \"\\n\\ud83d\\ude00\\u2028 !\", \"negative_text\": \" fox\\t\", \"prepend_text\": \"caf\\u00e9\\ufeff\", \"append_text\": \"detailed fur\\ufeffdetailed fur\", \"positive_text\": \"\\u0085\\u732b\\u0085detailed fur\", \"negative_effective_text\": \" fox\\t\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"103\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\n\\ud83d\\ude00\\u2028 \", \"negative_text\": \" fox\\t\", \"prepend_text\": \"\\u0085caf\\u00e9\\ufeff\", \"append_text\": \"\\ndetailed fur\\ufeffdetailed fur\"}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"106\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"fox\", \"strip_newlines\": true}}, \"105\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"106\", 0]}}, \"104\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": [\"105\", 0]}}, \"103\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": [\"104\", 0], \"prepend_text\": \" detailed fur\\u001c\", \"negative_text\": \"\\u0085\\na,\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "101"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-41", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"snow\\tsnow\"}}, \"104\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \" detailed fur \"}}, \"103\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": [\"104\", 0], \"strip_newlines\": true}}, \"102\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": [\"103\", 0], \"prepend_text\": \"\\t\\u001c\", \"append_text\": \"
 snow \", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-42", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": \"猫\", \"prepend_text\": \"
 a,\\t\", \"append_text\": \" \\u001c\", \"clip\": [\"4\", 1]}}, \"101\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"102\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": "graph-inferred", "status": "resolved", "text": "café, detailed fur snow a, café \t😀"}, "positive": {"source": "execution", "status": "resolved", "text": "snow "}}, "resolution": {"node": null, "reason": "", "reason_code": null, "sampler_id": "3", "state": "resolved"}}, "gap": false, "name": "fuzz-0-43", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"105\": {\"records\": [{\"text\": \"\\u3000a,\\u3000\", \"negative_text\": \"snow\\u3000\", \"prepend_text\": \"caf\\u00e9detailed fur\", \"append_text\": \"fox\\u001csnow\", \"positive_text\": \"\\u0085\\u732b\\u2028 \", \"negative_effective_text\": \"snow\\u3000\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \"café…\", \"text_l\": \"café…\"}}, \"103\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"104\", 0], \"conditioning_2\": [\"104\", 0]}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"105\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \" a, \", \"negative_text\": \"snow \", \"prepend_text\": \"\\tcafédetailed fur\", \"append_text\": \"\\nfox\\u001csnow\"}}, \"101\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"102\", 0], \"on_false\": [\"105\", 1]}}, \"109\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_a\": \"\\na, \", \"text_c\": \"\\ncafé\\n\", \"clean_whitespace\": true}}, \"108\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": \" detailed fur snow\", \"string_2\": [\"109\", 0], \"string_3\": \"\\t😀…\", \"inputcount\": 3, \"delimiter\": \" \", \"return_list\": false}}, \"107\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": [\"108\", 0], \"prepend_text\": \"…café\\u001c\", \"negative_text\": \"snow…\"}}, \"106\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "absent", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "😀 😀"}}, "resolution": {"node": null, "reason": "Negative input is absent", "reason_code": null, "sampler_id": "3", "state": "absent"}}, "gap": false, "name": "fuzz-0-44", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\ud83d\\ude00 \\ud83d\\ude00\", \"clip\": [\"4\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "café\u001cdetailed fur, detailed fur"}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-45", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"106\": {\"records\": [{\"text\": \"\\u001cfox\\u3000!\", \"negative_text\": \"\\n\\ud83d\\ude00\\u0085\", \"prepend_text\": \"\\ufeff\", \"append_text\": \"a,\", \"positive_text\": \"\\ufeffdetailed fur\\ud83d\\ude00\", \"negative_effective_text\": \"\\n\\ud83d\\ude00\\u0085\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"PromptManagerV2\", \"inputs\": {\"text\": \"
 detailed fur \", \"prepend_text\": \"…café\\u001cdetailed fur\", \"negative_text\": \"\\u001cfox\"}}, \"105\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \"
 😀\"}}, \"104\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"105\", 0]}}, \"103\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": []}, \"106\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\u001cfox \", \"negative_text\": \"\\n😀…\", \"prepend_text\": \"
 \", \"append_text\": \" a,\\t\"}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 0], \"conditioning_2\": [\"106\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "CLIPTextEncodeSDXL", "id": "102"}, "reason": "Encoder parts have different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-46", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"106\": {\"records\": [{\"text\": \"\\t\\u732b\\u2028 \", \"negative_text\": \"\\u001cfox\\ufeff\", \"prepend_text\": \"fox\\u3000detailed fur\", \"append_text\": \"detailed fur\", \"positive_text\": \" fox \\u732b\", \"negative_effective_text\": \"\\u001cfox\\ufeff\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"107\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \" detailed fur\", \"prepend_text\": \"café
 \", \"append_text\": \"\\ncafé\\n\"}}, \"102\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"103\", 0], \"text_l\": \"\\t😀
 猫\"}}, \"106\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\t猫
 \", \"negative_text\": \"\\u001cfox\", \"prepend_text\": \"\\nfox detailed fur\", \"append_text\": \"\\ndetailed fur
 \"}}, \"105\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"106\", 0]}}, \"104\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"105\", 0]}}, \"101\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 1], \"on_true\": [\"102\", 0], \"on_false\": [\"104\", 0]}}, \"110\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_b\": \"fox
 \", \"text_c\": \"猫\", \"text_a\": \"\\t😀\", \"clean_whitespace\": \"false\"}}, \"109\": {\"class_type\": \"JoinStringMulti\", \"inputs\": {\"string_1\": [\"110\", 0], \"inputcount\": 1, \"delimiter\": \",\", \"return_list\": false}}, \"108\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": [\"109\", 0], \"prepend_text\": \"\\u001c😀\\t猫\", \"append_text\": \" a,\", \"clip\": [\"4\", 1]}}, \"107\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"108\", 0], \"conditioning_2\": [\"108\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "102"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-47", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \" detailed fur
 猫\"}}, \"104\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": \"\\tcafé
 \", \"prepend_text\": \"
 …😀\", \"append_text\": \"fox\\n\", \"clip\": [\"4\", 1]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"101\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 0], \"on_true\": [\"102\", 0], \"on_false\": [\"103\", 0]}}, \"105\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": \" 😀\", \"text_l\": \" 😀\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Missing or malformed graph node", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-48", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": []}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\u001cfoxcafé\"}}, \"106\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \" detailed fur \"}}, \"105\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"106\", 0]}}, \"104\": {\"class_type\": \"PromptManagerFocused\", \"inputs\": {\"text\": [\"105\", 0], \"prepend_text\": \"\\tfox
 猫\", \"append_text\": \" 猫…café\", \"clip\": [\"4\", 1]}}, \"103\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"104\", 0]}}, \"102\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"103\", 0], \"conditioning_2\": [\"103\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "café
 😀"}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "102"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-49", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"café
 😀\", \"clip\": [\"4\", 1]}}, \"102\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"a,\\t\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt is chosen at run time (PromptSearchList).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "😀"}}, "resolution": {"node": {"class_type": "PromptSearchList", "id": "105"}, "reason": "Text is decided at run time", "reason_code": "runtime-value", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-50", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"104\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"103\": {\"class_type\": \"PrimitiveString\", \"inputs\": {\"value\": \" \\t\"}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"\\u2028 \\ud83d\\ude00\\u2028 \", \"negative_text\": \"\\ufeffdetailed fur\\t\"}}, \"105\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \" caf\\u00e9\\ufeffsnow\"}}, \"104\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"105\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (ConditioningCombine).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "ConditioningCombine", "id": "101"}, "reason": "Combined conditioning has different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-51", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"105\": {\"records\": [{\"text\": \"\\ufeffcaf\\u00e9\\u2028 \", \"negative_text\": \"\\t\\u732b\\t\", \"prepend_text\": \"\\ufeff\\ud83d\\ude00\\u001cdetailed fur\", \"append_text\": \"fox\", \"positive_text\": \"\\ud83d\\ude00\\t\", \"negative_effective_text\": \"\\t\\u732b\\t\"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \"a,\\tdetailed fur\", \"prepend_text\": \"\\nfox\\n\", \"append_text\": \"fox\\u3000\\ud83d\\ude00\"}}, \"103\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \"caf\\u00e9 \", \"string_b\": [\"104\", 0], \"delimiter\": \", \"}}, \"102\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"103\", 0], \"text_l\": [\"103\", 0]}}, \"105\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ufeffcaf\\u00e9\\u2028 \", \"negative_text\": \"\\t\\u732b\\t\", \"prepend_text\": \"\\ufeff\\ud83d\\ude00\\u001cdetailed fur\", \"append_text\": \"fox\\u2028 \"}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 0], \"conditioning_2\": [\"105\", 0]}}, \"109\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": \" a,\\na,\", \"string_b\": \"\\ufeff\\u2028 \", \"delimiter\": \"\"}}, \"108\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"109\", 0]}}, \"107\": {\"class_type\": \"PrimitiveStringMultiline\", \"inputs\": {\"value\": [\"108\", 0]}}, \"106\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"107\", 0], \"text_l\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"source": "graph-inferred", "status": "resolved", "text": "fox, a,"}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "103"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-52", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"103\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\"}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \" a,\\t\", \"strip_newlines\": true}}, \"101\": {\"class_type\": \"PromptManagerPositive\", \"inputs\": {\"text\": [\"102\", 0], \"prepend_text\": \"\\tfox \", \"negative_text\": \" snow
 😀\"}}, \"103\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \" a,\"}}}"}}, {"evidence": {"prompts": {"negative": {"source": null, "status": "ambiguous", "text": null}, "positive": {"source": null, "status": "ambiguous", "text": null}}, "resolution": {"node": null, "reason": "Selector branches have different prompts", "reason_code": null, "sampler_id": "3", "state": "ambiguous"}}, "gap": false, "name": "fuzz-0-53", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"106\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\nsnow\\ufeffdetailed fur\", \"negative_text\": \"\\nfox\\u2028 \", \"prepend_text\": \"a,\", \"append_text\": \"\\ta,\\u001c\"}}, \"105\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \"\\u0085caf\\u00e9\", \"prepend_text\": \"\\ufeffcaf\\u00e9\\u3000\", \"append_text\": \"\\ufeff\\u732b\"}}, \"104\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": [\"105\", 0], \"strip_newlines\": true}}, \"103\": {\"class_type\": \"PromptManager\", \"inputs\": {\"text\": [\"104\", 0], \"prepend_text\": \"\\ufeffa,\\u0085\", \"append_text\": \"\\tdetailed fur\\u3000detailed fur\", \"clip\": [\"4\", 1]}}, \"101\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": [\"4\", 0], \"on_true\": [\"102\", 0], \"on_false\": [\"103\", 0]}}, \"109\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"\\ufeff\\u732b\\u0085\", \"negative_text\": \"\\ta,\\n\\ud83d\\ude00\", \"prepend_text\": \"\\u2028 caf\\u00e9\\u2028 \", \"append_text\": \" \\ufeffcaf\\u00e9\"}}, \"108\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"109\", 1]}}, \"111\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"\\u001cdetailed fur\\u001c\", \"strip_newlines\": false}}, \"110\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"111\", 0], \"text_l\": \"\"}}, \"107\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"108\", 0], \"conditioning_2\": [\"110\", 0]}}, \"106\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Execution evidence does not match recorded node inputs", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-54", "records": {"comfyassets_prompt_pairs": "{\"version\": 1, \"nodes\": {\"102\": {\"records\": [{\"text\": \"\\ufeffdetailed fur\\u0085!\", \"negative_text\": \"\\u3000fox \", \"prepend_text\": \"caf\\u00e9\", \"append_text\": \"\", \"positive_text\": \"\\ufeffa,\\n\", \"negative_effective_text\": \"\\u3000fox \"}]}}}", "prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"detailed fur…\", \"negative_text\": \" fox \", \"prepend_text\": \"…café\\u001c\", \"append_text\": \"
 \\u001c\"}}, \"101\": {\"class_type\": \"ConditioningCombine\", \"inputs\": {\"conditioning_1\": [\"102\", 1], \"conditioning_2\": [\"102\", 1]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "No supported sampler was found.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "No supported sampler pair found", "reason_code": "no-sampler", "sampler_id": null, "state": "unresolved"}}, "gap": false, "name": "fuzz-0-55", "records": {"prompt": "{\"3\": {\"class_type\": null, \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": \"fox \", \"strip_newlines\": false}}, \"103\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"104\", 0], \"string_b\": \"\\u3000caf\\u00e9\\u2028 \", \"delimiter\": \"\"}}, \"102\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"103\", 0]}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": [\"102\", 0], \"clip\": [\"4\", 1]}}, \"109\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {\"text\": \"\\tcaf\\u00e9\\n\\ud83d\\ude00\", \"clip\": [\"4\", 1]}}, \"108\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"109\", 0]}}, \"107\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"108\", 0]}}, \"106\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"107\", 0]}}, \"105\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"106\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt uses a node the inspector does not support (FancyEncoder).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "FancyEncoder", "id": "101"}, "reason": "Unsupported node semantics or output slot", "reason_code": "unsupported-node", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-56", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"102\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"101\": {\"class_type\": \"FancyEncoder\", \"inputs\": {\"text\": \"\\t\\u732b\"}}, \"102\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\u001csnow\\u001c\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Positive prompt is empty.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Positive prompt is empty", "reason_code": null, "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-57", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"105\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": []}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\u3000caf\\u00e9\\t\"}}, \"103\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"104\", 0]}}, \"102\": {\"class_type\": \"ConditioningZeroOut\", \"inputs\": {\"conditioning\": [\"103\", 0]}}, \"101\": {\"class_type\": \"FluxGuidance\", \"inputs\": {\"conditioning\": [\"102\", 0]}}, \"106\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\ufeffa,\\ufeff\\ud83d\\ude00\"}}, \"107\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \" a,\\ufeff\\ud83d\\ude00\"}}, \"105\": {\"class_type\": \"easy ifElse\", \"inputs\": {\"boolean\": false, \"on_true\": [\"106\", 0], \"on_false\": [\"107\", 0]}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt combines several texts (CLIPTextEncodeSDXL).", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": {"class_type": "CLIPTextEncodeSDXL", "id": "101"}, "reason": "Encoder parts have different texts", "reason_code": "composite", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-58", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"107\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"104\": {\"class_type\": \"StringConstant\", \"inputs\": {\"string\": \"😀\"}}, \"103\": {\"class_type\": \"Text Concatenate\", \"inputs\": {\"text_d\": \"
 猫\\t\", \"text_a\": \"…detailed fur
 detailed fur\", \"text_b\": [\"104\", 0], \"clean_whitespace\": true}}, \"106\": {\"class_type\": \"StringConstant\", \"inputs\": {\"string\": \"
 detailed fur \"}}, \"105\": {\"class_type\": \"StringConstantMultiline\", \"inputs\": {\"string\": [\"106\", 0], \"strip_newlines\": false}}, \"102\": {\"class_type\": \"StringConcatenate\", \"inputs\": {\"string_a\": [\"103\", 0], \"string_b\": [\"105\", 0], \"delimiter\": \" \"}}, \"101\": {\"class_type\": \"CLIPTextEncodeSDXL\", \"inputs\": {\"text_g\": [\"102\", 0], \"text_l\": \"猫\\ndetailed fur\"}}, \"107\": {\"class_type\": \"PromptManagerPair\", \"inputs\": {\"text\": \"
 猫\\n\", \"negative_text\": \"\\nsnow
 猫\", \"prepend_text\": \"
 detailed fur \", \"append_text\": \"\\u001c\"}}}"}}, {"evidence": {"prompts": {"negative": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}, "positive": {"message": "Prompt metadata in this file is malformed.", "source": null, "status": "unresolved", "text": null}}, "resolution": {"node": null, "reason": "Expected a typed graph link or text input", "reason_code": "malformed", "sampler_id": "3", "state": "unresolved"}}, "gap": false, "name": "fuzz-0-59", "records": {"prompt": "{\"3\": {\"class_type\": \"KSampler\", \"inputs\": {\"seed\": 1, \"model\": [\"4\", 0], \"positive\": [\"101\", 0], \"negative\": [\"103\", 0], \"latent_image\": [\"5\", 0]}}, \"4\": {\"class_type\": \"CheckpointLoaderSimple\", \"inputs\": {\"ckpt_name\": \"m\"}}, \"5\": {\"class_type\": \"EmptyLatentImage\", \"inputs\": {\"width\": 64}}, \"102\": {\"class_type\": \"PromptManagerText\", \"inputs\": {\"text\": \"\\nfox\\t\", \"prepend_text\": \" \\ud83d\\ude00\\u001c\", \"append_text\": \"\\u001csnow \"}}, \"101\": {\"class_type\": \"CLIPTextEncode\", \"inputs\": {}}, \"104\": {\"class_type\": \"PromptSearchList\", \"inputs\": {\"text\": \"\\ncaf\\u00e9\\u3000\"}}, \"103\": {\"class_type\": \"Reroute\", \"inputs\": {\"value\": [\"104\", 0]}}}"}}], "version": 1} diff --git a/tests/js/support/local-inspect-oracle.mjs b/tests/js/support/local-inspect-oracle.mjs index 61711ced..3a02a7ff 100644 --- a/tests/js/support/local-inspect-oracle.mjs +++ b/tests/js/support/local-inspect-oracle.mjs @@ -14,6 +14,9 @@ // the carrier rule alone, as the server selects from ffprobe's tag map. // A {records} entry (records null = an unreadable file) answers // {classified: null, result: null, metadata} for the projection alone. +// A {mode: 'resolve'} entry (PR L3) answers {evidence} or {gap: true}: resolveLocalEvidence of its +// {path}'s local read, or of its {records} texts, with the repository semantics table +// (gap: a path the port leaves to Task 9). import fs from 'node:fs'; import path from 'node:path'; import { createRequire } from 'node:module'; @@ -28,6 +31,18 @@ const web = path.join(here, '..', '..', '..', 'web', 'js', 'workspace'); const { selectVideoCarrier } = await import(moduleUrl(path.join(web, 'local-video.mjs'))); const { projectMetadata } = await import(moduleUrl(path.join(web, 'local-projection.mjs'))); const { readLocalFile, toInspectionRead } = await import(moduleUrl(path.join(web, 'local-inspection.mjs'))); +const { resolveLocalEvidence, compileSemantics, LocalResolverGap } = await import(moduleUrl(path.join(web, 'local-resolver.mjs'))); +const semantics = compileSemantics(JSON.parse(fs.readFileSync(path.join(here, '..', '..', '..', 'web', 'js', 'inspection-semantics.json'), 'utf8'))); + +/** The local evidence for one set of record texts, or {gap: true}. */ +function resolved(records) { + try { + return { evidence: resolveLocalEvidence(records, semantics) }; + } catch (error) { + if (error instanceof LocalResolverGap) return { gap: true }; + throw error; + } +} const selectionRead = (selection) => selection.status === 'complete' ? { records: selection.records, record_formats: selection.record_formats, carrierText: selection.carrierText, limited: selection.limited } : null; @@ -37,6 +52,13 @@ for await (const chunk of process.stdin) chunks.push(chunk); const output = {}; for (const entry of JSON.parse(Buffer.concat(chunks).toString('utf8'))) { const { name } = entry; + if (entry.mode === 'resolve') { + if (entry.records !== undefined) { output[name] = resolved(entry.records); continue; } + const { classification, result } = await readLocalFile(await fs.openAsBlob(entry.path), { pngMetadata }); + const read = classification === null ? null : toInspectionRead(classification, result).read; + output[name] = read === null ? { unreadable: true } : resolved(read.records); + continue; + } if (entry.records !== undefined) { const read = entry.records === null ? null : { records: entry.records, diff --git a/tests/js/workspace-local-resolver.test.js b/tests/js/workspace-local-resolver.test.js new file mode 100644 index 00000000..af43fd0e --- /dev/null +++ b/tests/js/workspace-local-resolver.test.js @@ -0,0 +1,110 @@ +// PR L3 Task 8: the server's inspection resolver in this browser. The values below are what CPython answers +// (json.loads, len, str.strip, repr, utils/prompt_inspector.inspect_prompt_evidence); the full comparison with the +// server runs in tests/test_local_inspect_parity.py through tests/js/support/local-inspect-oracle.mjs. +import test from 'node:test'; +import assert from 'node:assert/strict'; +import fs from 'node:fs'; + +const py = await import('../../web/js/workspace/py-json.mjs'); +const resolver = await import('../../web/js/workspace/local-resolver.mjs'); +const semantics = resolver.compileSemantics(JSON.parse(fs.readFileSync(new URL('../../web/js/inspection-semantics.json', import.meta.url), 'utf8'))); + +test('json.loads keeps Python value kinds and dict order', () => { + const value = py.pyJsonLoads('{"9": 1, "10": 1.0, "a": NaN, "9": [true, -0, 9007199254740993, -Infinity]}'); + assert.ok(value instanceof Map); + // A repeated key keeps its first position and takes its last value; integer-like keys keep text order. + assert.deepEqual([...value.keys()], ['9', '10', 'a']); + const [flag, zero, big, negative] = value.get('9'); + assert.equal(flag, true); assert.equal(zero, 0); assert.equal(big, 9007199254740993n); + assert.ok(negative instanceof py.PyFloat); assert.equal(negative.value, -Infinity); + assert.ok(value.get('10') instanceof py.PyFloat, '1.0 is a float, not an int'); + assert.ok(Number.isNaN(value.get('a').value)); + assert.equal(py.isInt(value.get('10')), false); + assert.equal(py.pyJsonLoads('"\\ud83d\\ude00\\ud800"'), '\u{1f600}\ud800'); + for (const bad of ['{}', '{"a":1,}', '[01]', '{"a" 1}', '"\u0001"', '"\\x"', '1 2', '-', `${'9'.repeat(4301)}`, '"\\ud800\\uzzzz"']) { + assert.throws(() => py.pyJsonLoads(bad), py.PyValueError, bad); + } + assert.equal(py.pyJsonLoads(` ${'9'.repeat(4300)}\n`), BigInt('9'.repeat(4300))); +}); + +test('str helpers measure, slice and strip as CPython', () => { + assert.equal(py.pyLen('a\u{1f600}\ud800'), 3); + assert.equal(py.pySlice('\u{1f600}\u{1f600}x', 2), '\u{1f600}\u{1f600}'); + // str.isspace() includes \x1c-\x1f and \x85 and excludes , unlike String.prototype.trim. + assert.equal(py.pyStrip('\x1c\x85 a b \x1f'), 'a b'); + assert.equal(py.pyStrip('a'), 'a'); + assert.deepEqual([1.0, 0.0001, 1e-5, 1e16, 123456789012345.6, -2.5, 1e22].map(py.pyFloatRepr), + ['1.0', '0.0001', '1e-05', '1e+16', '123456789012345.6', '-2.5', '1e+22']); + assert.deepEqual([null, true, 0, 1n, new py.PyFloat(2), '', [], new Map()].map(py.pyTruthy), [false, true, false, true, true, false, false, false]); + assert.deepEqual([1, 1n, true, new py.PyFloat(1), '1', 2].map(py.pyEqualsOne), [true, true, true, true, false, false]); +}); + +const encode = text => ({class_type: 'CLIPTextEncode', inputs: {text, clip: ['4', 1]}}); +const sampler = (extra = {}) => ({class_type: 'KSampler', inputs: {seed: 1, positive: ['6', 0], negative: ['7', 0], latent_image: ['5', 0], model: ['4', 0], ...extra}}); +const base = (nodes = {}) => ({'3': sampler(), '4': {class_type: 'CheckpointLoaderSimple', inputs: {ckpt_name: 'm.safetensors'}}, + '5': {class_type: 'EmptyLatentImage', inputs: {width: 64, height: 64, batch_size: 1}}, '6': encode('a fox'), '7': encode('blurry'), ...nodes}); + +test('a single chain resolves both roles with their sources', () => { + const evidence = resolver.resolveLocalEvidence({prompt: JSON.stringify(base())}, semantics); + assert.deepEqual(evidence, { + prompts: {positive: {status: 'resolved', text: 'a fox', source: 'graph-inferred'}, negative: {status: 'resolved', text: 'blurry', source: 'graph-inferred'}}, + resolution: {state: 'resolved', sampler_id: '3', reason: '', reason_code: null, node: null}, + }); +}); + +test('records without roles, malformed text and a missing sampler answer as the server', () => { + assert.deepEqual(resolver.resolveLocalEvidence({workflow: '{}'}, semantics).resolution, + {state: 'absent', sampler_id: null, reason: 'No parsed prompt metadata', reason_code: null, node: null}); + const malformed = resolver.resolveLocalEvidence({prompt: '{broken'}, semantics); + assert.equal(malformed.resolution.reason, 'Prompt evidence is malformed'); + assert.equal(malformed.prompts.positive.message, 'Prompt metadata in this file is malformed.'); + const none = resolver.resolveLocalEvidence({prompt: JSON.stringify({'1': encode('x'), '2': {class_type: 'MySampler', inputs: {positive: ['1', 0]}}})}, semantics); + assert.deepEqual(none.resolution, {state: 'unresolved', sampler_id: null, reason: 'No supported sampler pair found (saw MySampler)', reason_code: 'no-sampler', node: null}); + assert.equal(none.prompts.negative.message, 'No supported sampler was found.'); + assert.equal(resolver.resolveLocalEvidence({prompt: JSON.stringify(base()), parameters: 'x'}, null).resolution.reason, 'Inspection node semantics are unavailable'); +}); + +test('a float output slot is not a link, and a runtime node is named', () => { + const floatSlot = resolver.resolveLocalEvidence({prompt: JSON.stringify(base()).replace('"positive":["6",0]', '"positive":["6",0.0]')}, semantics); + assert.deepEqual(floatSlot.resolution, {state: 'unresolved', sampler_id: '3', reason: 'Expected a typed graph link or text input', reason_code: 'malformed', node: null}); + const runtime = resolver.resolveLocalEvidence({prompt: JSON.stringify(base({'6': {class_type: 'PromptSearchList', inputs: {}}}))}, semantics); + assert.deepEqual(runtime.resolution.node, {id: '6', class_type: 'PromptSearchList'}); + assert.equal(runtime.prompts.positive.message, 'Prompt is chosen at run time (PromptSearchList).'); +}); + +test('execution evidence replaces a PromptManagerPair text when it matches the node inputs', () => { + const pair = {class_type: 'PromptManagerPair', inputs: {text: 'fox', negative_text: 'blur', prepend_text: '', append_text: ''}}; + const record = {text: 'fox', negative_text: 'blur', positive_text: 'fox, executed', negative_effective_text: 'blur', prepend_text: '', append_text: ''}; + const graph = base({'3': sampler({positive: ['8', 0], negative: ['8', 1]}), '8': pair}); + const evidence = resolver.resolveLocalEvidence({prompt: JSON.stringify(graph), comfyassets_prompt_pairs: JSON.stringify({version: 1, nodes: {'8': {records: [record]}}})}, semantics); + assert.deepEqual(evidence.prompts.positive, {status: 'resolved', text: 'fox, executed', source: 'execution'}); + const stale = resolver.resolveLocalEvidence({prompt: JSON.stringify(graph), comfyassets_prompt_pairs: JSON.stringify({version: 1, nodes: {'8': {records: [{...record, text: 'other'}]}}})}, semantics); + assert.equal(stale.resolution.reason, 'Execution evidence does not match recorded node inputs'); +}); + +test('several samplers and A1111 parameters are left to Task 9', () => { + assert.throws(() => resolver.resolveLocalEvidence({prompt: JSON.stringify(base({'9': sampler()}))}, semantics), resolver.LocalResolverGap); + assert.throws(() => resolver.resolveLocalEvidence({parameters: 'a fox\nSteps: 20, Sampler: euler'}, semantics), resolver.LocalResolverGap); +}); + +test('an unusable semantics table is refused', () => { + for (const doc of [null, {schema: 2}, {schema: 1, samplers: []}]) assert.throws(() => resolver.compileSemantics(doc), resolver.SemanticsError); +}); + +// The committed server answers (tests/fixtures/local-inspect/resolver-vectors.json, written by +// `python3 -m tests.local_resolver_cases --write` and checked current by the Python suite). +test('committed server answers equal the local evidence', () => { + const {vectors} = JSON.parse(fs.readFileSync(new URL('../fixtures/local-inspect/resolver-vectors.json', import.meta.url), 'utf8')); + const canonical = value => Array.isArray(value) ? value.map(canonical) : + value !== null && typeof value === 'object' ? Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])])) : value; + let compared = 0; + for (const {name, records, gap, evidence} of vectors) { + if (gap) { + assert.throws(() => resolver.resolveLocalEvidence(records, semantics), resolver.LocalResolverGap, name); + continue; + } + assert.deepEqual(canonical(resolver.resolveLocalEvidence(records, semantics)), canonical(evidence), name); + compared++; + } + assert.ok(compared > 140, `compared ${compared}`); +}); diff --git a/tests/local_resolver_cases.py b/tests/local_resolver_cases.py new file mode 100644 index 00000000..f3cb8a57 --- /dev/null +++ b/tests/local_resolver_cases.py @@ -0,0 +1,1307 @@ +"""Record sets for the local resolver parity test (#249 local Inspect, PR L3 Task 8). + +Every case is a dict of record texts as ``read_inspection_file`` returns them +(``prompt``, ``workflow``, ``comfyassets_prompt_pairs``), so the server's +``inspect_prompt_evidence`` and the browser's ``resolveLocalEvidence`` read the +same bytes. ``golden_cases`` names one case per traced strategy, bound and +malformed shape; ``fuzz_cases`` builds coherent single-sampler graphs from the +same node vocabulary, then corrupts some of them. All content is synthetic. +``single_chain`` says, from the server's own sampler table, whether a record +set resolves without candidate selection (the Task 8 subset). +""" + +import argparse +import json +import random +from pathlib import Path + +from utils.inspection_semantics import get_semantics +from utils.prompt_inspector import inspect_prompt_evidence +from utils.prompt_pair_resolver import INSPECTION_PROFILE + +VECTORS_PATH = ( + Path(__file__).resolve().parent + / "fixtures" + / "local-inspect" + / "resolver-vectors.json" +) +# Committed record sets stay small; the large bound cases are built at test time. +MAX_VECTOR_CHARS = 20_000 +COMMITTED_FUZZ = (0, 60) + +SPACES = ["", " ", "\t", "\n", "\x1c", "\x85", " ", "", "
 "] +WORDS = ["fox", "snow", "café", "猫", "\U0001f600", "a,", "detailed fur", ""] + + +def _dump(graph, ensure_ascii=False): + return json.dumps(graph, ensure_ascii=ensure_ascii) + + +def _encode(text, name="CLIPTextEncode"): + return {"class_type": name, "inputs": {"text": text, "clip": ["4", 1]}} + + +def _graph(positive, negative, extra=None, sampler=None): + graph = { + "3": sampler + or { + "class_type": "KSampler", + "inputs": { + "seed": 1, + "model": ["4", 0], + "positive": positive, + "negative": negative, + "latent_image": ["5", 0], + }, + }, + "4": {"class_type": "CheckpointLoaderSimple", "inputs": {"ckpt_name": "m"}}, + "5": {"class_type": "EmptyLatentImage", "inputs": {"width": 64}}, + } + graph.update(extra or {}) + return graph + + +def _pair(text="fox", negative="blur", prepend="", append=""): + return { + "class_type": "PromptManagerPair", + "inputs": { + "text": text, + "negative_text": negative, + "prepend_text": prepend, + "append_text": append, + }, + } + + +def _execution(node_id, **changes): + record = { + "text": "fox", + "negative_text": "blur", + "positive_text": "fox executed", + "negative_effective_text": "blur", + "prepend_text": "", + "append_text": "", + } + record.update(changes) + return json.dumps({"version": 1, "nodes": {node_id: {"records": [record]}}}) + + +def _chain(length, start="6"): + nodes = {start: _encode("deep")} + previous = start + for index in range(length): + node_id = f"r{index}" + nodes[node_id] = {"class_type": "Reroute", "inputs": {"value": [previous, 0]}} + previous = node_id + return nodes, previous + + +def _combine_tree(levels): + """A full ConditioningCombine tree over equal encoders: many distinct visits.""" + nodes, layer = {}, [] + for index in range(2**levels): + nodes[f"e{index}"] = _encode("same") + layer.append(f"e{index}") + level = 0 + while len(layer) > 1: + nxt = [] + for index in range(0, len(layer), 2): + node_id = f"c{level}_{index}" + nodes[node_id] = { + "class_type": "ConditioningCombine", + "inputs": { + "conditioning_1": [layer[index], 0], + "conditioning_2": [layer[index + 1], 0], + }, + } + nxt.append(node_id) + layer, level = nxt, level + 1 + return nodes, layer[0] + + +def golden_cases(): + """Named record sets, one per strategy, bound and malformed shape.""" + cases = {} + + def add(name, graph=None, prompt=None, **records): + cases[name] = {"prompt": prompt if prompt is not None else _dump(graph)} + cases[name].update(records) + + neg = ["7", 0] + base = {"6": _encode("a fox"), "7": _encode("blurry")} + add("encode", _graph(["6", 0], neg, base)) + add("empty-positive", _graph(["6", 0], neg, {**base, "6": _encode(" \x85")})) + add("feff-positive", _graph(["6", 0], neg, {**base, "6": _encode("")})) + add("no-negative", _graph(["6", 0], None, base)) + add( + "negative-missing-input", + None, + prompt=_dump(_graph(["6", 0], neg, base)).replace('"negative": ["7", 0], ', ""), + ) + add( + "float-slot", + None, + prompt=_dump(_graph(["6", 0], neg, base)).replace('["6", 0]', '["6", 0.0]'), + ) + add( + "bool-slot", + None, + prompt=_dump(_graph(["6", 0], neg, base)).replace('["6", 0]', '["6", true]'), + ) + add("int-id", None, prompt=_dump(_graph([6, 0], neg, base))) + add("dangling", _graph(["60", 0], neg, base)) + add("wrong-slot", _graph(["6", 3], neg, base)) + add( + "cycle", + _graph( + ["8", 0], + neg, + {**base, "8": {"class_type": "Reroute", "inputs": {"value": ["8", 0]}}}, + ), + ) + add( + "reroute-ambiguous", + _graph( + ["8", 0], + neg, + { + **base, + "8": { + "class_type": "Reroute", + "inputs": {"value": ["6", 0], "in": ["6", 0]}, + }, + }, + ), + ) + add( + "duplicate-key", + None, + prompt=_dump(_graph(["6", 0], neg, base))[:-1] + + ', "6": ' + + _dump(_encode("last wins")) + + "}", + ) + add( + "nan-input", + None, + prompt=_dump(_graph(["6", 0], neg, base)).replace('"seed": 1', '"seed": NaN'), + ) + add( + "class-type-number", + _graph( + ["6", 0], neg, {**base, "6": {"class_type": 1.5, "inputs": {"text": "x"}}} + ), + ) + add( + "class-type-missing", + _graph(["6", 0], neg, {**base, "6": {"inputs": {"text": "x"}}}), + ) + add( + "inputs-list", + _graph( + ["6", 0], + neg, + {**base, "6": {"class_type": "CLIPTextEncode", "inputs": ["x"]}}, + ), + ) + add("prompt-list", None, prompt="[1, 2]") + add("prompt-empty", None, prompt="{}") + add("prompt-bom", None, prompt="" + _dump(_graph(["6", 0], neg, base))) + add( + "huge-int", + None, + prompt=_dump(_graph(["6", 0], neg, base)).replace( + '"seed": 1', '"seed": ' + "9" * 4301 + ), + ) + add("only-execution", None, prompt=None) + cases["only-execution"] = {"comfyassets_prompt_pairs": _execution("8")} + add( + "no-sampler", + { + "1": _encode("x"), + "2": {"class_type": "XSampler", "inputs": {"positive": ["1", 0]}}, + "9": {"class_type": "YGuider", "inputs": {"guider": ["1", 0]}}, + }, + ) + add("no-sampler-plain", {"1": _encode("x")}) + sdxl = { + "class_type": "CLIPTextEncodeSDXL", + "inputs": {"text_g": "a", "text_l": "a"}, + } + add("sdxl-equal", _graph(["8", 0], neg, {**base, "8": sdxl})) + add( + "sdxl-one", + _graph( + ["8", 0], + neg, + { + **base, + "8": { + "class_type": "CLIPTextEncodeSDXL", + "inputs": {"text_g": "a", "text_l": ""}, + }, + }, + ), + ) + add( + "sdxl-differ", + _graph( + ["8", 0], + neg, + { + **base, + "8": { + "class_type": "CLIPTextEncodeSDXL", + "inputs": {"text_g": "a", "text_l": "b"}, + }, + }, + ), + ) + for flag in (False, True, 1, ["9", 0]): + smz = { + "class_type": "smZ CLIPTextEncode", + "inputs": {"text": "t", "text_g": "g", "text_l": "g", "with_SDXL": flag}, + } + add(f"smz-{json.dumps(flag)}", _graph(["8", 0], neg, {**base, "8": smz})) + add( + "zeroed", + _graph( + ["6", 0], + ["8", 0], + { + **base, + "8": { + "class_type": "ConditioningZeroOut", + "inputs": {"conditioning": ["6", 0]}, + }, + }, + ), + ) + add( + "passthrough", + _graph( + ["8", 0], + neg, + { + **base, + "8": { + "class_type": "FluxGuidance", + "inputs": {"conditioning": ["6", 0], "guidance": 3.5}, + }, + }, + ), + ) + add( + "controlnet-slot1", + _graph( + ["8", 0], + ["8", 1], + { + **base, + "8": { + "class_type": "ControlNetApplyAdvanced", + "inputs": {"positive": ["6", 0], "negative": ["7", 0]}, + }, + }, + ), + ) + add( + "combine-equal", + _graph( + ["8", 0], + neg, + { + **base, + "9": _encode("a fox"), + "8": { + "class_type": "ConditioningCombine", + "inputs": {"conditioning_1": ["6", 0], "conditioning_2": ["9", 0]}, + }, + }, + ), + ) + add( + "combine-differ", + _graph( + ["8", 0], + neg, + { + **base, + "8": { + "class_type": "ConditioningCombine", + "inputs": {"conditioning_1": ["6", 0], "conditioning_2": ["7", 0]}, + }, + }, + ), + ) + for condition in (True, False, ["9", 0], 1, "true"): + select = { + "class_type": "easy ifElse", + "inputs": {"boolean": condition, "on_true": ["6", 0], "on_false": ["7", 0]}, + } + add( + f"select-{json.dumps(condition)}", + _graph( + ["8", 0], + ["10", 0], + { + **base, + "8": select, + "10": _encode("neg"), + "9": {"class_type": "PrimitiveBoolean", "inputs": {"value": True}}, + }, + ), + ) + same = { + "class_type": "easy ifElse", + "inputs": {"boolean": ["9", 0], "on_true": ["6", 0], "on_false": ["11", 0]}, + } + add( + "select-converge", + _graph(["8", 0], neg, {**base, "8": same, "11": _encode("a fox")}), + ) + # Two selectors on one condition: forced together, so two candidates, not four. + add( + "select-shared", + _graph( + ["8", 0], + ["12", 0], + { + **base, + "8": { + "class_type": "easy ifElse", + "inputs": { + "boolean": ["9", 0], + "on_true": ["6", 0], + "on_false": ["7", 0], + }, + }, + "12": { + "class_type": "Switch conditioning [Crystools]", + "inputs": { + "boolean": ["9", 0], + "on_true": ["7", 0], + "on_false": ["6", 0], + }, + }, + }, + ), + ) + add( + "runtime", + _graph( + ["8", 0], + neg, + {**base, "8": {"class_type": "PromptSearchList", "inputs": {}}}, + ), + ) + add( + "unknown-encoder", + _graph( + ["8", 0], + neg, + { + **base, + "8": {"class_type": "FancyEncoder" + "x" * 80, "inputs": {"text": "x"}}, + }, + ), + ) + add( + "primitive", + _graph( + ["6", 0], + neg, + { + **base, + "6": _encode(["8", 0]), + "8": { + "class_type": "PrimitiveStringMultiline", + "inputs": {"value": " multi\nline "}, + }, + }, + ), + ) + add( + "string-kind-mismatch", + _graph( + ["8", 0], + neg, + {**base, "8": {"class_type": "PrimitiveString", "inputs": {"value": "x"}}}, + ), + ) + concat = { + "class_type": "StringConcatenate", + "inputs": {"string_a": " a ", "string_b": "", "delimiter": ", "}, + } + add( + "string-concatenate", + _graph(["6", 0], neg, {**base, "6": _encode(["8", 0]), "8": concat}), + ) + for clean in ("true", "False", True, "TRUE", 0): + text_concat = { + "class_type": "Text Concatenate", + "inputs": { + "text_b": " b ", + "text_a": " a", + "text_aa": "x", + "text_c": "", + "clean_whitespace": clean, + }, + } + add( + f"text-concatenate-{json.dumps(clean)}", + _graph(["6", 0], neg, {**base, "6": _encode(["8", 0]), "8": text_concat}), + ) + for strip in (True, False, 1): + multiline = { + "class_type": "StringConstantMultiline", + "inputs": {"string": "\n a\nb \n", "strip_newlines": strip}, + } + add( + f"strip-newlines-{json.dumps(strip)}", + _graph(["6", 0], neg, {**base, "6": _encode(["8", 0]), "8": multiline}), + ) + for count, as_list in ( + (3, False), + (1, False), + (0, False), + (1001, False), + (2, True), + (2.0, False), + (True, False), + ): + join = { + "class_type": "JoinStringMulti", + "inputs": { + "string_1": "", + "string_2": "b", + "string_3": "", + "string_4": "d", + "inputcount": count, + "delimiter": " | ", + "return_list": as_list, + }, + } + add( + f"join-multi-{json.dumps(count)}-{json.dumps(as_list)}", + _graph(["6", 0], neg, {**base, "6": _encode(["8", 0]), "8": join}), + ) + manager = { + "class_type": "PromptManager", + "inputs": { + "text": "main", + "prepend_text": " before ", + "append_text": "", + "clip": ["4", 1], + }, + } + add("prompt-manager", _graph(["8", 0], neg, {**base, "8": manager})) + add( + "prompt-manager-null-prepend", + _graph( + ["8", 0], + neg, + { + **base, + "8": {**manager, "inputs": {**manager["inputs"], "prepend_text": None}}, + }, + ), + ) + for name, slot in ( + ("PromptManagerV2", 0), + ("PromptManagerV2", 1), + ("PromptManagerPositive", 0), + ("PromptManagerNegative", 0), + ): + historical = { + "class_type": name, + "inputs": { + "text": " main ", + "negative_text": " neg ", + "prepend_text": "lead,", + "append_text": None, + }, + } + add( + f"historical-{name}-{slot}", + _graph(["8", slot], neg, {**base, "8": historical}), + ) + pair_graph = _graph(["8", 0], ["8", 1], {**base, "8": _pair()}) + add("pair-graph", pair_graph) + add("pair-execution", pair_graph, comfyassets_prompt_pairs=_execution("8")) + add( + "pair-execution-other-node", + pair_graph, + comfyassets_prompt_pairs=_execution("99"), + ) + add( + "pair-execution-mismatch", + pair_graph, + comfyassets_prompt_pairs=_execution("8", text="other"), + ) + add( + "pair-execution-negative-changed", + pair_graph, + comfyassets_prompt_pairs=_execution("8", negative_effective_text="x"), + ) + add( + "pair-execution-version-true", + pair_graph, + comfyassets_prompt_pairs=_execution("8").replace( + '"version": 1', '"version": true' + ), + ) + add( + "pair-execution-version-float", + pair_graph, + comfyassets_prompt_pairs=_execution("8").replace( + '"version": 1', '"version": 1.0' + ), + ) + add( + "pair-execution-truncated", + pair_graph, + comfyassets_prompt_pairs=_execution("8").replace( + '"version": 1', '"version": 1, "truncated": []' + ), + ) + add("pair-execution-bad-json", pair_graph, comfyassets_prompt_pairs="{nope") + two = json.loads(_execution("8")) + two["nodes"]["8"]["records"].append( + dict(two["nodes"]["8"]["records"][0], positive_text="other") + ) + add( + "pair-execution-two-records", + pair_graph, + comfyassets_prompt_pairs=json.dumps(two), + ) + linked_pair = _graph( + ["8", 0], + ["8", 1], + { + **base, + "8": {**_pair(), "inputs": {**_pair()["inputs"], "text": ["9", 0]}}, + "9": {"class_type": "PromptSearchList", "inputs": {}}, + }, + ) + add( + "pair-execution-runtime-input", + linked_pair, + comfyassets_prompt_pairs=_execution("8"), + ) + add( + "pair-execution-runtime-wrong-slot", + _graph( + ["8", 0], + ["8", 1], + { + **base, + "8": {**_pair(), "inputs": {**_pair()["inputs"], "text": ["9", 2]}}, + "9": {"class_type": "PromptManagerText", "inputs": {"text": "x"}}, + }, + ), + comfyassets_prompt_pairs=_execution("8"), + ) + guided = { + "class_type": "SamplerCustomAdvanced", + "inputs": { + "noise": ["20", 0], + "guider": ["21", 0], + "sampler": ["22", 0], + "sigmas": ["23", 0], + "latent_image": ["5", 0], + }, + } + add( + "custom-cfg", + _graph( + None, + None, + { + **base, + "21": { + "class_type": "CFGGuider", + "inputs": { + "positive": ["6", 0], + "negative": ["7", 0], + "model": ["4", 0], + "cfg": 5, + }, + }, + }, + sampler=guided, + ), + ) + add( + "custom-basic", + _graph( + None, + None, + { + **base, + "21": { + "class_type": "BasicGuider", + "inputs": {"conditioning": ["6", 0], "model": ["4", 0]}, + }, + }, + sampler=guided, + ), + ) + add( + "custom-reroute-guider", + _graph( + None, + None, + { + **base, + "21": {"class_type": "Reroute", "inputs": {"value": ["24", 0]}}, + "24": { + "class_type": "BasicGuider", + "inputs": {"conditioning": ["6", 0]}, + }, + }, + sampler=guided, + ), + ) + add( + "custom-unknown-guider", + _graph( + None, + None, + { + **base, + "21": {"class_type": "DualCFGGuider", "inputs": {"cond1": ["6", 0]}}, + }, + sampler=guided, + ), + ) + add( + "latent-stage", + _graph( + ["6", 0], + neg, + { + **base, + "5": {"class_type": "LatentUpscale", "inputs": {"samples": ["30", 0]}}, + "30": { + "class_type": "KSamplerPreview", + "inputs": {"model": ["4", 0], "positive": ["6", 0]}, + }, + }, + ), + ) + add( + "latent-encode", + _graph( + ["6", 0], + neg, + { + **base, + "5": { + "class_type": "VAEEncode", + "inputs": {"pixels": ["31", 0], "vae": ["4", 2]}, + }, + "31": {"class_type": "LoadImage", "inputs": {"image": "x.png"}}, + }, + ), + ) + add( + "latent-cycle", + _graph( + ["6", 0], + neg, + { + **base, + "5": {"class_type": "LatentUpscale", "inputs": {"samples": ["3", 0]}}, + }, + ), + ) + for override in ("", "wild", ["6", 0]): + detail = { + "class_type": "KSampler", + "inputs": { + "positive": ["6", 0], + "negative": neg, + "latent_image": ["5", 0], + "wildcard": override, + }, + } + add( + f"override-ignored-{json.dumps(override)}", + _graph(None, None, base, sampler=detail), + ) + chain, end = _chain(70) + add("depth-limit", _graph([end, 0], neg, {**base, **chain})) + chain, end = _chain(61) + add("depth-near", _graph([end, 0], neg, {**base, **chain})) + tree, top = _combine_tree(11) + add("work-limit-visits", _graph([top, 0], neg, {**base, **tree})) + tree, top = _combine_tree(9) + add("diamond-memo", _graph([top, 0], [top, 0], {**base, **tree})) + add("text-limit", _graph(["6", 0], neg, {**base, "6": _encode("x" * 100_001)})) + add( + "text-at-limit", + _graph(["6", 0], neg, {**base, "6": _encode("\U0001f600" * 100_000)}), + ) + big = { + f"s{index}": { + "class_type": "PrimitiveString", + "inputs": {"value": "y" * 99_000}, + } + for index in range(20) + } + joined = { + "class_type": "JoinStringMulti", + "inputs": { + "string_1": ["s0", 0], + "inputcount": 20, + "delimiter": "", + "return_list": False, + }, + } + joined["inputs"].update( + {f"string_{index + 1}": [f"s{index}", 0] for index in range(1, 20)} + ) + add( + "join-over-length", + _graph(["6", 0], neg, {**base, **big, "6": _encode(["8", 0]), "8": joined}), + ) + concats = { + f"k{index}": { + "class_type": "StringConcatenate", + "inputs": {"string_a": "z" * 90_000, "string_b": "", "delimiter": ""}, + } + for index in range(20) + } + combine = {f"q{index}": _encode([f"k{index}", 0]) for index in range(20)} + add("built-chars", _graph(["q0", 0], ["q1", 0], {**base, **concats, **combine})) + ceiling = { + str(index): {"class_type": "Note", "inputs": {}} for index in range(100, 20_102) + } + add("graph-ceiling", _graph(["6", 0], neg, {**base, **ceiling})) + workflow = { + "nodes": [ + {"id": 6, "type": "PromptManager", "widgets_values": ["own text"]}, + {"id": 7, "type": "PromptManager", "widgets_values": ["other text"]}, + ] + } + overwritten = {**base, "6": _encode("shared"), "7": _encode("shared")} + overwritten["6"]["inputs"]["search_text"] = "" + add( + "overwritten", + _graph(["6", 0], ["7", 0], overwritten), + workflow=json.dumps(workflow), + ) + nested = { + "nodes": [{"id": 1, "type": "sub-a", "widgets_values": []}], + "definitions": { + "subgraphs": [ + { + "id": "sub-a", + "nodes": [ + { + "id": 6, + "type": "PromptManagerFocused", + "widgets_values": {"text": "a"}, + }, + { + "id": 7, + "type": "PromptManagerFocused", + "widgets_values": ["b"], + }, + ], + } + ] + }, + } + nested_graph = { + **base, + "1:6": { + "class_type": "PromptManager", + "inputs": {"text": "same", "clip": ["4", 1]}, + }, + "1:7": {"class_type": "PromptManager", "inputs": {"text": "same"}}, + } + add( + "overwritten-subgraph", + _graph(["1:6", 0], ["1:7", 0], nested_graph), + workflow=json.dumps(nested), + ) + add( + "overwritten-bad-workflow", + _graph(["6", 0], ["7", 0], overwritten), + workflow="{bad", + ) + add( + "several-samplers", + _graph( + ["6", 0], + neg, + { + **base, + "9": { + "class_type": "KSampler", + "inputs": {"positive": ["6", 0], "negative": neg}, + }, + }, + ), + ) + add( + "detailer", + _graph( + None, + None, + base, + sampler={ + "class_type": "FaceDetailer", + "inputs": { + "image": ["5", 0], + "positive": ["6", 0], + "negative": neg, + "wildcard": "", + }, + }, + ), + ) + cases["parameters-only"] = { + "parameters": "a fox\nNegative prompt: blur\nSteps: 20, Sampler: euler" + } + cases["prompt-and-parameters"] = { + "prompt": _dump(_graph(["6", 0], neg, base)), + "parameters": "ignored", + } + return cases + + +def _visits_graph(count): + """``count`` PrimitiveString links joined under one encoder (``count`` visits).""" + first, second = count // 2, count - count // 2 + nodes = { + f"p{index}": {"class_type": "PrimitiveString", "inputs": {"value": "w"}} + for index in range(count) + } + for name, start, size in (("j1", 0, first), ("j2", first, second)): + inputs = {"inputcount": max(size, 1), "delimiter": "", "return_list": False} + inputs.update( + {f"string_{index + 1}": [f"p{start + index}", 0] for index in range(size)} + ) + inputs.setdefault("string_1", "") + nodes[name] = {"class_type": "JoinStringMulti", "inputs": inputs} + nodes["k"] = { + "class_type": "StringConcatenate", + "inputs": {"string_a": ["j1", 0], "string_b": ["j2", 0], "delimiter": ""}, + } + nodes["6"] = _encode(["k", 0]) + nodes["7"] = _encode("blurry") + return {"prompt": _dump(_graph(["6", 0], ["7", 0], nodes))} + + +def _depth_graph(length): + chain, end = _chain(length) + return { + "prompt": _dump(_graph([end, 0], ["7", 0], {**chain, "7": _encode("blurry")})) + } + + +def _scan_graph(tail): + """Whitespace-only Text Concatenate parts: scanned before stripping, never built.""" + nodes, parts = {}, [] + for index in range(4): + if index < 3: + inputs = { + f"text_{letter}": " " * 99_000 for letter in "abcdefghijklmnopqrstu" + } + else: + inputs, left = {}, tail + for letter in "abcdefghijklmnopqrstu": + inputs[f"text_{letter}"] = " " * min(99_000, left) + left -= min(99_000, left) + inputs["text_z"] = "kept" if index == 0 else "" + nodes[f"t{index}"] = {"class_type": "Text Concatenate", "inputs": inputs} + parts.append([f"t{index}", 0]) + nodes["k"] = { + "class_type": "JoinStringMulti", + "inputs": { + "string_1": parts[0], + "string_2": parts[1], + "string_3": parts[2], + "string_4": parts[3], + "inputcount": 4, + "delimiter": "", + "return_list": False, + }, + } + nodes["6"] = _encode(["k", 0]) + nodes["7"] = _encode("blurry") + return {"prompt": _dump(_graph(["6", 0], ["7", 0], nodes))} + + +def _threshold(build, low, high): + """The largest parameter in [low, high) the server still resolves.""" + + def resolved(value): + evidence = inspect_prompt_evidence( + build(value), None, profile=INSPECTION_PROFILE + ) + return evidence["resolution"]["state"] == "resolved" + + assert resolved(low) and not resolved(high) + while high - low > 1: + middle = (low + high) // 2 + if resolved(middle): + low = middle + else: + high = middle + return low + + +def boundary_cases(): + """Each work bound at its edge: the last value that resolves, then the next.""" + cases = {} + for name, build, low, high in ( + ("visits", _visits_graph, 10, 2000), + ("depth", _depth_graph, 1, 80), + ("scanned", _scan_graph, 0, 2_000_000), + ): + edge = _threshold(build, low, high) + cases[f"{name}-edge"] = build(edge) + cases[f"{name}-over"] = build(edge + 1) + long_name = "\U0001f600" * 70 + cases["named-astral"] = { + "prompt": _dump( + _graph( + ["\U0001f600" * 70, 0], + ["7", 0], + { + "\U0001f600" + * 70: {"class_type": long_name, "inputs": {"text": "x"}}, + "7": _encode("b"), + }, + ) + ) + } + return cases + + +class _Builder: + """Coherent random graphs over the traced vocabulary, sometimes corrupted.""" + + def __init__(self, rng): + self.rng = rng + self.nodes = {} + self.records = {} + self.counter = 100 + + def new_id(self): + self.counter += 1 + return str(self.counter) + + def word(self): + rng = self.rng + parts = [rng.choice(SPACES), rng.choice(WORDS), rng.choice(SPACES)] + if rng.random() < 0.3: + parts.append(rng.choice(WORDS)) + return "".join(parts) + + def string(self, depth): + """A string input: a literal, or a link to a string node.""" + rng = self.rng + if depth > 3 or rng.random() < 0.45: + return self.word() + node_id, choice = self.new_id(), rng.randrange(8) + if choice == 0: + node = { + "class_type": rng.choice( + ["PrimitiveString", "PrimitiveStringMultiline"] + ), + "inputs": {"value": self.string(depth + 1)}, + } + elif choice == 1: + node = { + "class_type": "StringConcatenate", + "inputs": { + "string_a": self.string(depth + 1), + "string_b": self.string(depth + 1), + "delimiter": rng.choice(["", ", ", " "]), + }, + } + elif choice == 2: + inputs = { + f"text_{letter}": self.string(depth + 1) + for letter in rng.sample("abcd", rng.randint(1, 3)) + } + inputs["clean_whitespace"] = rng.choice(["true", "false", True]) + node = {"class_type": "Text Concatenate", "inputs": inputs} + elif choice == 3: + node = { + "class_type": "StringConstantMultiline", + "inputs": { + "string": self.string(depth + 1), + "strip_newlines": rng.choice([True, False]), + }, + } + elif choice == 4: + count = rng.randint(1, 4) + inputs = { + f"string_{index}": self.string(depth + 1) + for index in range(1, count + 1) + if index == 1 or rng.random() < 0.8 + } + inputs.update( + { + "inputcount": count, + "delimiter": rng.choice([" ", ","]), + "return_list": rng.random() < 0.1, + } + ) + node = {"class_type": "JoinStringMulti", "inputs": inputs} + elif choice == 5: + node = { + "class_type": "Reroute", + "inputs": {"value": self.string_link(depth + 1)}, + } + elif choice == 6: + node = { + "class_type": rng.choice(["StringConstant", "TextInput"]), + "inputs": {rng.choice(["string", "text"]): self.string(depth + 1)}, + } + else: + node = { + "class_type": "PromptManagerText", + "inputs": { + "text": self.string(depth + 1), + "prepend_text": self.word(), + "append_text": self.word(), + }, + } + self.nodes[node_id] = node + return [node_id, 0] + + def string_link(self, depth): + value = self.string(depth) + if isinstance(value, list): + return value + node_id = self.new_id() + self.nodes[node_id] = { + "class_type": "PrimitiveString", + "inputs": {"value": value}, + } + return [node_id, 0] + + def conditioning(self, depth): + rng = self.rng + node_id = self.new_id() + choice = rng.randrange(11) if depth < 4 else 0 + slot = 0 + if choice == 0: + node = { + "class_type": "CLIPTextEncode", + "inputs": {"text": self.string(depth + 1), "clip": ["4", 1]}, + } + elif choice == 1: + text = self.string(depth + 1) + node = { + "class_type": "CLIPTextEncodeSDXL", + "inputs": { + "text_g": text, + "text_l": ( + text if rng.random() < 0.6 else rng.choice(["", self.word()]) + ), + }, + } + elif choice == 2: + node = { + "class_type": "FluxGuidance", + "inputs": {"conditioning": self.conditioning(depth + 1)}, + } + elif choice == 3: + node = { + "class_type": "ConditioningZeroOut", + "inputs": {"conditioning": self.conditioning(depth + 1)}, + } + elif choice == 4: + first = self.conditioning(depth + 1) + node = { + "class_type": "ConditioningCombine", + "inputs": { + "conditioning_1": first, + "conditioning_2": ( + first if rng.random() < 0.5 else self.conditioning(depth + 1) + ), + }, + } + elif choice == 5: + condition = rng.choice([True, False, ["4", 0], ["4", 1]]) + node = { + "class_type": "easy ifElse", + "inputs": { + "boolean": condition, + "on_true": self.conditioning(depth + 1), + "on_false": self.conditioning(depth + 1), + }, + } + elif choice == 6: + node = { + "class_type": rng.choice(["PromptManager", "PromptManagerFocused"]), + "inputs": { + "text": self.string(depth + 1), + "prepend_text": self.word(), + "append_text": self.word(), + "clip": ["4", 1], + }, + } + elif choice == 7: + node = { + "class_type": rng.choice(["PromptManagerV2", "PromptManagerPositive"]), + "inputs": { + "text": self.string(depth + 1), + "prepend_text": self.word(), + "negative_text": self.word(), + }, + } + elif choice == 8: + slot = rng.choice([0, 1]) + texts = { + "text": self.word(), + "negative_text": self.word(), + "prepend_text": self.word(), + "append_text": self.word(), + } + node = {"class_type": "PromptManagerPair", "inputs": dict(texts)} + if rng.random() < 0.6: + record = { + **texts, + "positive_text": self.word(), + "negative_effective_text": texts["negative_text"], + } + record["prepend_text"], record["append_text"] = ( + record["prepend_text"].strip(), + record["append_text"].strip(), + ) + if rng.random() < 0.2: + record["text"] = record["text"] + "!" + self.records[EXECUTION_KEY] = json.dumps( + {"version": 1, "nodes": {node_id: {"records": [record]}}} + ) + elif choice == 9: + node = { + "class_type": "Reroute", + "inputs": {"value": self.conditioning(depth + 1)}, + } + else: + node = { + "class_type": rng.choice(["PromptSearchList", "FancyEncoder"]), + "inputs": {"text": self.word()}, + } + self.nodes[node_id] = node + return [node_id, slot] + + def corrupt(self): + rng = self.rng + node_id = rng.choice(sorted(self.nodes)) + node = self.nodes[node_id] + links = [ + key + for key, value in node.get("inputs", {}).items() + if isinstance(value, list) + ] + choice = rng.randrange(6) + if choice == 0 and links: + node["inputs"][rng.choice(links)][1] = rng.choice([0.0, True, 7, -1]) + elif choice == 1 and links: + node["inputs"][rng.choice(links)][0] = rng.choice(["missing", node_id]) + elif choice == 2: + node["class_type"] = rng.choice([None, 3, "Unknown"]) + elif choice == 3: + node["inputs"] = rng.choice([[], {}]) + elif choice == 4 and links: + del node["inputs"][rng.choice(links)] + else: + node.pop("inputs", None) + + +EXECUTION_KEY = "comfyassets_prompt_pairs" + + +def fuzz_cases(seed, count): + rng = random.Random(seed) + cases = {} + for index in range(count): + builder = _Builder(rng) + positive = builder.conditioning(0) + negative = builder.conditioning(0) if rng.random() < 0.9 else None + graph = _graph(positive, negative, builder.nodes) + if negative is None: + del graph["3"]["inputs"]["negative"] + if rng.random() < 0.25: + builder.nodes = graph + builder.corrupt() + records = {"prompt": json.dumps(graph, ensure_ascii=rng.random() < 0.5)} + records.update(builder.records) + cases[f"fuzz-{seed}-{index}"] = records + return cases + + +def single_chain(records): + """Whether the server answers ``records`` without choosing among samplers.""" + roles = {key for key in records if key in ("prompt", "parameters", EXECUTION_KEY)} + if "prompt" not in roles: + return "parameters" not in roles + try: + graph = json.loads(records["prompt"]) + except (ValueError, RecursionError): + return True + if ( + not isinstance(graph, dict) + or not graph + or len(graph) > INSPECTION_PROFILE.node_ceiling + ): + return True + samplers = get_semantics().samplers + found = [ + node["class_type"] + for node in graph.values() + if isinstance(node, dict) + and isinstance(node.get("class_type"), str) + and node["class_type"] in samplers + and samplers[node["class_type"]]["strategy"] + in ("ksampler", "custom-advanced", "detailer-stage") + ] + return len(found) <= 1 and not any( + samplers[name]["strategy"] == "detailer-stage" for name in found + ) + + +def committed_vectors(): + """The committed record sets with the server's evidence, in a stable order.""" + cases = { + name: records + for name, records in golden_cases().items() + if len(json.dumps(records)) <= MAX_VECTOR_CHARS + } + cases.update(fuzz_cases(*COMMITTED_FUZZ)) + vectors = [] + for name, records in cases.items(): + gap = not single_chain(records) + evidence = ( + None + if gap + else inspect_prompt_evidence(records, None, profile=INSPECTION_PROFILE) + ) + vectors.append( + {"name": name, "records": records, "gap": gap, "evidence": evidence} + ) + return {"version": 1, "vectors": vectors} + + +def main(): + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument("--write", action="store_true", help="rewrite the vectors") + if parser.parse_args().write: + text = json.dumps(committed_vectors(), ensure_ascii=False, sort_keys=True) + VECTORS_PATH.write_text(text + "\n", encoding="utf-8", newline="\n") + + +if __name__ == "__main__": + main() diff --git a/tests/test_local_inspect_parity.py b/tests/test_local_inspect_parity.py index 9fdfdd98..f9a0950e 100644 --- a/tests/test_local_inspect_parity.py +++ b/tests/test_local_inspect_parity.py @@ -51,12 +51,17 @@ from utils.prompt_inspector import ( read_inspection_file, ) +from utils.prompt_inspector import inspect_prompt_evidence +from utils.prompt_pair_resolver import INSPECTION_PROFILE + try: from tests import inspection_parity as parity + from tests import local_resolver_cases as resolver_cases from tests.open_handles import assert_closed from tests.test_utils_video_metadata import HAVE_FFMPEG, write_video except ImportError: # pragma: no cover - discover -s tests puts tests/ first import inspection_parity as parity + import local_resolver_cases as resolver_cases from open_handles import assert_closed from test_utils_video_metadata import HAVE_FFMPEG, write_video @@ -1111,5 +1116,168 @@ class LocalProjectionParityTests(unittest.TestCase): self.assertTrue({"parsed", "malformed", "limited"} <= seen) +def _server_evidence(records): + return inspect_prompt_evidence(records, None, profile=INSPECTION_PROFILE) + + +class LocalResolverParityTests(unittest.TestCase): + """``resolveLocalEvidence`` answers as ``inspect_prompt_evidence`` (PR L3 Task 8). + + Python is the oracle: every expected value is the server's own answer on the + same record texts. Task 8 ports one sampler's tracing; a record set whose + graph has several sampler candidates or a detailer stage, or only A1111 + ``parameters``, is a gap the port reports until Task 9, and exactly those + are gaps (``local_resolver_cases.single_chain`` decides from the server's + table). + """ + + def setUp(self): + temporary = tempfile.TemporaryDirectory() + self.addCleanup(temporary.cleanup) + self.addCleanup(assert_closed, self, temporary.name) + self.directory = Path(temporary.name) + + def _compare(self, cases): + """Assert each record set equal or a recorded gap; return the server answers.""" + observed = _run_oracle( + self, + [ + {"name": name, "mode": "resolve", "records": records} + for name, records in cases.items() + ], + ) + answers = {} + for name, records in cases.items(): + with self.subTest(case=name): + local = observed[name] + self.assertEqual( + local.get("gap", False), + not resolver_cases.single_chain(records), + "a gap is exactly a Task 9 path", + ) + if local.get("gap"): + continue + server = _server_evidence(records) + answers[name] = server + self.assertEqual( + _canonical_bytes(local["evidence"]), _canonical_bytes(server) + ) + return answers + + def test_local_roles_match_execution_and_single_chain_vectors(self): + files = {} + for name in parity.COMMITTED: + files[name] = parity.fixture_path(name) + for name in parity.TEST_TIME: + path = parity.fixture_path(name, self.directory) + parity.write_png(path, parity.build(name)) + files[name] = path + observed = _run_oracle( + self, + [ + {"name": name, "mode": "resolve", "path": str(path)} + for name, path in files.items() + ], + ) + vectors = { + vector["fixture"]: vector + for vector in json.loads(parity.VECTORS_PATH.read_text(encoding="utf-8")) + if vector["profile"] == "inspection" + } + compared = gaps = 0 + for name, path in files.items(): + with self.subTest(fixture=name): + local = observed[name] + try: + records = read_inspection_file(path).metadata + except MetadataReadError: + self.assertEqual(local, {"unreadable": True}) + continue + self.assertEqual( + local.get("gap", False), not resolver_cases.single_chain(records) + ) + if local.get("gap"): + gaps += 1 + continue + server = _server_evidence(records) + self.assertEqual( + _canonical_bytes(local["evidence"]), _canonical_bytes(server) + ) + # The committed vector agrees with the server read here. + expect = vectors[name]["expect"] + self.assertEqual(server["resolution"]["state"], expect["state"]) + self.assertEqual( + server["resolution"]["reason_code"], expect["reason_code"] + ) + compared += 1 + # f01, f09 (several samplers) and f19 (multistage detailer) wait for Task 9. + self.assertGreaterEqual(compared, 20) + self.assertGreaterEqual(gaps, 1) + + def test_local_roles_match_golden_record_sets(self): + answers = self._compare(resolver_cases.golden_cases()) + codes = {answer["resolution"]["reason_code"] for answer in answers.values()} + self.assertTrue( + { + "malformed", + "unsupported-node", + "runtime-value", + "composite", + "work-limit", + "depth-limit", + "text-limit", + "graph-ceiling", + "no-sampler", + None, + } + <= codes + ) + sources = { + side["source"] + for answer in answers.values() + for side in answer["prompts"].values() + } + self.assertTrue( + {"execution", "graph-inferred", "zeroed-conditioning"} <= sources + ) + + def test_committed_resolver_vectors_are_current(self): + """The Node unit test's committed answers are still the server's.""" + committed = json.loads(resolver_cases.VECTORS_PATH.read_text(encoding="utf-8")) + self.assertEqual( + committed, + json.loads(json.dumps(resolver_cases.committed_vectors())), + "regenerate with: python3 -m tests.local_resolver_cases --write", + ) + + def test_local_roles_match_at_every_work_bound(self): + answers = self._compare(resolver_cases.boundary_cases()) + for name in ("visits", "depth", "scanned"): + self.assertEqual(answers[f"{name}-edge"]["resolution"]["state"], "resolved") + self.assertIn( + answers[f"{name}-over"]["resolution"]["reason_code"], + ("work-limit", "depth-limit"), + ) + self.assertEqual( + answers["named-astral"]["resolution"]["node"]["class_type"], + "\U0001f600" * 64, + ) + + def test_local_roles_match_fuzzed_record_sets(self): + cases = {} + for seed in range(4): + cases.update(resolver_cases.fuzz_cases(seed, 150)) + answers = self._compare(cases) + states = [answer["resolution"]["state"] for answer in answers.values()] + # Coherent graphs reach real results, not only early refusals. + self.assertGreater(states.count("resolved"), len(states) // 5) + self.assertGreater(states.count("ambiguous"), 0) + self.assertGreater(states.count("unresolved"), len(states) // 10) + self.assertGreaterEqual( + len({answer["resolution"]["reason_code"] for answer in answers.values()}), + 5, + ) + + if __name__ == "__main__": unittest.main() diff --git a/tools/vendor/frontend-coverage-baseline.json b/tools/vendor/frontend-coverage-baseline.json index 6869e83a..db441041 100644 --- a/tools/vendor/frontend-coverage-baseline.json +++ b/tools/vendor/frontend-coverage-baseline.json @@ -181,7 +181,7 @@ }, "workspace/file-inspector.mjs": { "lines": 96, - "branches": 92, + "branches": 93, "functions": 92, "statements": 96 }, @@ -335,6 +335,18 @@ "functions": 98, "statements": 97 }, + "workspace/local-resolver-support.mjs": { + "lines": 96, + "branches": 80, + "functions": 98, + "statements": 96 + }, + "workspace/local-resolver.mjs": { + "lines": 95, + "branches": 83, + "functions": 98, + "statements": 95 + }, "workspace/local-session.mjs": { "lines": 98, "branches": 92, @@ -377,6 +389,12 @@ "functions": 98, "statements": 98 }, + "workspace/py-json.mjs": { + "lines": 97, + "branches": 91, + "functions": 98, + "statements": 97 + }, "workspace/recorded-run.mjs": { "lines": 95, "branches": 83, diff --git a/web/js/workspace/local-resolver-support.mjs b/web/js/workspace/local-resolver-support.mjs new file mode 100644 index 00000000..b9328b31 --- /dev/null +++ b/web/js/workspace/local-resolver-support.mjs @@ -0,0 +1,260 @@ +// Tables, evidence reader, bounds and outcome lines for local-resolver.mjs (#249 local Inspect, PR L3 Task 8): +// the constants of utils/prompt_pair_resolver.py and utils/inspection_outcomes.py, utils/pair_execution.py +// `read_pair_execution` and the semantics table check of utils/inspection_semantics.py. No DOM. +import { PyFloat, PyValueError, isDict, isList, isInt, pyJsonLoads, pyLen, pySlice, pyStrip, pyTruthy, pyEqualsOne, pyStr, pyGet } from './py-json.mjs'; + +/** A resolution path Task 9 ports (several samplers, a detailer stage, A1111 parameters). */ +export class LocalResolverGap extends Error { + constructor(message) { + super(message); + this.name = 'LocalResolverGap'; + } +} + +/** The semantics table is unusable: the server's `SemanticsError`. */ +export class SemanticsError extends Error { + constructor(message) { + super(message); + this.name = 'SemanticsError'; + } +} + +// INSPECTION_PROFILE (prompt_pair_resolver.py 152-166). +export const PROFILE = Object.freeze({ + perCandidateVisits: 2000, totalVisits: 20000, maxDepth: 64, maxTextLength: 100000, nodeCeiling: 20000, + maxPathEntries: 64 * 20000, maxBuiltChars: 16 * 100000, maxScannedUnits: 8000000, +}); +export const EXECUTION_KEY = 'comfyassets_prompt_pairs'; +export const ROLE_METADATA_KEYS = new Set(['prompt', 'parameters', EXECUTION_KEY]); +// pair_execution.py +export const MAX_EXECUTION_RECORDS = 16, MAX_EXECUTION_NODES = 64, MAX_EXECUTION_TEXT = 100000, MAX_EXECUTION_JSON = 500000; +export const EXECUTION_FIELDS = ['text', 'negative_text', 'positive_text', 'negative_effective_text', 'prepend_text', 'append_text']; + +export const CANDIDATE_STRATEGIES = new Set(['ksampler', 'custom-advanced', 'detailer-stage']); +export const DETAILER = 'detailer-stage'; +export const GUIDER_ABSENT_REASON = 'Guider has no negative input'; +export const ZEROED_SOURCE = 'zeroed-conditioning'; +export const MAX_BRANCH_CANDIDATES = 32; +export const RUNTIME_REASON = 'Text is decided at run time'; +export const EMPTY_POSITIVE_REASON = 'Positive prompt is empty'; +export const MULTISTAGE_UNATTRIBUTED_REASON = 'Multistage sampler ancestry is ambiguous'; +export const SEMANTICS_UNAVAILABLE_REASON = 'Inspection node semantics are unavailable'; +export const INCOMPATIBLE_SLOT = 'Output slot has an incompatible type'; +export const OVERWRITTEN_PROMPT_REASON = 'Saved PromptManager text was overwritten by another node'; +export const UNVERIFIABLE_CODES = new Set(['unsupported-node', 'runtime-value']); +export const MAX_JOIN_INPUTS = 1000; +export const SAMPLER_LIKE_INPUTS = ['latent_image', 'guider', 'positive', 'negative']; +export const NO_SAMPLER_NAMES = 3; +export const CLASS_NAME_LENGTH = 64; +export const MAX_SUBGRAPH_DEPTH = 8, MAX_WORKFLOW_NODES = 100000; + +// inspection_outcomes.py +export const OUTCOME_NAME_LENGTH = 200; +export const LIMIT_CODES = ['work-limit', 'depth-limit', 'text-limit', 'graph-ceiling']; +export const NAMED_LINES = { + 'unsupported-node': 'Prompt uses a node the inspector does not support', + 'runtime-value': 'Prompt is chosen at run time', + composite: 'Prompt combines several texts', +}; +export const CODED_LINES = { + ...Object.fromEntries(LIMIT_CODES.map(code => [code, 'Prompt exceeds inspection limits.'])), + 'no-sampler': 'No supported sampler was found.', + malformed: 'Prompt metadata in this file is malformed.', + 'multistage-differs': 'Sampler stages have different prompts.', +}; +export const UNCODED_LINES = { + [EMPTY_POSITIVE_REASON]: 'Positive prompt is empty.', + [MULTISTAGE_UNATTRIBUTED_REASON]: 'Several sampler stages were found; their prompts were not compared.', + [SEMANTICS_UNAVAILABLE_REASON]: "The inspector's node table is unavailable.", + 'Media metadata could not be read': 'Metadata in this file could not be read.', +}; + +// Output adapters (prompt_pair_resolver.py 44-105): [inputName, kind, {compose, storageInput, comma, strip, default}]. +export const adapter = (inputName, kind, options = {}) => Object.freeze({ inputName, kind, compose: false, storageInput: false, comma: false, strip: false, default: null, ...options }); +export const slotKey = (name, slot) => `${name}\u0000${String(slot)}`; +export const ADAPTERS = new Map(); +for (const name of ['PromptManager', 'PromptManagerFocused', 'PromptManagerSplit']) { + ADAPTERS.set(slotKey(name, 0), adapter('text', 'conditioning', { compose: true })); + ADAPTERS.set(slotKey(name, 1), adapter('text', 'string', { compose: true })); +} +ADAPTERS.set(slotKey('PromptManagerPair', 0), adapter('text', 'conditioning', { compose: true })); +ADAPTERS.set(slotKey('PromptManagerPair', 2), adapter('text', 'string', { compose: true })); +ADAPTERS.set(slotKey('PromptManagerPair', 1), adapter('negative_text', 'conditioning', { storageInput: true })); +ADAPTERS.set(slotKey('PromptManagerPair', 3), adapter('negative_text', 'string', { storageInput: true })); +ADAPTERS.set(slotKey('PromptManagerText', 0), adapter('text', 'string', { compose: true })); +ADAPTERS.set(slotKey('CLIPTextEncode', 0), adapter('text', 'conditioning')); +for (const name of ['PrimitiveString', 'PrimitiveStringMultiline']) ADAPTERS.set(slotKey(name, 0), adapter('value', 'string')); +for (const name of ['Text Multiline', 'String Literal', 'ShowText|pysssss']) ADAPTERS.set(slotKey(name, 0), adapter('text', 'string')); +// Historical PromptManager classes (inspection only). +export const COMMA = { comma: true }, NEGATIVE = { strip: true, default: '' }; +const historical = [ + ['PromptManagerV2', 0, 'text', 'conditioning', COMMA], ['PromptManagerV2', 1, 'negative_text', 'conditioning', NEGATIVE], + ['PromptManagerV2', 2, 'text', 'string', COMMA], ['PromptManagerV2', 3, 'negative_text', 'string', NEGATIVE], + ['PromptManagerV2Text', 0, 'text', 'string', COMMA], ['PromptManagerV2Text', 1, 'negative_text', 'string', NEGATIVE], + ['PromptManagerNegative', 0, 'text', 'conditioning', { strip: true }], ['PromptManagerNegative', 1, 'text', 'string', { strip: true }], + ['PromptManagerPositiveText', 0, 'text', 'string', COMMA], ['PromptManagerNegativeText', 0, 'text', 'string', COMMA], +]; +for (const name of ['PromptManagerPositive', 'PromptManagerDetailer']) historical.push([name, 0, 'text', 'conditioning', COMMA], [name, 1, 'text', 'string', COMMA]); +for (const [name, slot, input, kind, options] of historical) ADAPTERS.set(slotKey(name, slot), adapter(input, kind, options)); +// `known_slots` in execution_record: every adapter slot per class. +export const ADAPTER_SLOTS = new Map(); +for (const key of ADAPTERS.keys()) { + const [name, slot] = key.split('\u0000'); + if (!ADAPTER_SLOTS.has(name)) ADAPTER_SLOTS.set(name, new Set()); + ADAPTER_SLOTS.get(name).add(slot); +} + +export class Unresolved extends Error { + constructor(message, code = null, node = null) { + super(message); + this.code = code; + this.node = node; + } +} +export class Diverging extends Error { + constructor(key) { + super('diverging'); + this.key = key; + } +} + +/** `_link`: a two-item list of (str or int) and a non-negative int, never a bool. */ +export function isLink(value) { + if (!isList(value) || value.length !== 2) return false; + const [source, slot] = value; + return (typeof source === 'string' || isInt(source)) && isInt(slot) && (typeof slot === 'bigint' ? slot >= 0n : slot >= 0); +} +export const nodeRef = (nodeId, classType) => ({ id: pySlice(nodeId, CLASS_NAME_LENGTH), class_type: typeof classType === 'string' ? pySlice(classType, CLASS_NAME_LENGTH) : null }); + +export function result(state, { positive = null, negative = null, samplerId = null, reason = '', candidates = [], reasonCode = null, node = null } = {}) { + return { state, positive, negative, sampler_id: samplerId, reason, candidates, reason_code: reasonCode, node }; +} + +export class Budget { + constructor(total) { + this.total = total; + this.allowance = total; + } + reset(allowance) { this.allowance = allowance; } + spend() { + if (this.total <= 0 || this.allowance <= 0) throw new Unresolved('Resolution visit limit reached', 'work-limit'); + this.total -= 1; + this.allowance -= 1; + } + charge(cost) { + if (cost > this.allowance) throw new Unresolved('Resolution visit limit reached', 'work-limit'); + this.allowance -= cost; + } +} + +/** `read_pair_execution`: one distinct record for a traced node, or null; malformed evidence throws `Unresolved`. */ +export function readPairExecution(metadata, nodeId) { + const evidence = message => new Unresolved(message, 'malformed'); + if (!isDict(metadata) || !metadata.has(EXECUTION_KEY)) return null; + let envelope = metadata.get(EXECUTION_KEY); + if (typeof envelope === 'string') { + if (pyLen(envelope) > MAX_EXECUTION_JSON) throw evidence('Execution evidence exceeds the size limit'); + try { envelope = pyJsonLoads(envelope); } catch (error) { + if (error instanceof PyValueError) throw evidence('Malformed execution evidence JSON'); + throw error; + } + } + if (!isDict(envelope) || !pyEqualsOne(pyGet(envelope, 'version'))) throw evidence('Unsupported execution evidence format'); + const nodes = pyGet(envelope, 'nodes'); + if (pyTruthy(pyGet(envelope, 'truncated')) || !isDict(nodes) || nodes.size > MAX_EXECUTION_NODES) throw evidence('Truncated or malformed execution evidence'); + if (!nodes.has(nodeId)) return null; + const node = nodes.get(nodeId); + if (!isDict(node) || pyTruthy(pyGet(node, 'truncated'))) throw evidence('Truncated or malformed node execution evidence'); + const records = pyGet(node, 'records'); + if (!isList(records) || !records.length || records.length > MAX_EXECUTION_RECORDS) throw evidence('Malformed node execution records'); + const unique = new Map(); + for (const record of records) { + if (!isDict(record) || EXECUTION_FIELDS.some(key => typeof pyGet(record, key) !== 'string' || pyLen(record.get(key)) > MAX_EXECUTION_TEXT)) { + throw evidence('Malformed execution text values'); + } + const clean = Object.fromEntries(EXECUTION_FIELDS.map(key => [key, record.get(key)])); + if (clean.negative_effective_text !== clean.negative_text) throw evidence('Negative execution text must be unchanged'); + unique.set(JSON.stringify(EXECUTION_FIELDS.map(key => clean[key])), clean); + } + if (unique.size !== 1) throw evidence('Multiple distinct executions have no image anchor'); + return [...unique.values()][0]; +} + +/** + * The validated semantics table (utils/inspection_semantics.py), from the parsed JSON document. Throws + * `SemanticsError` for any shape the server rejects; the caller then answers "semantics unavailable". + */ +export function compileSemantics(doc) { + const fail = message => { throw new SemanticsError(message); }; + const plain = value => value !== null && typeof value === 'object' && !Array.isArray(value); + if (!plain(doc) || doc.schema !== 1) fail('unsupported semantics table'); + const owners = new Map(); + const claim = (name, category) => { + if (owners.has(name) && owners.get(name) !== category) fail(`duplicate class ${name}`); + owners.set(name, category); + }; + const byClass = category => { + if (!plain(doc[category])) fail(`category ${category} must be an object`); + const table = new Map(); + for (const [name, entry] of Object.entries(doc[category])) { + if (!plain(entry) || typeof entry.strategy !== 'string') fail(`${category}[${name}]`); + claim(name, category); + table.set(name, entry); + } + return table; + }; + const bySlot = category => { + if (!Array.isArray(doc[category])) fail(`category ${category} must be a list`); + const table = new Map(); + for (const row of doc[category]) { + if (!plain(row) || typeof row.class !== 'string' || !Number.isInteger(row.slot) || row.slot < 0 || row.slot > 255) fail(`${category} row`); + const key = slotKey(row.class, row.slot); + if (table.has(key)) fail(`${category}: duplicate output key`); + claim(row.class, category); + const { class: _name, slot: _slot, ...entry } = row; + table.set(key, entry); + } + return table; + }; + const bySet = category => { + if (!Array.isArray(doc[category])) fail(`category ${category} must be a list`); + const set = new Set(); + for (const name of doc[category]) { + if (typeof name !== 'string' || set.has(name)) fail(`${category}: duplicate class`); + claim(name, category); + set.add(name); + } + return set; + }; + const samplers = byClass('samplers'), guiders = byClass('guiders'), selectors = byClass('selectors'); + const composites = byClass('composites'), savers = byClass('savers'); + const conditioning = bySlot('conditioning'), encoders = bySlot('encoders'), strings = bySlot('strings'); + const runtime = bySet('runtime'), nonFileOutputs = bySet('non_file_outputs'); + const stageInputs = doc.stage_inputs; + if (!plain(stageInputs) || !Array.isArray(stageInputs.shaped) || !Array.isArray(stageInputs.with_model)) fail('stage_inputs'); + return Object.freeze({ + samplers, guiders, selectors, composites, savers, conditioning, encoders, strings, runtime, nonFileOutputs, + stageInputs: { shaped: [...stageInputs.shaped], withModel: [...stageInputs.with_model] }, allClasses: new Set(owners.keys()), + }); +} + +/** `outcome_message`: one line for an unresolved outcome, or null to keep the status copy. */ +export function outcomeMessage(resolution) { + if (resolution?.state !== 'unresolved') return null; + const code = typeof resolution.reason_code === 'string' ? resolution.reason_code : null; + if (Object.hasOwn(NAMED_LINES, code)) { + const node = resolution.node, raw = node !== null && typeof node === 'object' ? node.class_type : null; + const name = typeof raw === 'string' && raw ? pySlice(raw, OUTCOME_NAME_LENGTH) : null; + return name ? `${NAMED_LINES[code]} (${name}).` : `${NAMED_LINES[code]}.`; + } + if (code === null) return Object.hasOwn(UNCODED_LINES, resolution.reason) ? UNCODED_LINES[resolution.reason] : null; + return Object.hasOwn(CODED_LINES, code) ? CODED_LINES[code] : null; +} + +export const sideOf = (status, text = null, source = null) => ({ status, text, source }); +export function explained(prompts, resolution) { + const message = outcomeMessage(resolution); + if (message === null) return prompts; + return Object.fromEntries(Object.entries(prompts).map(([role, side]) => [role, side.status === 'unresolved' && !Object.hasOwn(side, 'message') ? { ...side, message } : side])); +} +export const EMPTY_POSITIVE = outcomeMessage({ state: 'unresolved', reason: EMPTY_POSITIVE_REASON }); diff --git a/web/js/workspace/local-resolver.mjs b/web/js/workspace/local-resolver.mjs new file mode 100644 index 00000000..bde4db2f --- /dev/null +++ b/web/js/workspace/local-resolver.mjs @@ -0,0 +1,776 @@ +// The server's inspection resolver in this browser (#249 local Inspect, PR L3 Task 8, decision LI-1): a port of +// utils/prompt_inspector.py `inspect_prompt_evidence` with utils/prompt_pair_resolver.py (INSPECTION_PROFILE) and +// utils/pair_execution.py `read_pair_execution`, driven by web/js/inspection-semantics.json. Python is the oracle: +// tests/test_local_inspect_parity.py compares every answer with the server's on the same records. Values follow +// Python's model (py-json.mjs): dict order, int versus float, code-point lengths, `str.strip()`. +// +// Task 8 ports execution evidence and graph tracing for one sampler. Candidate selection among several samplers, +// detailer stages and A1111 `parameters` are Task 9; until then they raise `LocalResolverGap`. No DOM. +import { PyValueError, isDict, isList, isInt, pyJsonLoads, pyLen, pySlice, pyStrip, pyStr, pyGet } from './py-json.mjs'; +import { + ADAPTERS, + ADAPTER_SLOTS, + Budget, + CANDIDATE_STRATEGIES, + CLASS_NAME_LENGTH, + DETAILER, + Diverging, + EMPTY_POSITIVE, + EMPTY_POSITIVE_REASON, + GUIDER_ABSENT_REASON, + INCOMPATIBLE_SLOT, + LocalResolverGap, + MAX_BRANCH_CANDIDATES, + MAX_JOIN_INPUTS, + MAX_SUBGRAPH_DEPTH, + MAX_WORKFLOW_NODES, + MULTISTAGE_UNATTRIBUTED_REASON, + NO_SAMPLER_NAMES, + OVERWRITTEN_PROMPT_REASON, + PROFILE, + ROLE_METADATA_KEYS, + RUNTIME_REASON, + SAMPLER_LIKE_INPUTS, + SEMANTICS_UNAVAILABLE_REASON, + UNVERIFIABLE_CODES, + Unresolved, + ZEROED_SOURCE, + compileSemantics, + explained, + isLink, + nodeRef, + readPairExecution, + result, + sideOf, + slotKey, +} from './local-resolver-support.mjs'; + +export { LocalResolverGap, SemanticsError, compileSemantics, readPairExecution, outcomeMessage, isLink } from './local-resolver-support.mjs'; + +class GraphResolver { + constructor(graph, metadata, semantics, overwritten) { + this.graph = graph; + this.overwritten = overwritten; + this.perCandidateVisits = PROFILE.perCandidateVisits; + this.budget = new Budget(PROFILE.totalVisits); + this.budget.reset(PROFILE.perCandidateVisits); + this.pathEntries = PROFILE.maxPathEntries; + this.builtChars = PROFILE.maxBuiltChars; + this.scanned = PROFILE.maxScannedUnits; + this.checked = new Map(); + this.costs = new Map(); + this.heights = new Map(); + this.deepest = 0; + this.maxDepth = PROFILE.maxDepth; + this.maxTextLength = PROFILE.maxTextLength; + this.memo = new Map(); + this.active = new Set(); + this.metadata = metadata ?? new Map(); + this.textSources = new Map(); + this.choices = new Map(); + this.tainted = false; + this.latentWalks = new Map(); + this.latentCharged = new Set(); + this.semantics = semantics; + this.samplerClasses = new Set([...semantics.samplers].filter(([, entry]) => CANDIDATE_STRATEGIES.has(entry.strategy)).map(([name]) => name)); + this.stageClasses = new Set(semantics.samplers.keys()); + } + + node(nodeId) { + if (!this.checked.has(nodeId)) { + try { + this.checked.set(nodeId, this.checkedNode(nodeId)); + } catch (error) { + if (!(error instanceof Unresolved) || error.code === 'work-limit') throw error; + this.checked.set(nodeId, error); + } + } + const checked = this.checked.get(nodeId); + if (checked instanceof Unresolved) throw new Unresolved(checked.message, checked.code, checked.node); + return checked; + } + checkedNode(nodeId) { + const node = pyGet(this.graph, nodeId); + if (!isDict(node) || !isDict(pyGet(node, 'inputs'))) throw new Unresolved('Missing or malformed graph node', 'malformed'); + const inputs = node.get('inputs'); + this.scan(inputs.size); + return [pyStr(pyGet(node, 'class_type', '')), inputs]; + } + scan(units) { + if (units > this.scanned) { + this.scanned = -1; + throw new Unresolved('Resolution work limit reached', 'work-limit'); + } + this.scanned -= units; + } + unsupported(message, nodeId) { return this.named(message, 'unsupported-node', nodeId); } + named(message, code, nodeId) { + const node = pyGet(this.graph, nodeId); + const classType = isDict(node) ? pyGet(node, 'class_type') : null; + return new Unresolved(message, code, nodeRef(nodeId, classType)); + } + bounded(text) { + if (pyLen(text) > this.maxTextLength) throw new Unresolved('Resolved text exceeds the length limit', 'text-limit'); + return text; + } + built(text) { + this.builtChars -= pyLen(text); + if (this.builtChars < 0) throw new Unresolved('Resolution work limit reached', 'work-limit'); + return text; + } + + /** `text`: [text, path, storageText] for a string value or a typed link. */ + text(value, kind, depth = 0) { + this.deepest = Math.max(this.deepest, depth); + if (depth >= this.maxDepth) throw new Unresolved('Resolution depth limit reached', 'depth-limit'); + if (typeof value === 'string' && kind === 'string') return [this.bounded(value), [], value]; + if (!isLink(value)) throw new Unresolved('Expected a typed graph link or text input', 'malformed'); + const nodeId = String(value[0]), slot = value[1]; + const key = `${slotKey(nodeId, slot)}\u0000${kind}`; + if (this.active.has(key)) throw new Unresolved('Cyclic prompt graph', 'malformed'); + if (this.memo.has(key)) { + const height = this.heights.get(key); + if (depth + height >= this.maxDepth) throw new Unresolved('Resolution depth limit reached', 'depth-limit'); + this.budget.charge(this.costs.get(key)); + this.deepest = Math.max(this.deepest, depth + height); + return this.memo.get(key); + } + const allowance = this.budget.allowance, outerDeepest = this.deepest, outerTainted = this.tainted; + this.tainted = false; + this.deepest = depth; + try { + this.budget.spend(); + const [name, inputs] = this.node(nodeId); + this.scan(inputs.size); + if (this.overwritten.has(nodeId)) throw new Unresolved(OVERWRITTEN_PROMPT_REASON, 'malformed'); + this.active.add(key); + let text, path, storageText; + const adapted = ADAPTERS.get(slotKey(name, slot)); + if (name === 'Reroute' && slot === 0) { + const keys = ['value', 'input', 'in'].filter(item => inputs.has(item)); + if (keys.length !== 1) throw new Unresolved('Reroute input is not uniquely identifiable', 'malformed'); + [text, path, storageText] = this.text(inputs.get(keys[0]), kind, depth + 1); + this.inheritSource(nodeId, slot, [path]); + } else if (adapted) { + if (adapted.kind !== kind) throw new Unresolved(INCOMPATIBLE_SLOT, 'malformed'); + const evidence = name === 'PromptManagerPair' ? this.executionRecord(nodeId, inputs) : null; + if (evidence !== null) { + text = evidence[adapted.inputName === 'text' ? 'positive_text' : 'negative_effective_text']; + storageText = evidence[adapted.inputName]; + path = []; + this.textSources.set(slotKey(nodeId, slot), 'execution'); + } else if (adapted.comma || adapted.strip) { + [text, path, storageText] = this.historical(adapted, inputs, depth); + } else { + [text, path, storageText] = this.text(pyGet(inputs, adapted.inputName), 'string', depth + 1); + if (adapted.compose || adapted.storageInput) storageText = text; + if (adapted.compose) { + const [before, beforePath] = this.text(pyGet(inputs, 'prepend_text', ''), 'string', depth + 1); + const [after, afterPath] = this.text(pyGet(inputs, 'append_text', ''), 'string', depth + 1); + this.scan(pyLen(before) + pyLen(after) + beforePath.length + path.length + afterPath.length); + text = this.built(this.bounded([pyStrip(before), text, pyStrip(after)].filter(part => part).join(' '))); + path = [...beforePath, ...path, ...afterPath]; + } + } + } else if ((name === 'StringConcatenate' || name === 'Text Concatenate') && slot === 0 && kind === 'string') { + [text, path] = this.concatenate(name, inputs, depth); + storageText = text; + } else if (this.follows(name, slot, kind)) { + [text, path, storageText] = this.semantic(nodeId, name, slot, kind, inputs, depth); + } else { + throw this.unsupported('Unsupported node semantics or output slot', nodeId); + } + this.scan(path.length + 1); + path = [{ node_id: nodeId, output_slot: slot }, ...path]; + const pathLimit = this.maxDepth * Math.max(1, this.perCandidateVisits); + this.pathEntries -= path.length; + if (path.length > pathLimit || this.pathEntries < 0) throw new Unresolved('Provenance path limit reached', 'work-limit'); + const traced = [text, path, storageText]; + if (!this.tainted) { + this.memo.set(key, traced); + this.costs.set(key, allowance - this.budget.allowance); + this.heights.set(key, this.deepest - depth); + } + return traced; + } finally { + this.deepest = Math.max(outerDeepest, this.deepest); + this.tainted = outerTainted || this.tainted; + this.active.delete(key); + } + } + + /** `StringConcatenate` / `Text Concatenate` (the `text` branch). */ + concatenate(name, inputs, depth) { + let keys, delimiter, clean; + if (name === 'StringConcatenate') { + keys = ['string_a', 'string_b']; + delimiter = pyGet(inputs, 'delimiter', ''); + clean = false; + } else { + keys = [...inputs.keys()].filter(item => /^text_[a-z]$/.test(item)).sort(); + delimiter = pyGet(inputs, 'delimiter', ' '); + clean = pyStr(pyGet(inputs, 'clean_whitespace', 'true')).toLowerCase() === 'true'; + } + if (!keys.length || typeof delimiter !== 'string') throw new Unresolved('Malformed concatenation', 'malformed'); + const parts = [], path = []; + let size = 0; + for (const inputName of keys) { + let [part, followed] = this.text(pyGet(inputs, inputName, ''), 'string', depth + 1); + this.scan(pyLen(part) + followed.length); + if (clean) part = pyStrip(part); + path.push(...followed); + if (part || name === 'StringConcatenate') { + size += pyLen(part) + (parts.length ? pyLen(delimiter) : 0); + if (size > this.maxTextLength) throw new Unresolved('Resolved text exceeds the length limit', 'text-limit'); + parts.push(part); + } + } + return [this.built(parts.join(delimiter)), path]; + } + + /** `prompt_manager_*.py` at 07a5af3: strip, then join with ", ". */ + historical(adapted, inputs, depth) { + let [text, path] = this.text(pyGet(inputs, adapted.inputName, adapted.default), 'string', depth + 1); + this.scan(pyLen(text)); + text = pyStrip(text); + const storageText = text; + if (adapted.comma) { + let [before, beforePath] = this.text(pyGet(inputs, 'prepend_text') ?? '', 'string', depth + 1); + let [after, afterPath] = this.text(pyGet(inputs, 'append_text') ?? '', 'string', depth + 1); + this.scan(pyLen(before) + pyLen(after) + beforePath.length + afterPath.length); + before = pyStrip(before); after = pyStrip(after); + if (before) text = `${before}${text && !before.endsWith(',') ? ', ' : ''}${text}`; + if (after) text = `${text}${text && !text.endsWith(',') ? ', ' : ''}${after}`; + text = this.built(this.bounded(text)); + path = [...beforePath, ...path, ...afterPath]; + } + return [text, path, storageText]; + } + + follows(name, slot, kind) { + const semantics = this.semantics, key = slotKey(name, slot); + if (semantics.runtime.has(name)) return true; + if (semantics.encoders.has(key) || semantics.strings.has(key)) return true; + if (slot === 0 && semantics.selectors.has(name)) return true; + return kind === 'conditioning' && (semantics.conditioning.has(key) || (slot === 0 && semantics.composites.has(name))); + } + + semantic(nodeId, name, slot, kind, inputs, depth) { + const semantics = this.semantics, key = slotKey(name, slot); + if (semantics.runtime.has(name)) throw this.named(RUNTIME_REASON, 'runtime-value', nodeId); + for (const [table, expected, build] of [[semantics.encoders, 'conditioning', 'encoded'], [semantics.strings, 'string', 'stringed']]) { + const listed = table.get(key); + if (listed !== undefined) { + if (kind !== expected) throw new Unresolved(INCOMPATIBLE_SLOT, 'malformed'); + return this[build](nodeId, listed, inputs, depth); + } + } + const entry = kind === 'conditioning' ? semantics.conditioning.get(key) : undefined; + if (entry !== undefined && entry.strategy === 'zeroed') { + this.textSources.set(slotKey(nodeId, slot), ZEROED_SOURCE); + return ['', [], '']; + } + if (entry !== undefined) { + const traced = this.text(pyGet(inputs, entry.input), kind, depth + 1); + this.inheritSource(nodeId, slot, [traced[1]]); + return traced; + } + if (semantics.selectors.has(name)) return this.select(nodeId, semantics.selectors.get(name), inputs, kind, depth); + const parts = semantics.composites.get(name).inputs.map(inputName => this.text(pyGet(inputs, inputName), kind, depth + 1)); + if (new Set(parts.map(part => part[0])).size !== 1) throw this.named('Combined conditioning has different texts', 'composite', nodeId); + return this.merged(nodeId, slot, parts); + } + + select(nodeId, entry, inputs, kind, depth) { + const condition = pyGet(inputs, entry.condition), branches = entry.branches; + let choice; + if (typeof condition === 'boolean') choice = condition; + else if (!isLink(condition)) throw new Unresolved('Malformed selector condition', 'malformed'); + else if (this.choices.has(slotKey(String(condition[0]), condition[1]))) { + choice = this.choices.get(slotKey(String(condition[0]), condition[1])); + this.tainted = true; + } else choice = null; + if (choice !== null) { + const traced = this.text(pyGet(inputs, branches[choice ? 'true' : 'false']), kind, depth + 1); + this.inheritSource(nodeId, 0, [traced[1]]); + return traced; + } + const parts = ['true', 'false'].map(label => this.text(pyGet(inputs, branches[label]), kind, depth + 1)); + if (parts[0][0] !== parts[1][0]) throw new Diverging(slotKey(String(condition[0]), condition[1])); + return this.merged(nodeId, 0, parts); + } + + merged(nodeId, slot, parts) { + const traced = this.joinedPaths(parts, parts); + this.inheritSource(nodeId, slot, parts.map(part => part[1])); + return traced; + } + + joinedPaths(chosen, parts) { + const text = chosen[0][0]; + const storages = new Set(chosen.map(part => part[2])); + const storageText = storages.size === 1 ? chosen[0][2] : text; + const paths = parts.map(part => part[1]); + this.scan(paths.reduce((sum, path) => sum + path.length, 0)); + const merged = [], seen = new Set(); + for (const path of paths) { + for (const step of path) { + const identity = slotKey(step.node_id, step.output_slot); + if (!seen.has(identity)) { seen.add(identity); merged.push(step); } + } + } + return [text, merged, storageText]; + } + + encoded(nodeId, entry, inputs, depth) { + const names = entry.inputs; + if (entry.strategy === 'single') return this.text(pyGet(inputs, names[0]), 'string', depth + 1); + if (entry.strategy === 'flag-parts') return this.flagged(nodeId, entry, inputs, depth); + if (entry.strategy !== 'parts-equal') throw this.unsupported('Unsupported encoder strategy', nodeId); + const parts = names.map(name => this.text(pyGet(inputs, name), 'string', depth + 1)); + this.scan(parts.reduce((sum, part) => sum + pyLen(part[0]), 0)); + if (new Set(parts.map(part => part[0])).size === 1) return this.joinedPaths(parts, parts); + const filled = parts.filter(part => part[0] !== ''); + if (filled.length === 1) return this.joinedPaths(filled, parts); + throw this.named('Encoder parts have different texts', 'composite', nodeId); + } + + flagged(nodeId, entry, inputs, depth) { + const names = entry.inputs; + if (!this.setting(nodeId, inputs, entry.params.flag, 'bool')) return this.text(pyGet(inputs, names[0]), 'string', depth + 1); + const parts = names.map(name => this.text(pyGet(inputs, name), 'string', depth + 1)); + this.scan(parts.reduce((sum, part) => sum + pyLen(part[0]), 0)); + if (new Set(parts.map(part => part[0])).size === 1) return this.joinedPaths(parts, parts); + throw this.named(RUNTIME_REASON, 'runtime-value', nodeId); + } + + stringed(nodeId, entry, inputs, depth) { + const strategy = entry.strategy, source = entry.inputs[0]; + if (strategy === 'literal') return this.text(pyGet(inputs, source), 'string', depth + 1); + if (strategy === 'strip-newlines') { + const flag = this.setting(nodeId, inputs, entry.params.flag, 'bool'); + const traced = this.text(pyGet(inputs, source), 'string', depth + 1); + if (!flag) return traced; + this.scan(pyLen(traced[0])); + const text = this.built(this.bounded(pyStrip(traced[0].replaceAll('\n', '')))); + return [text, traced[1], text]; + } + if (strategy === 'join-multi') return this.joinMulti(nodeId, entry, inputs, depth); + throw this.unsupported('Unsupported string strategy', nodeId); + } + + /** A literal node setting of exactly `type(value) is kind`; linked is `unsupported-node`, else malformed. */ + setting(nodeId, inputs, name, kind) { + if (!inputs.has(name)) throw new Unresolved('Missing string node setting', 'malformed'); + const value = inputs.get(name); + if (isLink(value)) throw this.unsupported('Linked string node setting', nodeId); + const typed = { bool: typeof value === 'boolean', int: isInt(value), str: typeof value === 'string' }[kind]; + if (!typed) throw new Unresolved('Malformed string node setting', 'malformed'); + return value; + } + + joinMulti(nodeId, entry, inputs, depth) { + const params = entry.params, flag = params.list_flag; + if (!inputs.has(flag)) throw new Unresolved('Missing string node setting', 'malformed'); + if (isLink(inputs.get(flag)) || inputs.get(flag) === true) throw this.named(RUNTIME_REASON, 'runtime-value', nodeId); + if (inputs.get(flag) !== false) throw new Unresolved('Malformed string node setting', 'malformed'); + const count = this.setting(nodeId, inputs, params.count, 'int'); + const delimiter = this.setting(nodeId, inputs, params.delimiter, 'str'); + if (!(count >= 1 && count <= MAX_JOIN_INPUTS)) throw new Unresolved('Malformed string node setting', 'malformed'); + const total = Number(count); + this.scan(total); + const names = [entry.inputs[0]]; + for (let index = 2; index <= total; index++) names.push(`${params.input_prefix}${index}`); + const parts = [], path = [], seen = new Set(); + let size = 0; + names.forEach((inputName, position) => { + if (position && !inputs.has(inputName)) return; + const [part, followed] = this.text(pyGet(inputs, inputName), 'string', depth + 1); + this.scan(pyLen(part) + followed.length); + for (const step of followed) { + const identity = slotKey(step.node_id, step.output_slot); + if (!seen.has(identity)) { seen.add(identity); path.push(step); } + } + if (position && !part) return; + size += pyLen(part) + (parts.length ? pyLen(delimiter) : 0); + if (size > this.maxTextLength) throw new Unresolved('Resolved text exceeds the length limit', 'text-limit'); + parts.push(part); + }); + const text = this.built(parts.join(delimiter)); + return [text, path, text]; + } + + sourceOf(path) { + if (!path.length) return 'graph-inferred'; + return this.textSources.get(slotKey(path[0].node_id, path[0].output_slot)) ?? 'graph-inferred'; + } + inheritSource(nodeId, slot, paths) { + const sources = new Set(paths.map(path => this.sourceOf(path))); + if (sources.size === 1) this.textSources.set(slotKey(nodeId, slot), [...sources][0]); + else this.textSources.delete(slotKey(nodeId, slot)); + } + unverifiable(error) { return UNVERIFIABLE_CODES.has(error.code); } + + executionRecord(nodeId, inputs) { + const record = readPairExecution(this.metadata, nodeId); + if (record === null) return null; + for (const name of ['text', 'negative_text', 'prepend_text', 'append_text']) { + let expected; + try { + expected = this.text(pyGet(inputs, name, ''), 'string')[0]; + } catch (error) { + if (error instanceof Unresolved && this.unverifiable(error)) { + const value = pyGet(inputs, name); + if (isLink(value)) { + const [sourceName] = this.node(String(value[0])); + const known = ADAPTER_SLOTS.get(sourceName); + if (known && !known.has(String(value[1]))) throw error; + if (['StringConcatenate', 'Text Concatenate', 'Reroute'].includes(sourceName) && value[1] !== 0) throw error; + } + continue; + } + throw error; + } + if (name === 'prepend_text' || name === 'append_text') expected = pyStrip(expected); + if (expected !== record[name]) throw new Unresolved('Execution evidence does not match recorded node inputs', 'malformed'); + } + return record; + } + + side(value, samplerId, guiderId = null, depth = 0) { + const [text, path, storageText] = this.text(value, 'conditioning', depth); + const origin = path[0]; + const provenance = { + format: 'comfyui', sampler_id: samplerId, ...origin, path, + text_source: this.textSources.get(slotKey(origin.node_id, origin.output_slot)) ?? 'graph-inferred', + }; + if (guiderId !== null) provenance.guider_id = guiderId; + return { text, storage_text: storageText, provenance }; + } + + guider(value) { + const seen = new Set(); + let depth = 0; + for (;;) { + if (depth >= this.maxDepth) throw new Unresolved('Resolution depth limit reached', 'depth-limit'); + if (!isLink(value)) throw new Unresolved('Expected a guider link', 'malformed'); + const nodeId = String(value[0]), slot = value[1]; + if (seen.has(nodeId)) throw new Unresolved('Cyclic guider ancestry', 'malformed'); + seen.add(nodeId); + this.budget.spend(); + const [name, inputs] = this.node(nodeId); + this.scan(inputs.size); + depth += 1; + if (name === 'Reroute' && slot === 0) { + const keys = ['value', 'input', 'in'].filter(item => inputs.has(item)); + if (keys.length !== 1) throw new Unresolved('Reroute input is not uniquely identifiable', 'malformed'); + value = inputs.get(keys[0]); + continue; + } + const entry = this.semantics.guiders.get(name); + if (entry === undefined || slot !== 0) throw this.unsupported('Unsupported guider', nodeId); + return [nodeId, inputs, { positive: entry.positive, negative: entry.negative ?? null }, entry.absent_reason ?? GUIDER_ABSENT_REASON, depth]; + } + } + + pair(samplerId) { + this.budget.reset(this.perCandidateVisits); + this.latentCharged = new Set(); + if (this.budget.total <= 0) return result('unresolved', { samplerId, reason: 'Resolution visit limit reached', reasonCode: 'work-limit' }); + return this.branches(samplerId); + } + + /** One sampler's result. A detailer stage compared with its upstream stages is Task 9. */ + stage(samplerId, later) { + if (later.size >= this.maxDepth) return result('unresolved', { samplerId, reason: 'Resolution depth limit reached', reasonCode: 'depth-limit' }); + const own = this.sides(samplerId); + if (own.state === 'unresolved') return own; + const [name] = this.node(samplerId); + const entry = this.semantics.samplers.get(name); + if (entry === undefined || entry.strategy !== DETAILER) return own; + throw new LocalResolverGap('Detailer stages are compared in Task 9'); + } + + branches(samplerId) { + const pending = [new Map()], results = []; + try { + while (pending.length) { + this.choices = pending.shift(); + try { + results.push(this.stage(samplerId, new Set())); + } catch (error) { + if (!(error instanceof Diverging)) throw error; + if (results.length + pending.length + 2 > MAX_BRANCH_CANDIDATES) throw new Unresolved('Too many selector branches', 'work-limit'); + for (const choice of [true, false]) pending.push(new Map([...this.choices, [error.key, choice]])); + } + } + } catch (error) { + if (!(error instanceof Unresolved)) throw error; + return result('unresolved', { samplerId, reason: error.message, reasonCode: error.code, node: error.node }); + } finally { + this.choices = new Map(); + } + if (results.every(item => item.state === 'unresolved')) return results[0]; + if (new Set(results.map(outcomeKey)).size === 1) return results[0]; + return result('ambiguous', { samplerId, reason: 'Selector branches have different prompts', candidates: results }); + } + + sides(samplerId) { + let positive = null, negative = null; + try { + let [name, inputs] = this.node(samplerId); + const entry = this.semantics.samplers.get(name); + this.checkOverrides(samplerId, entry, inputs); + const latent = entry.latent; + if (latent !== undefined && latent !== null && inputs.has(latent)) this.latentChecked(samplerId, inputs.get(latent)); + let guiderId = null, depth = 0, conditioning = entry.conditioning, absentReason = 'Negative input is absent'; + if (entry.strategy === 'custom-advanced') { + let guiderReason; + [guiderId, inputs, conditioning, guiderReason, depth] = this.guider(pyGet(inputs, conditioning.guider)); + if (conditioning.negative === null) absentReason = guiderReason; + } + positive = this.side(pyGet(inputs, conditioning.positive), samplerId, guiderId, depth); + if (!pyStrip(positive.text)) throw new Unresolved(EMPTY_POSITIVE_REASON); + const negativeName = conditioning.negative; + if (negativeName === null || negativeName === undefined || !inputs.has(negativeName)) { + return result('absent', { positive, samplerId, reason: absentReason }); + } + negative = this.side(inputs.get(negativeName), samplerId, guiderId, depth); + return result('resolved', { positive, negative, samplerId }); + } catch (error) { + if (!(error instanceof Unresolved)) throw error; + return result('unresolved', { positive, negative, samplerId, reason: error.message, reasonCode: error.code, node: error.node }); + } + } + + checkOverrides(samplerId, entry, inputs) { + for (const name of entry.prompt_overrides ?? []) { + const value = pyGet(inputs, name); + if (value === null || value === '') continue; + if (isLink(value)) throw this.unsupported('Unsupported prompt override', String(value[0])); + throw this.named(RUNTIME_REASON, 'runtime-value', samplerId); + } + } + + latentChecked(samplerId, value) { + let error; + if (this.latentWalks.has(samplerId)) { + const [walked, cost] = this.latentWalks.get(samplerId); + error = walked; + if (!this.latentCharged.has(samplerId)) { + this.budget.charge(cost); + this.latentCharged.add(samplerId); + } + } else { + const before = this.budget.allowance; + try { + this.latentStages(samplerId, value); + error = null; + } catch (raised) { + if (!(raised instanceof Unresolved) || raised.code === 'work-limit') throw raised; + error = raised; + } + this.latentWalks.set(samplerId, [error, before - this.budget.allowance]); + this.latentCharged.add(samplerId); + } + if (error !== null) throw new Unresolved(error.message, error.code, error.node === null ? null : { ...error.node }); + } + + enqueue(queue, queued, inputs, depth) { + this.scan(inputs.size); + for (const item of inputs.values()) { + if (!isLink(item)) continue; + const key = String(item[0]); + if (!queued.has(key)) { queued.add(key); queue.push([key, depth]); } + } + } + + stageShaped(name, inputs) { + if (this.semantics.allClasses.has(name)) return false; + const { shaped, withModel } = this.semantics.stageInputs; + if (shaped.some(key => isLink(pyGet(inputs, key)))) return true; + return isLink(pyGet(inputs, 'model')) && withModel.some(key => isLink(pyGet(inputs, key))); + } + + latentStages(origin, value) { + if (!isLink(value)) throw new Unresolved('Unknown latent ancestry', 'malformed'); + const start = String(value[0]), queue = [[start, 0]], queued = new Set([start]); + for (let head = 0; head < queue.length; head++) { + const [nodeId, depth] = queue[head]; + if (nodeId === origin) throw new Unresolved('Cyclic latent ancestry', 'malformed'); + if (depth >= this.maxDepth) throw new Unresolved('Resolution depth limit reached', 'depth-limit'); + this.budget.spend(); + const [name, inputs] = this.node(nodeId); + if (this.stageClasses.has(name)) throw new Unresolved(MULTISTAGE_UNATTRIBUTED_REASON); + if (this.stageShaped(name, inputs)) throw this.unsupported('Unsupported latent ancestry', nodeId); + this.enqueue(queue, queued, inputs, depth + 1); + } + } +} + +const roleText = side => side !== null && typeof side === 'object' ? side.text : null; +const outcomeKey = item => JSON.stringify([item.state, roleText(item.positive), roleText(item.negative)]); + +/** `_sampler_like_classes`: distinct classes, in graph order, of nodes shaped like samplers or guiders. */ +function samplerLikeClasses(graph) { + const names = []; + for (const node of graph.values()) { + if (!isDict(node) || !isDict(pyGet(node, 'inputs'))) continue; + const name = pyGet(node, 'class_type'); + if (typeof name !== 'string' || !name || names.includes(name)) continue; + if (SAMPLER_LIKE_INPUTS.some(key => isLink(pyGet(node.get('inputs'), key)))) { + names.push(pySlice(name, CLASS_NAME_LENGTH)); + if (names.length === NO_SAMPLER_NAMES) break; + } + } + return names; +} + +function noSampler(graph) { + const seen = samplerLikeClasses(graph); + const reason = `No supported sampler pair found${seen.length ? ` (saw ${seen.join(', ')})` : ''}`; + return result('unresolved', { reason, reasonCode: 'no-sampler' }); +} + +/** Python `kind in mapping` for a workflow `type`: an unhashable list or dict raises `TypeError` there. */ +function hashable(value) { + if (isList(value) || isDict(value)) throw new TypeError("unhashable type in workflow node 'type'"); + return value; +} + +/** `_prompt_manager_widgets`: API node ID to widget text for every PromptManager node that runs. */ +function promptManagerWidgets(workflow) { + const nodes = isDict(workflow) ? pyGet(workflow, 'nodes') : null; + if (!isList(nodes)) return new Map(); + const definitions = pyGet(workflow, 'definitions'); + const listed = isDict(definitions) ? pyGet(definitions, 'subgraphs') : null; + const subgraphs = new Map(); + for (const subgraph of isList(listed) ? listed : []) { + if (isDict(subgraph) && typeof pyGet(subgraph, 'id') === 'string' && isList(pyGet(subgraph, 'nodes'))) subgraphs.set(subgraph.get('id'), subgraph.get('nodes')); + } + const widgets = new Map(), stack = [[nodes, '', 0]]; + let visited = 0; + while (stack.length) { + const [members, prefix, depth] = stack.pop(); + for (const node of members) { + visited += 1; + if (visited > MAX_WORKFLOW_NODES) return widgets; + if (!isDict(node)) continue; + const kind = pyGet(node, 'type'), nodeId = pyGet(node, 'id'); + if (!(typeof nodeId === 'string' || isInt(nodeId))) continue; + const apiId = `${prefix}${String(nodeId)}`; + if (typeof hashable(kind) === 'string' && subgraphs.has(kind) && depth < MAX_SUBGRAPH_DEPTH) { + stack.push([subgraphs.get(kind), `${apiId}:`, depth + 1]); + continue; + } + const values = pyGet(node, 'widgets_values'); + const text = isList(values) && values.length && typeof values[0] === 'string' ? values[0] : + isDict(values) && typeof pyGet(values, 'text') === 'string' ? values.get('text') : null; + if (typeof kind === 'string' && kind !== 'PromptManagerPair' && kind.toLowerCase().includes('promptmanager') && text !== null) widgets.set(apiId, text); + } + } + return widgets; +} + +/** `_overwritten_prompt_nodes` (R1). */ +function overwrittenPromptNodes(workflow, graph) { + const widgets = promptManagerWidgets(workflow), byText = new Map(); + for (const [nodeId] of widgets) { + const node = pyGet(graph, nodeId); + const inputs = isDict(node) ? pyGet(node, 'inputs') : null; + const text = isDict(inputs) ? pyGet(inputs, 'text') : null; + if (typeof text === 'string') { + if (!byText.has(text)) byText.set(text, []); + byText.get(text).push(nodeId); + } + } + const found = new Set(); + for (const ids of byText.values()) { + if (ids.length > 1 && new Set(ids.map(id => widgets.get(id))).size > 1) ids.forEach(id => found.add(id)); + } + return found; +} + +/** `_resolve` for an unanchored inspection (output_node_id None). */ +function resolve(metadata, semantics) { + if (!isDict(metadata) || !metadata.size) return result('absent', { reason: 'No parsed prompt metadata' }); + let graph; + if (metadata.has('prompt')) graph = metadata.get('prompt'); + else if (metadata.has('parameters')) throw new LocalResolverGap('A1111 parameters are resolved in Task 9'); + else graph = metadata; + if (!isDict(graph) || !graph.size) return result('unresolved', { reason: 'API graph is missing or malformed', reasonCode: 'malformed' }); + if (graph.size > PROFILE.nodeCeiling) return result('unresolved', { reason: 'Prompt graph exceeds the inspection node ceiling', reasonCode: 'graph-ceiling' }); + if (semantics === null) return result('unresolved', { reason: SEMANTICS_UNAVAILABLE_REASON }); + const overwritten = metadata.has('prompt') ? overwrittenPromptNodes(pyGet(metadata, 'workflow'), graph) : new Set(); + const resolver = new GraphResolver(graph, metadata.has('prompt') ? metadata : null, semantics, overwritten); + const samplerIds = [...graph].filter(([, node]) => isDict(node) && typeof pyGet(node, 'class_type') === 'string' && resolver.samplerClasses.has(node.get('class_type'))).map(([id]) => id); + if (!samplerIds.length) return noSampler(graph); + if (samplerIds.length > 1 || samplerIds.some(id => semantics.samplers.get(graph.get(id).get('class_type')).strategy === DETAILER)) { + throw new LocalResolverGap('Several sampler candidates are selected in Task 9'); + } + return resolver.pair(samplerIds[0]); +} + + +/** `_may_hold_prompt_manager`. */ +function mayHoldPromptManager(canonical) { + const graph = pyGet(canonical, 'prompt'); + if (!isDict(graph)) return false; + for (const node of graph.values()) { + if (!isDict(node)) continue; + const name = pyGet(node, 'class_type'), inputs = pyGet(node, 'inputs'); + if (typeof name === 'string' && name.toLowerCase().includes('promptmanager')) return true; + if (isDict(inputs) && inputs.has('search_text')) return true; + } + return false; +} + +/** `_parsed_workflow`: the UI workflow as a dict, or null. */ +function parsedWorkflow(value) { + if (typeof value === 'string') { + try { value = pyJsonLoads(value); } catch (error) { + if (error instanceof PyValueError) return null; + throw error; + } + } + return isDict(value) ? value : null; +} + +/** + * `inspect_prompt_evidence(records, None, profile=INSPECTION_PROFILE)`: `{prompts, resolution}` for the records a + * local read found (`{prompt, workflow, parameters, comfyassets_prompt_pairs}` texts). `semantics` is + * `compileSemantics(...)`'s table, or null when it could not be loaded. + */ +export function resolveLocalEvidence(records, semantics) { + const source = records !== null && typeof records === 'object' ? records : {}; + const metadata = new Map(Object.entries(source).filter(([key]) => ROLE_METADATA_KEYS.has(key))); + const malformedResolution = { state: 'unresolved', sampler_id: null, reason: 'Prompt evidence is malformed', reason_code: 'malformed', node: null }; + if (!metadata.size) { + return { + prompts: { positive: sideOf('absent'), negative: sideOf('absent') }, + resolution: { state: 'absent', sampler_id: null, reason: 'No parsed prompt metadata', reason_code: null, node: null }, + }; + } + const malformed = { prompts: explained({ positive: sideOf('unresolved'), negative: sideOf('unresolved') }, malformedResolution), resolution: malformedResolution }; + if (!metadata.has('prompt') && !metadata.has('parameters')) return malformed; + if (typeof metadata.get('prompt') === 'string') { + try { metadata.set('prompt', pyJsonLoads(metadata.get('prompt'))); } catch (error) { + if (error instanceof PyValueError) return malformed; + throw error; + } + } + const workflow = mayHoldPromptManager(metadata) ? parsedWorkflow(source.workflow ?? null) : null; + if (workflow !== null && metadata.has('prompt')) metadata.set('workflow', workflow); + const resolved = resolve(metadata, semantics); + const state = resolved.state, prompts = {}; + for (const role of ['positive', 'negative']) { + const side = resolved[role]; + const present = side !== null && typeof side === 'object'; + if (state !== 'ambiguous' && present && (role === 'negative' || pyStrip(side.text))) prompts[role] = sideOf('resolved', side.text, side.provenance.text_source); + else if (state === 'resolved' && present) prompts[role] = { ...sideOf('unresolved'), message: EMPTY_POSITIVE }; + else prompts[role] = sideOf(state !== 'resolved' ? state : 'unresolved'); + } + const resolution = { state, sampler_id: resolved.sampler_id, reason: resolved.reason, reason_code: resolved.reason_code, node: resolved.node }; + return { prompts: explained(prompts, resolution), resolution }; +} + diff --git a/web/js/workspace/py-json.mjs b/web/js/workspace/py-json.mjs new file mode 100644 index 00000000..54d7dd92 --- /dev/null +++ b/web/js/workspace/py-json.mjs @@ -0,0 +1,239 @@ +// Python's value model for the local inspection resolver (#249 local Inspect, PR L3): the server's resolver +// (utils/prompt_pair_resolver.py) runs on `json.loads` output, so the browser port reads the same text the same way. +// Objects are `Map`s (insertion order, a repeated key keeps its first position and its last value, as a dict does), +// integers are numbers (or BigInt past 2^53 - 1), floats are `PyFloat`, None is null. Strings are measured, sliced and +// stripped as Python's `str` is: by code point, with `str.isspace()` whitespace. No DOM. + +/** A Python float: distinct from an int (`1.0` is not a link slot, `type(x) is int` is false). */ +export class PyFloat { + constructor(value) { + this.value = value; + Object.freeze(this); + } +} + +/** `ValueError` from `json.loads` (malformed text, or an integer past `sys.int_info.str_digits_check_threshold`). */ +export class PyValueError extends Error { + constructor(message) { + super(message); + this.name = 'PyValueError'; + } +} + +// CPython's default int max str digits (PEP 651 / gh-95778). +const INT_MAX_STR_DIGITS = 4300; +const MAX_SAFE_DIGITS = '9007199254740991'; +const NUMBER = /-?(?:0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?/y; +const STRING_STOP = /["\\\u0000-\u001f]/g; +const HEX4 = /^[0-9a-fA-F]{4}$/; +const ESCAPES = { '"': '"', '\\': '\\', '/': '/', b: '\b', f: '\f', n: '\n', r: '\r', t: '\t' }; +// The C scanner's constants, in its order of checks. +const CONSTANTS = [['null', null], ['true', true], ['false', false], ['NaN', new PyFloat(NaN)], + ['Infinity', new PyFloat(Infinity)], ['-Infinity', new PyFloat(-Infinity)]]; + +export const isDict = value => value instanceof Map; +export const isList = value => Array.isArray(value); +/** `isinstance(value, int) and not isinstance(value, bool)`. */ +export const isInt = value => (typeof value === 'number' && Number.isInteger(value)) || typeof value === 'bigint'; + +function numberValue(match) { + const [literal, fraction, exponent] = match; + if (fraction || exponent) return new PyFloat(Number(literal)); + const digits = literal[0] === '-' ? literal.slice(1) : literal; + if (digits.length > INT_MAX_STR_DIGITS) throw new PyValueError('Exceeds the limit for integer string conversion'); + if (digits.length > MAX_SAFE_DIGITS.length || (digits.length === MAX_SAFE_DIGITS.length && digits > MAX_SAFE_DIGITS)) return BigInt(literal); + // `-0` is the int 0. + return Number(literal) || 0; +} + +/** `json.loads(text)` with Python's defaults (C scanner): NaN/Infinity accepted, a repeated key's last value wins. */ +export function pyJsonLoads(text) { + if (typeof text !== 'string') throw new TypeError('JSON text must be a string'); + if (text.startsWith('')) throw new PyValueError('Unexpected UTF-8 BOM (decode using utf-8-sig)'); + let pos = 0; + const fail = message => new PyValueError(`${message}: char ${pos}`); + const skip = () => { + while (pos < text.length) { + const c = text.charCodeAt(pos); + if (c !== 0x20 && c !== 0x09 && c !== 0x0a && c !== 0x0d) break; + pos++; + } + }; + function string() { + pos++; + let out = ''; + for (;;) { + STRING_STOP.lastIndex = pos; + const stop = STRING_STOP.exec(text); + if (!stop) throw fail('Unterminated string starting at'); + out += text.slice(pos, stop.index); + pos = stop.index + 1; + if (stop[0] === '"') return out; + if (stop[0] !== '\\') throw fail('Invalid control character at'); + const escape = text[pos]; + if (escape === 'u') { + const hex = text.slice(pos + 1, pos + 5); + if (!HEX4.test(hex)) throw fail('Invalid \\uXXXX escape'); + pos += 5; + const code = parseInt(hex, 16); + if (code >= 0xd800 && code <= 0xdbff && text[pos] === '\\' && text[pos + 1] === 'u') { + const low = text.slice(pos + 2, pos + 6); + if (!HEX4.test(low)) throw fail('Invalid \\uXXXX escape'); + const lowCode = parseInt(low, 16); + if (lowCode >= 0xdc00 && lowCode <= 0xdfff) { + out += String.fromCharCode(code, lowCode); + pos += 6; + continue; + } + } + out += String.fromCharCode(code); + } else if (Object.hasOwn(ESCAPES, escape)) { + out += ESCAPES[escape]; + pos++; + } else throw fail('Invalid \\escape'); + } + } + function key() { + if (text[pos] !== '"') throw fail('Expecting property name enclosed in double quotes'); + const name = string(); + skip(); + if (text[pos] !== ':') throw fail("Expecting ':' delimiter"); + pos++; + skip(); + return name; + } + function scalar() { + if (text[pos] === '"') return string(); + for (const [literal, value] of CONSTANTS) { + if (text.startsWith(literal, pos)) { + pos += literal.length; + return value; + } + } + NUMBER.lastIndex = pos; + const match = NUMBER.exec(text); + if (!match) throw fail('Expecting value'); + pos += match[0].length; + return numberValue(match); + } + skip(); + const stack = []; + let result; + for (;;) { + let value; + if (text[pos] === '{') { + pos++; skip(); + const frame = { value: new Map(), object: true, key: null }; + if (text[pos] === '}') pos++; + else { frame.key = key(); stack.push(frame); continue; } + value = frame.value; + } else if (text[pos] === '[') { + pos++; skip(); + const frame = { value: [], object: false }; + if (text[pos] === ']') pos++; + else { stack.push(frame); continue; } + value = frame.value; + } else value = scalar(); + for (;;) { + if (!stack.length) { result = value; break; } + const frame = stack[stack.length - 1]; + if (frame.object) frame.value.set(frame.key, value); + else frame.value.push(value); + skip(); + if (text[pos] === ',') { + pos++; skip(); + if (frame.object) frame.key = key(); + break; + } + if (text[pos] !== (frame.object ? '}' : ']')) throw fail("Expecting ',' delimiter"); + pos++; + stack.pop(); + value = frame.value; + } + if (!stack.length) break; + } + skip(); + if (pos !== text.length) throw fail('Extra data'); + return result; +} + +/** `len(text)`: code points (a lone surrogate counts once). */ +export function pyLen(text) { + let pairs = 0; + for (let index = 0; index < text.length - 1; index++) { + const code = text.charCodeAt(index); + if (code >= 0xd800 && code <= 0xdbff) { + const next = text.charCodeAt(index + 1); + if (next >= 0xdc00 && next <= 0xdfff) { pairs++; index++; } + } + } + return text.length - pairs; +} + +/** `text[:count]` by code points. */ +export function pySlice(text, count) { + if (text.length <= count) return text; + let end = 0; + for (let taken = 0; taken < count && end < text.length; taken++) { + const code = text.charCodeAt(end); + const next = text.charCodeAt(end + 1); + end += code >= 0xd800 && code <= 0xdbff && next >= 0xdc00 && next <= 0xdfff ? 2 : 1; + } + return text.slice(0, end); +} + +// `str.isspace()`: Unicode Zs plus the bidi classes B, S and WS (not U+FEFF, unlike `trim()`). +const SPACE = '\\t\\n\\x0b\\x0c\\r\\x1c-\\x1f \\x85\\xa0\\u1680\\u2000-\\u200a\\u2028\\u2029\\u202f\\u205f\\u3000'; +const LEADING = new RegExp(`^[${SPACE}]+`), TRAILING = new RegExp(`[${SPACE}]+$`); +/** `text.strip()`. */ +export const pyStrip = text => text.replace(LEADING, '').replace(TRAILING, ''); + +/** `bool(value)`. */ +export function pyTruthy(value) { + if (value === null || value === undefined || value === false) return false; + if (value === true) return true; + if (typeof value === 'number') return value !== 0; + if (typeof value === 'bigint') return value !== 0n; + if (value instanceof PyFloat) return value.value !== 0; + if (typeof value === 'string' || isList(value)) return value.length > 0; + if (isDict(value)) return value.size > 0; + return true; +} + +/** `value == 1` (True and 1.0 equal it too). */ +export const pyEqualsOne = value => value === 1 || value === 1n || value === true || (value instanceof PyFloat && value.value === 1); + +/** `repr(float)`: the shortest round-trip digits, fixed for exponents -4..15, else `d.ddde+XX`. */ +export function pyFloatRepr(value) { + if (Number.isNaN(value)) return 'nan'; + if (!Number.isFinite(value)) return value > 0 ? 'inf' : '-inf'; + if (value === 0) return Object.is(value, -0) ? '-0.0' : '0.0'; + const [mantissa, exponentText] = value.toExponential().split('e'); + const exponent = Number(exponentText); + const sign = mantissa.startsWith('-') ? '-' : ''; + const digits = mantissa.replace(/^-/, '').replace('.', ''); + if (exponent < -4 || exponent >= 16) { + const rest = digits.slice(1); + return `${sign}${digits[0]}${rest ? `.${rest}` : ''}e${exponent < 0 ? '-' : '+'}${String(Math.abs(exponent)).padStart(2, '0')}`; + } + if (exponent < 0) return `${sign}0.${'0'.repeat(-exponent - 1)}${digits}`; + const whole = digits.slice(0, exponent + 1).padEnd(exponent + 1, '0'), fraction = digits.slice(exponent + 1); + return `${sign}${whole}.${fraction || '0'}`; +} + +/** + * `str(value)` where the resolver compares the result with node class names (`str(node.get("class_type", ""))`). + * A container's text never equals a class name, so it is a marker only. + */ +export function pyStr(value) { + if (typeof value === 'string') return value; + if (value === null || value === undefined) return 'None'; + if (value === true) return 'True'; + if (value === false) return 'False'; + if (typeof value === 'number' || typeof value === 'bigint') return String(value); + if (value instanceof PyFloat) return pyFloatRepr(value.value); + return '\u0000container'; +} + +/** `mapping.get(key, fallback)`. */ +export const pyGet = (mapping, key, fallback = null) => mapping.has(key) ? mapping.get(key) : fallback;