From a1026663aed621e70b2e811713d5e29ceade823f Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 31 Jul 2026 23:26:51 +0800 Subject: [PATCH] feat(plugins): externalize ComfyUI provider (#116888) --- docs/help/testing-live.md | 2 +- docs/plugins/plugin-inventory.md | 8 +-- docs/plugins/reference/comfy.md | 2 +- docs/providers/comfy.md | 12 +++- docs/tools/music-generation.md | 5 +- extensions/comfy/README.md | 26 ++++++++ extensions/comfy/package.json | 26 +++++++- package.json | 1 + .../official-external-provider-catalog.json | 63 +++++++++++++++++++ src/cli/plugins-location-bridges.test.ts | 32 ++++++++++ .../official-external-plugin-catalog.test.ts | 18 ++++++ .../bundled-plugin-build-entries.test.ts | 6 ++ 12 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 extensions/comfy/README.md diff --git a/docs/help/testing-live.md b/docs/help/testing-live.md index 54379544d9d1..67e51602457f 100644 --- a/docs/help/testing-live.md +++ b/docs/help/testing-live.md @@ -650,7 +650,7 @@ Docker runners below with an explicit `OPENCLAW_PROFILE_FILE`. - Test: `extensions/comfy/comfy.live.test.ts` - Enable: `OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - Scope: - - Exercises the bundled comfy image, video, and `music_generate` paths + - Exercises the comfy image, video, and `music_generate` paths - Skips each capability unless `plugins.entries.comfy.config.` is configured - Useful after changing comfy workflow submission, polling, downloads, or plugin registration diff --git a/docs/plugins/plugin-inventory.md b/docs/plugins/plugin-inventory.md index 2d106672c913..36d63ae04536 100644 --- a/docs/plugins/plugin-inventory.md +++ b/docs/plugins/plugin-inventory.md @@ -51,7 +51,7 @@ Each entry lists the package, distribution route, and description. ## Core npm package -60 plugins +59 plugins - **[admin-http-rpc](/plugins/reference/admin-http-rpc)** (`@openclaw/admin-http-rpc`) - included in OpenClaw. OpenClaw admin HTTP RPC endpoint. @@ -71,8 +71,6 @@ Each entry lists the package, distribution route, and description. - **[clawrouter](/plugins/reference/clawrouter)** (`@openclaw/clawrouter`) - included in OpenClaw. Adds ClawRouter model provider support to OpenClaw. -- **[comfy](/plugins/reference/comfy)** (`@openclaw/comfy-provider`) - included in OpenClaw. Adds ComfyUI model provider support to OpenClaw. - - **[copilot-proxy](/plugins/reference/copilot-proxy)** (`@openclaw/copilot-proxy`) - included in OpenClaw. Adds Copilot Proxy model provider support to OpenClaw. - **[crabbox](/plugins/reference/crabbox)** (`@openclaw/crabbox-provider`) - included in OpenClaw. Cloud worker provider backed by the Crabbox CLI. @@ -175,7 +173,7 @@ Each entry lists the package, distribution route, and description. ## Official external packages -85 plugins +86 plugins - **[acpx](/plugins/reference/acpx)** (`@openclaw/acpx`) - npm; ClawHub. OpenClaw ACP runtime backend with plugin-owned session and transport management. @@ -207,6 +205,8 @@ Each entry lists the package, distribution route, and description. - **[cohere](/plugins/reference/cohere)** (`@openclaw/cohere-provider`) - npm; ClawHub: `clawhub:@openclaw/cohere-provider`. OpenClaw Cohere provider plugin. +- **[comfy](/plugins/reference/comfy)** (`@openclaw/comfy-provider`) - npm; ClawHub: `clawhub:@openclaw/comfy-provider`. Adds ComfyUI model provider support to OpenClaw. + - **[copilot](/plugins/reference/copilot)** (`@openclaw/copilot`) - npm; ClawHub: `clawhub:@openclaw/copilot`. Registers the GitHub Copilot agent runtime. - **[deepinfra](/plugins/reference/deepinfra)** (`@openclaw/deepinfra-provider`) - npm; ClawHub: `clawhub:@openclaw/deepinfra-provider`. Adds DeepInfra model provider support to OpenClaw. diff --git a/docs/plugins/reference/comfy.md b/docs/plugins/reference/comfy.md index d1675a40e98a..7cbdf7c051c4 100644 --- a/docs/plugins/reference/comfy.md +++ b/docs/plugins/reference/comfy.md @@ -12,7 +12,7 @@ Adds ComfyUI model provider support to OpenClaw. ## Distribution - Package: `@openclaw/comfy-provider` -- Install route: included in OpenClaw +- Install route: npm; ClawHub: `clawhub:@openclaw/comfy-provider` ## Surface diff --git a/docs/providers/comfy.md b/docs/providers/comfy.md index ac7a0b749b74..1a8158004f19 100644 --- a/docs/providers/comfy.md +++ b/docs/providers/comfy.md @@ -4,11 +4,17 @@ title: "ComfyUI" read_when: - You want to use local ComfyUI workflows with OpenClaw - You want to use Comfy Cloud with image, video, or music workflows - - You need the bundled comfy plugin config keys + - You need the comfy plugin config keys --- -OpenClaw ships a bundled `comfy` plugin for workflow-driven ComfyUI runs. The -plugin is entirely workflow-driven: OpenClaw does not map generic `size`, +Install the official `comfy` plugin for workflow-driven ComfyUI runs: + +```bash +openclaw plugins install @openclaw/comfy-provider +openclaw gateway restart +``` + +The plugin is entirely workflow-driven: OpenClaw does not map generic `size`, `aspectRatio`, `resolution`, `durationSeconds`, or TTS-style controls onto your graph. diff --git a/docs/tools/music-generation.md b/docs/tools/music-generation.md index 1990e66f43e8..046cb8e5f7b7 100644 --- a/docs/tools/music-generation.md +++ b/docs/tools/music-generation.md @@ -271,9 +271,8 @@ Automatic fallback across authenticated providers is always enabled. A per-call Workflow-driven and depends on the configured graph plus node mapping - for prompt/output fields. The bundled `comfy` plugin plugs into the - shared `music_generate` tool through the music-generation provider - registry. + for prompt/output fields. The `comfy` plugin plugs into the shared + `music_generate` tool through the music-generation provider registry. Uses fal model endpoints through the shared provider auth path. The diff --git a/extensions/comfy/README.md b/extensions/comfy/README.md new file mode 100644 index 000000000000..c07cac79476d --- /dev/null +++ b/extensions/comfy/README.md @@ -0,0 +1,26 @@ +# @openclaw/comfy-provider + +Official ComfyUI image, video, and music generation provider plugin for +OpenClaw. + +## Install + +```bash +openclaw plugins install @openclaw/comfy-provider +openclaw gateway restart +``` + +## Configure + +Local ComfyUI workflows do not require credentials. Comfy Cloud workflows use +`COMFY_API_KEY` or `COMFY_CLOUD_API_KEY`. + +Full workflow, model, and provider configuration: + +- https://docs.openclaw.ai/providers/comfy + +## Package + +- Plugin id: `comfy` +- Package: `@openclaw/comfy-provider` +- Minimum OpenClaw host: `2026.7.2` diff --git a/extensions/comfy/package.json b/extensions/comfy/package.json index 4ed5d0b51f26..0959cfb41fe9 100644 --- a/extensions/comfy/package.json +++ b/extensions/comfy/package.json @@ -1,8 +1,11 @@ { "name": "@openclaw/comfy-provider", "version": "2026.7.2", - "private": true, - "description": "OpenClaw ComfyUI provider plugin", + "description": "OpenClaw ComfyUI provider plugin.", + "repository": { + "type": "git", + "url": "https://github.com/openclaw/openclaw" + }, "type": "module", "devDependencies": { "@openclaw/plugin-sdk": "workspace:*" @@ -10,6 +13,23 @@ "openclaw": { "extensions": [ "./index.ts" - ] + ], + "install": { + "clawhubSpec": "clawhub:@openclaw/comfy-provider", + "npmSpec": "@openclaw/comfy-provider", + "defaultChoice": "npm", + "minHostVersion": ">=2026.7.2" + }, + "compat": { + "pluginApi": ">=2026.7.2" + }, + "build": { + "openclawVersion": "2026.7.2", + "bundledDist": false + }, + "release": { + "publishToClawHub": true, + "publishToNpm": true + } } } diff --git a/package.json b/package.json index 173497c3b673..4953d0a1cd95 100644 --- a/package.json +++ b/package.json @@ -251,6 +251,7 @@ "!dist/extensions/cerebras/**", "!dist/extensions/chutes/**", "!dist/extensions/cohere/**", + "!dist/extensions/comfy/**", "!dist/extensions/clickclack/**", "!dist/extensions/cloudflare-ai-gateway/**", "!dist/extensions/codex/**", diff --git a/scripts/lib/official-external-provider-catalog.json b/scripts/lib/official-external-provider-catalog.json index fbc85bdb6143..138b422cc752 100644 --- a/scripts/lib/official-external-provider-catalog.json +++ b/scripts/lib/official-external-provider-catalog.json @@ -471,6 +471,69 @@ } } }, + { + "name": "@openclaw/comfy-provider", + "description": "OpenClaw ComfyUI provider plugin.", + "source": "official", + "kind": "provider", + "openclaw": { + "plugin": { + "id": "comfy", + "label": "ComfyUI" + }, + "providers": [ + { + "id": "comfy", + "name": "ComfyUI", + "docs": "/providers/comfy", + "categories": [ + "local", + "cloud", + "media" + ], + "envVars": [ + "COMFY_API_KEY", + "COMFY_CLOUD_API_KEY" + ], + "authChoices": [ + { + "method": "cloud-api-key", + "choiceId": "comfy-cloud-api-key", + "choiceLabel": "Comfy Cloud API key", + "choiceHint": "Required for cloud workflows", + "groupId": "comfy", + "groupLabel": "ComfyUI", + "groupHint": "Local or cloud workflows", + "optionKey": "comfyApiKey", + "cliFlag": "--comfy-api-key", + "cliOption": "--comfy-api-key ", + "cliDescription": "Comfy Cloud API key", + "onboardingScopes": [ + "image-generation" + ] + } + ] + } + ], + "contracts": { + "imageGenerationProviders": [ + "comfy" + ], + "musicGenerationProviders": [ + "comfy" + ], + "videoGenerationProviders": [ + "comfy" + ] + }, + "install": { + "clawhubSpec": "clawhub:@openclaw/comfy-provider", + "npmSpec": "@openclaw/comfy-provider", + "defaultChoice": "npm", + "minHostVersion": ">=2026.7.2" + } + } + }, { "name": "@openclaw/deepinfra-provider", "description": "OpenClaw DeepInfra provider plugin.", diff --git a/src/cli/plugins-location-bridges.test.ts b/src/cli/plugins-location-bridges.test.ts index 629f0b2f9df5..2e088dc315a4 100644 --- a/src/cli/plugins-location-bridges.test.ts +++ b/src/cli/plugins-location-bridges.test.ts @@ -209,6 +209,38 @@ describe("listPersistedBundledPluginLocationBridges", () => { }, ); + it("externalizes the shipped bundled ComfyUI plugin while preserving default enablement", async () => { + readPersistedInstalledPluginIndexMock.mockResolvedValue( + makeIndex({ + pluginId: "comfy", + manifestPath: "/app/dist/extensions/comfy/openclaw.plugin.json", + manifestHash: "hash", + source: "/app/dist/extensions/comfy/index.js", + rootDir: "/app/dist/extensions/comfy", + origin: "bundled", + enabled: true, + enabledByDefault: true, + startup: startupInfo, + compat: [], + packageInstall: { + warnings: [], + }, + }), + ); + loadPluginManifestRegistryForInstalledIndexMock.mockReturnValue(makeRegistry("comfy", [])); + + await expect(listPersistedBundledPluginLocationBridges({})).resolves.toEqual([ + { + bundledPluginId: "comfy", + pluginId: "comfy", + preferredSource: "npm", + npmSpec: "@openclaw/comfy-provider", + clawhubSpec: "clawhub:@openclaw/comfy-provider", + enabledByDefault: true, + }, + ]); + }); + it("does not create a relocation bridge without persisted or official install metadata", async () => { readPersistedInstalledPluginIndexMock.mockResolvedValue( makeIndex({ diff --git a/src/plugins/official-external-plugin-catalog.test.ts b/src/plugins/official-external-plugin-catalog.test.ts index ef6530fa64f0..2377a536283c 100644 --- a/src/plugins/official-external-plugin-catalog.test.ts +++ b/src/plugins/official-external-plugin-catalog.test.ts @@ -2129,6 +2129,24 @@ describe("official external plugin catalog", () => { ]); }); + it("lists ComfyUI as an official external media provider", () => { + const comfy = expectCatalogEntry("comfy"); + const manifest = getOfficialExternalPluginCatalogManifest(comfy); + + expect(resolveOfficialExternalPluginId(comfy)).toBe("comfy"); + expect(resolveOfficialExternalPluginInstall(comfy)).toEqual({ + clawhubSpec: "clawhub:@openclaw/comfy-provider", + npmSpec: "@openclaw/comfy-provider", + defaultChoice: "npm", + minHostVersion: ">=2026.7.2", + }); + expect(manifest?.contracts).toMatchObject({ + imageGenerationProviders: ["comfy"], + musicGenerationProviders: ["comfy"], + videoGenerationProviders: ["comfy"], + }); + }); + it.each([ ["teams-meetings", "@openclaw/teams-meetings", "teams_meetings", "teams"], ["zoom-meetings", "@openclaw/zoom-meetings", "zoom_meetings", "zoom"], diff --git a/test/scripts/bundled-plugin-build-entries.test.ts b/test/scripts/bundled-plugin-build-entries.test.ts index 4577f26a4b90..c16f424ae8f4 100644 --- a/test/scripts/bundled-plugin-build-entries.test.ts +++ b/test/scripts/bundled-plugin-build-entries.test.ts @@ -357,6 +357,12 @@ describe("bundled plugin build entries", () => { expect(artifacts).not.toContain("dist/extensions/vydra/package.json"); }); + it("excludes the externalized ComfyUI provider from bundled artifacts", () => { + const artifacts = listBundledPluginPackArtifacts(); + + expectNoPrefixMatches(artifacts, "dist/extensions/comfy/"); + }); + it("excludes externalized meeting plugins from bundled artifacts", () => { const artifacts = listBundledPluginPackArtifacts();