* chore: initialise BEACON framework with all bootstrap artefacts - Problem statement, constitution, architecture doc, roadmap populated - CHANGELOG.md created (Keep a Changelog); README expanded with What-is-this, Install, and Quickstart sections - pyproject.toml gains [project.urls] (repository + documentation) - beacon doctor: 32 pass, 2 pre-commit warns, 0 failures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: Phase 1 — add NullHandler to package root, remove hardcoded setLevel T001: logging.getLogger("comfydv").addHandler(NullHandler()) in __init__.py T002: remove logger.setLevel(logging.DEBUG) from format_string.py Also fix pyproject.toml TOML structure (project.urls was inside [project] block) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: failing tests for logging modernisation (T010-T through T030-T) RED phase — 5 tests fail for the correct reasons before implementation: T010-T: format_string produces stdout (print block) T011-T: update_widget emits INFO records on hot path T012-T: random_choice produces stdout (colorama/rich prints) T020-T: load_node_state uses print() on error instead of logger.error T021-T: circuit_breaker uses print() instead of logger T001/T002/T030-T already green: NullHandler registered, setLevel removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: standardise logging across all nodes (T010-I through T044) GREEN phase — all 11 logging tests pass: T010-I: Remove 8-line diagnostic print block from format_string() T011-I: Downgrade all hot-path logger.info() calls to logger.debug(); switch all logger calls to %-style formatting; remove rich import T012-I: Replace colorama/termcolor/rich print calls in random_choice with logger.debug(); add logger = logging.getLogger(__name__) T020-I: Convert print() on load_node_state error to logger.error() T021-I: Add logger to circuit_breaker; replace print() with logger.debug(); fix logic so status=False triggers the interrupt (per BDD spec) T040: Remove colorama, rich, termcolor from pyproject.toml dependencies T042: ruff check + format clean T044: beacon doctor --strict passes (34/34) Also adds ADR-001 and ADR-002 capturing the stdlib logging and NullHandler decisions, linked from the logging-modernisation epic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: mark all 001-standardise-logging tasks complete in tasks.md All [x] checkboxes flipped after 11/11 tests pass and beacon doctor --strict reports 0 failures. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: mark logging-modernisation epic success criteria complete All success criteria verified: NullHandler added, setLevel removed, print() calls converted, colorama/rich/termcolor removed from deps, zero stdout in normal operation, errors surface at ERROR level, all tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: commit spec artefacts and dependency lock for 001-standardise-logging Includes spec.md, plan.md, research.md, BDD feature files, contracts, .beacon.toml backlink, and uv.lock after removing colorama/rich/termcolor. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: James Veitch <darthveitcher@office-mac-mini.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
86 lines
3.6 KiB
Markdown
86 lines
3.6 KiB
Markdown
# comfydv
|
|
|
|
A collection of workflow efficiency and quality-of-life nodes built out of necessity for personal ComfyUI use.
|
|
|
|
## What is this?
|
|
|
|
`comfydv` fills gaps in ComfyUI's built-in node library: dynamic string formatting, seed-controlled random selection, and graceful workflow interruption. Install it once and connect the nodes like any other — no Python knowledge required.
|
|
|
|
| Node | What it does |
|
|
|------|-------------|
|
|
| **Format String** | Formats a string from a Python f-string or Jinja2 template. Detects variables in the template and automatically adds/removes input sockets. |
|
|
| **Random Choice** | Accepts any number of typed inputs and outputs one at random, with a configurable seed for reproducibility. |
|
|
| **Circuit Breaker** | Halts the current ComfyUI queue run gracefully (raises `InterruptProcessingException`) without crashing the server. |
|
|
|
|
## Install
|
|
|
|
1. Clone this repo into your ComfyUI `custom_nodes/` directory:
|
|
|
|
```bash
|
|
cd /path/to/ComfyUI/custom_nodes
|
|
git clone https://github.com/darth-veitcher/comfydv.git
|
|
```
|
|
|
|
2. Restart ComfyUI. The nodes appear under the **dv/** category in the node menu.
|
|
|
|
> **Dependencies** (`jinja2`, `rich`, `colorama`, `termcolor`) are listed in `pyproject.toml`. ComfyUI's Python environment must have them installed — run `pip install jinja2 rich colorama termcolor` inside that environment if they are missing.
|
|
|
|
## Quickstart
|
|
|
|
**Format String — simple f-string:**
|
|
|
|
1. Add a **Format String** node to your workflow.
|
|
2. Set `template_type` to `Simple` and enter `Hello {name}` in the template field.
|
|
3. A `name` input socket appears automatically — wire it up or type a value.
|
|
4. Output 0 (`formatted_string`) contains `Hello <your value>`.
|
|
|
|
**Random Choice:**
|
|
|
|
1. Add a **Random Choice** node.
|
|
2. Connect any number of inputs (strings, images, conditioning — any type).
|
|
3. Set `seed` for reproducibility; leave at `0` for a different pick each run.
|
|
4. Output is whichever input was selected.
|
|
|
|
## Documentation
|
|
|
|
Full documentation can be found: [darth-veitcher.github.io/comfydv](https://darth-veitcher.github.io/comfydv/stable/)
|
|
|
|
## String Formatting
|
|
|
|
The FormatString node provides flexible string formatting with dynamic input/output configuration.
|
|
|
|
### Python F-String
|
|
|
|
A simple python f-string dynamically creates the necessary inputs/outputs for the detected keys.
|
|
|
|

|
|
|
|
### Jinja 2
|
|
|
|
Switching to Jinja2 allows you to use more advanced control blocks and other filters/features of that templating language. See [Jinja documentation](https://jinja.palletsprojects.com/en/latest/) for further details.
|
|
|
|

|
|
|
|
### Output Structure
|
|
|
|
The node's outputs are organized for maximum reliability and flexibility:
|
|
|
|
1. **`formatted_string`** (Output 0): The formatted result string - always in position 0
|
|
2. **`saved_file_path`** (Output 1): Path to saved state file (if save_path provided) - always in position 1
|
|
3. **Variable outputs** (Output 2+): Pass-through values for any variables detected in the template, enabling easy chaining
|
|
|
|
For example, with template `"Hello {name}, you are {age}"`:
|
|
|
|
* Output 0: The formatted string (e.g., "Hello Alice, you are 30")
|
|
* Output 1: The save file path (or empty string)
|
|
* Output 2: The value of `name` (e.g., "Alice")
|
|
* Output 3: The value of `age` (e.g., "30")
|
|
|
|
This structure ensures the primary outputs (`formatted_string` and `saved_file_path`) are always in predictable, fixed positions for reliable workflow connections.
|
|
|
|
## Random Choice
|
|
|
|
Ability to take arbitrary length and type of inputs to then output a **choice** with a controllable seed.
|
|
|
|

|