Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ REGISTRY = cap-demo-public-registry.cn-hangzhou.cr.aliyuncs.com/cap-app
AGENT_IMAGE ?= $(REGISTRY)/image-generation-comfyui-agent-dev:$(VERSION)
COMFYUI_VERSION ?= v0.3.77
ifeq ($(COMFYUI_VERSION),v0.16.4)
CAP_SYSTEM_VERSION ?= 2.0.3
# 指纹只用裸系统版本号(不带 -vp 后缀),与存量实例 NAS 上记录的版本一致,
# 避免内置依赖指纹变化触发存量 ComfyUI 冷启动时重跑 install_all
CAP_SYSTEM_VERSION ?= 2.0.5
# 指纹只用裸系统版本号(不带 -vp 后缀),与存量实例 NAS 记录保持同一口径。
# 内置插件代码或依赖实质变更时必须 bump,以触发存量项目更新。
BUILTIN_DEPENDENCY_VERSION ?= $(CAP_SYSTEM_VERSION)
else
CAP_SYSTEM_VERSION ?= 1.6.7
Expand Down
14 changes: 14 additions & 0 deletions src/code/comfyui/custom_nodes/funart_prompt_id_compat/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Keep Function Compute task IDs compatible with newer ComfyUI releases."""

from .prompt_id_compat import install_prompt_id_compat


# Install before ComfyUI starts accepting requests. This lives in a dedicated
# built-in plugin so an older FunArt-ComfyUI-APIs copy on a user's NAS cannot
# shadow the compatibility fix during an in-place ComfyUI upgrade.
install_prompt_id_compat()

NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}

__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Compatibility for Function Compute task IDs on newer ComfyUI releases.

ComfyUI v0.27.0 only accepts canonical UUIDs when callers provide a
``prompt_id``. Function Compute task and request IDs are opaque strings, and
the Agent intentionally uses the same value end-to-end for queue, history,
status, and cancellation lookups. Keep that established contract while still
rejecting values that cannot safely be used as dictionary keys.
"""

from typing import Any


_PROBE_ID = "funart-fc-task-id"


def _validate_fc_task_id(value: Any) -> str:
"""Accept non-empty string IDs, matching the pre-v0.27 ComfyUI contract."""
if not isinstance(value, str):
raise ValueError(f"job id must be a string, got {type(value).__name__}")
if not value:
raise ValueError("job id must not be empty")
return value


def install_prompt_id_compat(server_module=None, jobs_module=None) -> bool:
"""Relax UUID-only validation when the running ComfyUI requires it.

``server.py`` imports ``validate_job_id`` into its own module namespace, so
both aliases are replaced. Older ComfyUI versions do not expose the
validator (or already accept opaque IDs) and are left unchanged.

Returns ``True`` when the compatibility validator was installed.
"""
if server_module is None:
try:
import server as server_module
except ImportError:
return False

validator = getattr(server_module, "validate_job_id", None)
if not callable(validator):
return False

try:
validator(_PROBE_ID)
except (AttributeError, TypeError, ValueError):
pass
else:
return False

if jobs_module is None:
try:
from comfy_execution import jobs as jobs_module
except ImportError:
jobs_module = None

server_module.validate_job_id = _validate_fc_task_id
if jobs_module is not None:
jobs_module.validate_job_id = _validate_fc_task_id

print("[FunArt-Prompt-ID-Compat] Function Compute prompt_id compatibility enabled")
return True
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from types import SimpleNamespace
import uuid

import pytest

from funart_prompt_id_compat.prompt_id_compat import install_prompt_id_compat


CANONICAL_UUID = "123e4567-e89b-12d3-a456-426614174000"
FC_REQUEST_ID = "1-6a603c38-1525c9f1-9b1542799d80"


def _uuid_only(value):
"""Match ComfyUI v0.27.0's canonical UUID validator."""
if not isinstance(value, str):
raise ValueError("job id must be a string")
if str(uuid.UUID(value)) != value:
raise ValueError("job id must be a canonical UUID")
return value


@pytest.mark.parametrize("task_id", [FC_REQUEST_ID, "my-task-001", CANONICAL_UUID])
def test_preserves_task_id_across_server_and_jobs_aliases(task_id):
server = SimpleNamespace(validate_job_id=_uuid_only)
jobs = SimpleNamespace(validate_job_id=_uuid_only)

assert install_prompt_id_compat(server, jobs) is True
assert server.validate_job_id(task_id) == task_id
assert jobs.validate_job_id(task_id) == task_id

# Queue/history/status/cancel all use the prompt id as an exact-match key.
# Both aliases must therefore produce the same original FC identifier.
stored = {server.validate_job_id(task_id): "queued"}
assert stored[jobs.validate_job_id(task_id)] == "queued"


def test_rejects_values_that_cannot_be_task_ids():
server = SimpleNamespace(validate_job_id=_uuid_only)
jobs = SimpleNamespace(validate_job_id=_uuid_only)
install_prompt_id_compat(server, jobs)

with pytest.raises(ValueError):
server.validate_job_id(123)
with pytest.raises(ValueError):
server.validate_job_id("")


def test_install_is_idempotent():
server = SimpleNamespace(validate_job_id=_uuid_only)
jobs = SimpleNamespace(validate_job_id=_uuid_only)

assert install_prompt_id_compat(server, jobs) is True
installed_validator = server.validate_job_id
assert install_prompt_id_compat(server, jobs) is False
assert server.validate_job_id is installed_validator
assert jobs.validate_job_id is installed_validator


def test_leaves_older_permissive_validator_unchanged():
def permissive(value):
return value

server = SimpleNamespace(validate_job_id=permissive)

assert install_prompt_id_compat(server) is False
assert server.validate_job_id is permissive


def test_skips_versions_without_job_id_validator():
assert install_prompt_id_compat(SimpleNamespace()) is False
1 change: 1 addition & 0 deletions src/code/comfyui/shared/Dockerfile.template
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ RUN rm -rf ${COMFYUI_DIR}/custom_nodes/Comfy-VisionPlaid && \
RUN mkdir -p /root/built-in/custom_nodes && \
cp -r ${COMFYUI_DIR}/custom_nodes/FunArt-ComfyUI-Multi-User /root/built-in/custom_nodes/ && \
cp -r ${COMFYUI_DIR}/custom_nodes/FunArt-ComfyUI-APIs /root/built-in/custom_nodes/ && \
cp -r ${COMFYUI_DIR}/custom_nodes/funart_prompt_id_compat /root/built-in/custom_nodes/ && \
cp -r ${COMFYUI_DIR}/custom_nodes/Comfy-VisionPlaid /root/built-in/custom_nodes/ && \
echo "${BUILTIN_DEPENDENCY_VERSION}" > /root/built-in/version.txt

Expand Down
8 changes: 4 additions & 4 deletions src/code/comfyui/v0.16.4/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ COMFYUI_VERSION := v0.16.4
CUSTOM_NODES_JSON := comfyui/v0.16.4/custom_nodes.json
OSS_COMFYUI_BASE_DIR := base/comfyui/$(COMFYUI_VERSION)-gamma
OSS_COMFYUI_DEEPGPU_BASE_DIR := base/comfyui/$(COMFYUI_VERSION)-gamma-deepgpu
CAP_SYSTEM_VERSION := 2.0.3
VISION_PLAID_VERSION := 1.2.2
CAP_SYSTEM_VERSION := 2.0.5
VISION_PLAID_VERSION := 1.3.0
BITFORGE_VERSION := 0.2.4
VISION_PLAID_EXTRA_PACKAGES := flashinfer-python flashinfer-cubin
# 指纹回归旧方式:只用 CAP_SYSTEM_VERSION,不编码 VP 版本,
# 防止存量实例因指纹变化在冷启动时触发 install_all
# 指纹只用裸 CAP_SYSTEM_VERSION不编码 VP 后缀。
# 内置插件代码或依赖实质变更时必须 bump,以触发存量项目更新。
BUILTIN_DEPENDENCY_VERSION := $(CAP_SYSTEM_VERSION)

include ../shared/Makefile.common