Files
wildminder-ComfyUI-Chatterbox/__init__.py
T
WildAi 896c6c34df feat(ui): toast node errors in the web ui
Core app logged execution_error without a toast; startup note dropped.
2026-10-14 13:26:27 +03:00

84 lines
3.5 KiB
Python

"""ComfyUI-Chatterbox entry point.
ComfyUI imports this module for one reason: to find ``comfy_entrypoint``, the
async factory that hands back the :class:`~comfy_api.latest.ComfyExtension`
holding this package's nodes. That is all a V3 custom node exposes -- the V1
``NODE_CLASS_MAPPINGS`` / ``NODE_DISPLAY_NAME_MAPPINGS`` pair is gone. The one
other name it does expose is ``WEB_DIRECTORY``: ``js/`` ships ``extension.js``,
a plain-ESM extension that turns a failed Chatterbox node execution into a
web-UI toast, and ComfyUI serves that directory at
``/extensions/ComfyUI-Chatterbox/`` for its loader to import at boot.
What happens here, in order, each step degrading rather than raising:
1. **Pytest guard.** pytest imports every ``__init__.py`` it meets during
collection -- including this one -- but imports it parentless, so the
relative imports below would die with "attempted relative import with no
known parent package" before a single test runs. Under pytest the module
therefore exports nothing and returns.
2. **Vendor path.** ``src/`` is appended (never inserted) to ``sys.path`` so the
vendored ``chatterbox`` package resolves, and a pip-installed one still
wins.
3. **Folder registration.** ``tts`` and ``chatterbox`` are registered with
ComfyUI's ``folder_paths`` so voice packs are discoverable.
4. **Model discovery.** The pack directory is scanned once so the dropdowns are
populated on the first request instead of the first click.
5. **Routes.** The ``/chatterbox/*`` API is registered when a ``PromptServer``
is available. A headless or test process has none, and that is not an error.
"""
import sys
if "pytest" in sys.modules:
# Imported parentless by pytest's collection pass; see the module docstring.
__all__: list[str] = []
else:
import logging
import os
import folder_paths
from .modules.api_routes import register_routes
from .modules.folder_registration import register_chatterbox_folders
from .modules.model_discovery import get_chatterbox_model_pack_names
from .modules.vendor_loader import ensure_vendor_on_path
# Declared with the bootstrap, never above the pytest guard: the guard is
# what makes this module importable during collection, and a web directory
# bound there would be a claim the test process cannot back up. ComfyUI
# resolves it against this module's own directory and serves whatever it
# finds at /extensions/ComfyUI-Chatterbox/.
WEB_DIRECTORY = "./js"
# 1. The vendored `chatterbox` package lives in this repository's `src/`.
ensure_vendor_on_path()
# 2. Where voice packs are looked for: `models/tts/chatterbox`.
register_chatterbox_folders(folder_paths)
# 3. One scan now, so the pack dropdown is populated on the frontend's first
# `/object_info` request instead of its first click.
logging.debug(
"[Chatterbox TTS] Found %d Chatterbox voice pack(s).",
len(get_chatterbox_model_pack_names()),
)
# 4. The `/chatterbox/*` API. Only a running server has a `PromptServer`;
# a headless or partially-booted process simply gets no routes.
try:
from server import PromptServer
register_routes(
PromptServer.instance.routes, folder_paths, os.path.dirname(__file__)
)
except Exception as exc:
logging.debug(
"[Chatterbox TTS] The /chatterbox API routes were not registered "
"on this process: %s",
exc,
)
from .chatterbox_nodes import comfy_entrypoint # noqa: E402 (after bootstrap)
__all__ = ["comfy_entrypoint"]