UNPKG

comfyui-mcp

Version:

Local-first, agent-native control plane for ComfyUI — MCP server + autonomous sidebar agent that drives your live graph in natural language on ANY LLM: Claude/ChatGPT/Gemini on your subscription (no API key), free local models via Ollama (fully offline),

96 lines • 3.81 kB
import { createWorkflow } from "./workflow-composer.js"; import { DefaultsManager } from "./defaults-manager.js"; import { ValidationError } from "../utils/errors.js"; const DEFAULTABLE_KEYS = [ "negative_prompt", "width", "height", "steps", "cfg", "sampler", "scheduler", "seed", "checkpoint", ]; function withDefaults(args) { const seed = {}; for (const key of DEFAULTABLE_KEYS) { const v = args[key]; if (v !== undefined) seed[key] = v; } return DefaultsManager.apply(seed); } async function resolveCheckpointOrThrow(explicit, resolved, resolveCheckpoint) { let checkpoint = explicit ?? resolved.checkpoint; if (!checkpoint) checkpoint = await resolveCheckpoint(); if (!checkpoint) { throw new ValidationError("No checkpoint specified, defaulted, or found locally. " + "Pass `checkpoint`, set a default via get_defaults (action:\"set\"), or download one with download_model."); } return checkpoint; } function commonTemplateParams(args, resolved, checkpoint) { return { checkpoint, positive_prompt: args.prompt, negative_prompt: resolved.negative_prompt, width: resolved.width, height: resolved.height, steps: resolved.steps, cfg: resolved.cfg, seed: resolved.seed, sampler_name: resolved.sampler, scheduler: resolved.scheduler, }; } /** * Build + enqueue a ControlNet-conditioned txt2img workflow. `control_image` * must already exist in ComfyUI's input dir (use upload_image (action:"image") first). */ export async function generateWithControlNet(args, deps) { if (!args.control_image) { throw new ValidationError("control_image is required (upload it first with upload_image (action:\"image\"))"); } const resolved = withDefaults(args); const checkpoint = await resolveCheckpointOrThrow(args.checkpoint, resolved, deps.resolveCheckpoint); let controlnetModel = args.controlnet_model; if (!controlnetModel && deps.resolveControlNetModel) { controlnetModel = await deps.resolveControlNetModel(); } if (!controlnetModel) { throw new ValidationError("No controlnet_model specified and none found locally. Pass `controlnet_model` " + "(a file in models/controlnet/) or download one with download_model."); } const workflow = createWorkflow("controlnet", { ...commonTemplateParams(args, resolved, checkpoint), control_image: args.control_image, controlnet_model: controlnetModel, strength: args.strength, }); const { prompt_id, queue_remaining } = await deps.enqueue(workflow); return { prompt_id, queue_remaining, checkpoint }; } /** * Build + enqueue an IP-Adapter-conditioned txt2img workflow. Requires the * ComfyUI_IPAdapter_plus custom nodes. `reference_image` must already exist in * ComfyUI's input dir (use upload_image (action:"image") first). */ export async function generateWithIpAdapter(args, deps) { if (!args.reference_image) { throw new ValidationError("reference_image is required (upload it first with upload_image (action:\"image\"))"); } const resolved = withDefaults(args); const checkpoint = await resolveCheckpointOrThrow(args.checkpoint, resolved, deps.resolveCheckpoint); const workflow = createWorkflow("ip_adapter", { ...commonTemplateParams(args, resolved, checkpoint), reference_image: args.reference_image, weight: args.weight, preset: args.preset, weight_type: args.weight_type, }); const { prompt_id, queue_remaining } = await deps.enqueue(workflow); return { prompt_id, queue_remaining, checkpoint }; } //# sourceMappingURL=generate-conditioned.js.map