From bdead4bc045021415caaa65f659ff94ecc424780 Mon Sep 17 00:00:00 2001 From: zhaog100 Date: Sun, 22 Mar 2026 03:53:01 +0800 Subject: [PATCH 1/2] Add JSON Schema for Prompt API Format Closes #8899 - schemas/prompt.json: Draft-07 JSON Schema documenting the prompt format - Node objects with class_type (required), inputs (required), _meta (optional) - Node links as [source_id, output_index] arrays - Self-validating examples included in schema - docs/api/prompt-schema.md: Documentation with validation rules, examples, and common error types Based on analysis of execution.py:validate_prompt() and server.py --- docs/api/prompt-schema.md | 137 ++++++++++++++++++++++++++++++++++++++ schemas/prompt.json | 92 +++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 docs/api/prompt-schema.md create mode 100644 schemas/prompt.json diff --git a/docs/api/prompt-schema.md b/docs/api/prompt-schema.md new file mode 100644 index 000000000..48d1bb289 --- /dev/null +++ b/docs/api/prompt-schema.md @@ -0,0 +1,137 @@ +# ComfyUI Prompt API Schema + +This document describes the JSON format used by the `/prompt` endpoint in ComfyUI. + +## Overview + +A ComfyUI prompt is a JSON object where: +- **Keys** are unique node IDs (arbitrary strings, typically numeric) +- **Values** are node objects containing `class_type`, `inputs`, and optional `_meta` + +## Format Specification + +### Node Object + +```json +{ + "class_type": "KSampler", + "inputs": { + "seed": 123456, + "steps": 20, + "model": ["4", 0] + }, + "_meta": { + "title": "My KSampler" + } +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `class_type` | string | ✅ | Must match a registered node class in `NODE_CLASS_MAPPINGS` | +| `inputs` | object | ✅ | Input parameters for the node | +| `_meta` | object | ❌ | UI metadata (display title, position, etc.) | + +### Input Values + +Each input can be one of two types: + +#### Direct Value +Any JSON-serializable value: +```json +{"seed": 123456, "steps": 20, "cfg": 7.0, "width": 512} +``` + +#### Node Link (Output Reference) +A 2-element array `[source_node_id, output_index]`: +```json +{"model": ["4", 0], "positive": ["6", 0]} +``` + +### Validation Rules + +Based on `execution.py:validate_prompt()`: + +1. Every node **must** have a `class_type` field +2. `class_type` **must** reference a registered node (existing in `NODE_CLASS_MAPPINGS`) +3. The prompt **must** contain at least one `OUTPUT_NODE` +4. All linked inputs must reference valid node IDs and output indices +5. Required inputs for each node class must be provided + +### Common Error Types + +| Type | Description | +|------|-------------| +| `missing_node_type` | Node has no `class_type` or class not found | +| `prompt_no_outputs` | No OUTPUT_NODE found in the prompt | + +## Validation + +Use the JSON Schema to validate prompts: + +```bash +# Using ajv-cli +npx ajv validate -s schemas/prompt.json -d my_prompt.json + +# Using Python +pip install jsonschema +python -c " +import json, jsonschema +with open('schemas/prompt.json') as f: + schema = json.load(f) +with open('my_prompt.json') as f: + prompt = json.load(f) +jsonschema.validate(prompt, schema) +print('Valid!') +" +``` + +## Minimal Example + +```json +{ + "1": { + "class_type": "CheckpointLoaderSimple", + "inputs": {"ckpt_name": "model.safetensors"} + }, + "2": { + "class_type": "CLIPTextEncode", + "inputs": {"text": "hello world", "clip": ["1", 1]} + }, + "3": { + "class_type": "EmptyLatentImage", + "inputs": {"width": 512, "height": 512, "batch_size": 1} + }, + "4": { + "class_type": "KSampler", + "inputs": { + "seed": 0, "steps": 20, "cfg": 7, + "sampler_name": "euler", "scheduler": "normal", + "denoise": 1, "model": ["1", 0], + "positive": ["2", 0], "negative": ["2", 0], + "latent_image": ["3", 0] + } + }, + "5": { + "class_type": "VAEDecode", + "inputs": {"samples": ["4", 0], "vae": ["1", 2]} + }, + "6": { + "class_type": "SaveImage", + "inputs": {"filename_prefix": "test", "images": ["5", 0]} + } +} +``` + +## Workflow vs Prompt Format + +The **prompt format** (this schema) is the compact API format used by `/prompt`. + +The **workflow format** is the UI serialization format that includes additional layout data, group information, and node positions. Workflows are converted to prompts before execution. + +## Future Enhancements + +This schema documents the current static format. Future versions may include: +- Per-node schemas with required/optional input definitions +- Dynamic schema generation based on installed custom nodes +- LLM-friendly structured output definitions diff --git a/schemas/prompt.json b/schemas/prompt.json new file mode 100644 index 000000000..92bbcf655 --- /dev/null +++ b/schemas/prompt.json @@ -0,0 +1,92 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://github.com/Comfy-Org/ComfyUI/blob/main/schemas/prompt.json", + "title": "ComfyUI Prompt Format", + "description": "JSON Schema for the ComfyUI /prompt endpoint. Each key is a unique node ID, and each value describes a node with its class_type, inputs, and optional metadata.", + "type": "object", + "patternProperties": { + "^[a-zA-Z0-9_-]+$": { + "$ref": "#/definitions/node" + } + }, + "additionalProperties": false, + "definitions": { + "node": { + "type": "object", + "required": ["class_type", "inputs"], + "properties": { + "class_type": { + "type": "string", + "description": "The node class to instantiate. Must match a key in NODE_CLASS_MAPPINGS." + }, + "inputs": { + "$ref": "#/definitions/inputs" + }, + "_meta": { + "type": "object", + "description": "Optional UI metadata for a node.", + "properties": { + "title": { + "type": "string", + "description": "Display title for the node in the UI." + } + } + } + }, + "additionalProperties": false + }, + "inputs": { + "type": "object", + "description": "Node inputs. Keys are parameter names. Values are either direct values or node links [source_id, output_index].", + "additionalProperties": true + }, + "node_link": { + "type": "array", + "description": "A link to another node's output.", + "items": [ + {"type": "string", "description": "Source node ID"}, + {"type": "integer", "description": "Output index of the source node"} + ], + "minItems": 2, + "maxItems": 2 + } + }, + "examples": [ + { + "4": { + "class_type": "CheckpointLoaderSimple", + "inputs": {"ckpt_name": "v1-5-pruned-emaonly.safetensors"} + }, + "5": { + "class_type": "EmptyLatentImage", + "inputs": {"width": 512, "height": 512, "batch_size": 1} + }, + "6": { + "class_type": "CLIPTextEncode", + "inputs": {"text": "a beautiful landscape", "clip": ["4", 1]} + }, + "7": { + "class_type": "CLIPTextEncode", + "inputs": {"text": "ugly, blurry", "clip": ["4", 1]} + }, + "3": { + "class_type": "KSampler", + "inputs": { + "seed": 123456, "steps": 20, "cfg": 7.0, + "sampler_name": "euler", "scheduler": "normal", "denoise": 1.0, + "model": ["4", 0], "positive": ["6", 0], "negative": ["7", 0], + "latent_image": ["5", 0] + } + }, + "8": { + "class_type": "VAEDecode", + "inputs": {"samples": ["3", 0], "vae": ["4", 2]}, + "_meta": {"title": "VAE Decode"} + }, + "9": { + "class_type": "SaveImage", + "inputs": {"filename_prefix": "ComfyUI", "images": ["8", 0]} + } + } + ] +} From 3f627561f0a2dc0f8b3c7c4398ff8e4f60a88218 Mon Sep 17 00:00:00 2001 From: zhaog100 Date: Sun, 22 Mar 2026 13:27:36 +0800 Subject: [PATCH 2/2] fix: relax JSON Schema constraints for node IDs and properties - Remove strict patternProperties regex for node IDs (runtime allows any string key) - Change node additionalProperties to true (runtime allows extra metadata fields) - Update docs to clarify node ID format is not constrained by schema Fixes coderabbit Major review comments on #13094 --- schemas/prompt.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/schemas/prompt.json b/schemas/prompt.json index 92bbcf655..3bbb8f13e 100644 --- a/schemas/prompt.json +++ b/schemas/prompt.json @@ -4,12 +4,9 @@ "title": "ComfyUI Prompt Format", "description": "JSON Schema for the ComfyUI /prompt endpoint. Each key is a unique node ID, and each value describes a node with its class_type, inputs, and optional metadata.", "type": "object", - "patternProperties": { - "^[a-zA-Z0-9_-]+$": { - "$ref": "#/definitions/node" - } + "additionalProperties": { + "$ref": "#/definitions/node" }, - "additionalProperties": false, "definitions": { "node": { "type": "object", @@ -33,7 +30,7 @@ } } }, - "additionalProperties": false + "additionalProperties": true }, "inputs": { "type": "object",