StillMade AIDeveloper docs
Browse documentation · SDK 0.1.0

ComfyUI Blocks

Package, test, and preview a reviewed core-image workflow.

The reviewed adapter now supports core text-to-image and image-to-image generation. Use CheckpointLoaderSimple, CLIPTextEncode, EmptyLatentImage, KSampler, VAEEncode and VAEDecode with existing PreviewImage output. One installed safetensors checkpoint basename, one sampling pass, batch 1 and at most 40 steps are admitted. Generation dimensions are 64–1024 in multiples of 8, subject to the existing four-megapixel aggregate working budget (1024-square image-to-image can exceed it). The connection must report that checkpoint; filenames do not prove file hashes, licenses or GPU readiness. No weights are downloaded. comfyModelRequirements(workflow) returns the required model names. Text and numeric controls use typed scalar bindings. The import wizard preserves real sample inputs and prepares padded image-to-image fixture copies; project inputs are never silently resized. See examples/comfy-text-to-image.stillmade.json and replace the checkpoint placeholder before review.

A ComfyUI Block is a portable declaration of a reviewed image capability. Users see its controls and resulting image, not its internal node wiring. Start with the complete example.

Import an existing ComfyUI workflow

Choose Import ComfyUI workflow in the import tools, or choose its JSON file with Import package. Export the API format from ComfyUI first; its API documentation describes the numbered node map. Visual exports containing nodes and links cannot be converted without the exact frontend/node definitions and receive export guidance. The importer accepts the prompt map itself or { "prompt": { … } }. A ZIP may contain one workflow.json, workflow_api.json, or *.comfy.json file.

The mapping screen asks for the Block name, description, source license, input and result names, and the main image input/output. Multiple image inputs or outputs require an explicit main choice. Optional semantic roles distinguish source images from character references. Resize controls can stay fixed or become user-editable inputs. Every LoadImage and PreviewImage must be mapped; unknown nodes, dependencies, credentials, cycles, and disconnected processing are rejected. This adapter accepts the reviewed image and diffusion classes listed below, not arbitrary custom-node workflows.

Choose a sample for every image input. The browser creates a copy no larger than 128 pixels per side, with a combined fixture budget, and includes those pixels in the downloaded source. Originals are unchanged. The sample stays local until you explicitly run the backend review. Optional expected dimensions add fixture assertions; leaving them blank still requires a valid decoded single image. Choose sample images you may distribute with this Block.

Continue to tests and preview creates an SDK package, not an installation or a successful test. The existing account connection, real fixtures, separate sample execution, preview, rights review and Confirm Import follow. Importing never republishes third-party code. The original API JSON is retained in manifest.provenance.comfyuiImport.source; execution uses normalized placeholders instead of its saved image filenames. Original _meta.title remains attribution, not executable behavior. Review this retained source before sharing a release.

The downloadable SDK exposes the same static conversion API:

js
import {inspectComfyImport, buildComfyImportPackage}
  from './packages/block-sdk/index.js';
import {comfyImageInvert} from './packages/block-sdk/comfyui-example.js';

// Replace with a supported API export. No backend is contacted by either call.
const raw = structuredClone(comfyImageInvert.comfyui.prompt);
raw['1'].inputs.image = 'my-example.png';
const inspection = inspectComfyImport(raw);
console.log(inspection.inputCandidates, inspection.outputCandidates);

const pkg = buildComfyImportPackage(raw, {
  manifest: {...comfyImageInvert.manifest, id: 'my.invert', name: 'My invert'},
  inputs: comfyImageInvert.comfyui.inputs,
  outputs: comfyImageInvert.comfyui.outputs,
  tests: comfyImageInvert.tests,
});
// Save pkg as JSON, then import it for real backend review and confirmation.

inspectComfyImport(raw) returns format, inert source, normalized prompt, nodes, inputCandidates, outputCandidates, warnings, and execution: "not-run". It does not choose names, roles, primary ports or fixtures. buildComfyImportPackage(raw, {manifest, inputs, outputs, tests}) requires those explicit choices, validates their contracts and selected resize values, and returns a package without execution receipts. Source is limited to 64 KiB and the complete package to the usual bounded JSON/import limits.

Package and runtime contract

Set manifest.runtime to comfyui, entry to src/comfyui.json, and declare permissions: {project: [], capabilities: ["comfyui.execute"]}. The top-level package contains manifest, comfyui, tests, and an optional view. It cannot contain code or recipe. Put the workflow in comfyui or, in an editable folder, src/comfyui.json. Endpoints, tokens, connection IDs, file paths, dependencies, and Python never belong in the package. Input/output types and semantic roles use the same StillMade contract as other Blocks.

The workflow has four fields: schemaVersion: 1, prompt, inputs, and outputs. prompt is an API-format map of numbered nodes with class_type and inputs. Supported core classes are LoadImage, ImageInvert, ImageScale, PreviewImage, CheckpointLoaderSimple, CLIPTextEncode, EmptyLatentImage, KSampler, VAEEncode and VAEDecode. Every node must contribute to a declared output. A LoadImage uses an empty filename placeholder and a binding such as image: {node: "1", input: "image", encoding: "uploaded-image"}. StillMade uploads verified input pixels and supplies the generated basename. Resize controls use encoding: "scalar". An output selects one image from a declared PreviewImage: image: {node: "3", collection: "images", index: 0}.

Each fixture has name, input, and expectations. For example:

json
{"name":"One pixel","input":{"image":{"width":1,"height":1,"data":[20,80,200,255]}},"expectations":{"image":{"kind":"image","count":1,"width":1,"height":1,"maxBytes":4096}}}

Every output requires kind: "image" and count: 1. Optional width, height, maximum encoded bytes, and lowercase sha256 check the host-decoded and re-encoded PNG, not a claimed backend descriptor. Use deterministic hash fixtures when exact image behavior matters. Bounds: 16 nodes, 8 inputs/outputs, one megapixel per single-frame image, and four megapixels total working images. Small inline fixtures fit the four-megabyte import limit. Large media inputs should use existing account-owned media references.

In Settings → ComfyUI connections, save the public HTTPS endpoint and optional bearer token. Tokens use the same stable account encryption key as BYOK with a separate encryption purpose. They are never returned to the browser or guest UI. StillMade rejects private network endpoints, redirects and arbitrary requests. The backend is an explicitly selected service you operate or trust. Checking its core-node schema is compatibility evidence, not attestation of its Python implementation. Desktop loopback and arbitrary custom nodes are not available through this adapter. Reviewed core diffusion nodes may use the backend’s GPU after explicit approval.

Import the JSON or ZIP, choose the connection, and click Run tests and sample. StillMade scans the package, records durable jobs, runs every fixture and a separate sample, decodes outputs, and displays the before/after result. Only then can you confirm rights and Confirm Import. Confirmation revalidates the account/source/connection-bound receipt without silently submitting another job. Changing source, connection revision, backend contract, or an expired receipt requires another review. Saving a connection, opening a page, and custom iframe JavaScript cannot confirm remote execution. Preview runs never install or publish a Block. Cancellation targets only owned jobs; unsupported remote cancellation can leave work running on the selected backend. The SDK rejects a cancelled invocation immediately even if its trusted host callback is still waiting. Source and input contracts are captured before dispatch; editing the caller’s package during execution cannot change output validation.

In a saved project, the host checks edit access and finds a completed review for this exact package and connection. A current backend compatibility check runs without resubmitting fixtures. A successful import review can be reused for project execution after its import-confirmation expiry; changed source, connection revision, backend schema, or security status invalidates that reuse. The host asks for Run in project before submitting the actual project input. If review is required, Run tests and sample and its preview come first, then a separate Run in project action. Custom interfaces cannot skip these actions. Durable production jobs are associated with the saved project. Local demo and Marketplace previews remain samples and cannot claim project access.

Offline validate and pack check and package source. For ComfyUI, pack returns reviewRequired: true and zero executed tests. test and preview return RUNTIME_UNAVAILABLE without a trusted host executor. A host integration may pass options.comfyui(package, input, {signal}) to runPackageAsync or testPackage, returning {outputs, metadata} where every metadata entry has verified width, height, bytes, mimeType: "image/png", frames: 1, and optionally SHA-256. This callback is trusted host code; it is never loaded from a package.

The server supports reviewed ComfyUI packages inside Project Types through the account-bound envelope below. The import wizard opens each included ComfyUI Block in its connection review panel. Unattended ComfyUI automation remains unavailable. Existing recipe/JavaScript Project Types and exact-output fixture checks are unchanged.

ComfyUI packages in Project Types: host integration

The offline CLI can package ComfyUI-only or mixed hosted/local Project Types:

sh
node packages/block-cli/cli.js validate ./workflow.json
node packages/block-cli/cli.js pack ./workflow.json ./workflow.stillmade.json

This performs static/schema checks on every embedded package and preserves exact source. It never runs a provider, connects to ComfyUI, or executes local fixtures. The result explicitly reports tests: 0, reviewRequired: true, liveVerified: false, and workflowComplete: false. Import the result into StillMade for authenticated backend review, local tests, sample execution, and user confirmation. Unsupported ComfyUI nodes still fail the static package scan.

The authenticated review/import/release/install APIs accept typeComfyuiReviews alongside typeCapabilityReviews. It is request metadata, never portable source:

json
{
  "typeComfyuiReviews": {
    "<exact package SHA-256>": {
      "receiptId": "<account review UUID>",
      "connectionId": "<account connection UUID>",
      "connectionRevision": 1
    }
  }
}

Provide exactly one entry for every embedded ComfyUI package, including unused or disabled packages. The server authenticates every fixture and sample against the selected backend contract, then checks the ledger again at the save boundary. Missing, expired, foreign, cancelled, or changed-connection evidence is rejected. Saved imports, release reports, and installation reports retain the fixture and sample media. Another account must provide its own reviews. No prompt is submitted by receipt verification.

A trusted SDK host can supply verifyComfyPackage in the third argument to verifyHostedProjectTypePackages(type, verifyCapabilityPackage, options). The callback must return the server-verified Block report, including receiptId, connectionId, and connectionRevision. The resulting opaque handle supports testProjectType and previewProjectType; JSON claims cannot substitute for it. Offline rehearsal defers reviewed ComfyUI execution and its dependent outputs. Interactive rehearsal requires verifyHostedResult before downstream execution; retained run metadata uses comfyuiRun. A passing package admission report still does not prove that the complete connected workflow ran.

In the import or builder review, choose Review Block beside each ComfyUI package, select your connection, and run its tests/sample (or reuse a fresh matching review). Finish the package checks, inspect the result, and confirm import. Connected workflow preview separately confirms each ComfyUI execution and refetches its exact run evidence before handing images downstream. These interactive controls do not enable unattended remote execution.

Connected ComfyUI execution in a project

Run connected steps can continue through ComfyUI Blocks when you approve each run on your account connection. It reuses the existing reviewed-connection dialog; missing fixtures require a separate review before the project input runs. Image references reach the broker intact, so the server can check project access and bind the exact input. Local image processors decode accepted images as needed.

The host uses planSegment(..., {interactive: true}) and supplies an authenticated verifyHostedResult callback to runSegment. ComfyUI results retain comfyuiRun and mediaReceipts; hosted model results retain capabilityRun. These callbacks are trusted StillMade integration code, never imported Block code. A resumed run or Use results re-fetches and verifies each remote result against the current project, source, inputs, and connection metadata before accepting it. Waiting for consent or a remote backend does not consume the local computation budget.

Cancellation or failed verification stops downstream work and retains earlier completed results for review. The default non-interactive planner still stops at ComfyUI or hosted model Blocks; future-media automation cannot submit those jobs.