Commit Graph
5 Commits
Author SHA1 Message Date
James VeitchandClaude Sonnet 5 24119e3ab6 feat(format-string): add fromjson Jinja2 filter
ComfyUI has no native list/array socket type — FormatString's dynamic
inputs are always STRING (see update_widget). Passing a list of values
(e.g. extraction hints) into a {% for %} loop therefore requires either
manual comma-splitting or a way to carry structured data through a
STRING socket as JSON text.

Jinja2 ships `tojson` but not its inverse. Register `fromjson` (a thin
wrapper over json.loads) on FormatString.jinja_env so a STRING input
containing a JSON array/object can be parsed back into real Python data:

    {% for hint in extraction_hints | fromjson %}
    - {{ hint }}
    {% endfor %}

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YArD9ZjBWKsAvazmS48amA
2026-07-24 22:40:08 +01:00
James VeitchandClaude Sonnet 5 e534fac121 fix(format-string): extract Jinja2 template variables via AST, not regex
FormatString._extract_keys used hand-rolled regexes to detect variables
in Jinja2 templates, which broke on anything beyond bare {{ var }} and
{{ var | filter }}:

- {% for hint in extraction_hints %}{{ hint }}{% endfor %} incorrectly
  surfaced the loop-local `hint` as a required input and never detected
  `extraction_hints` itself, since the control-structure regex only
  matched filter syntax (word followed by `|`).
- {% if extraction_hints is defined %} never matched at all.
- Filters called with arguments, e.g. {{ x | tojson(indent=2) }}, broke
  the regex's anchor to the closing `}}` and silently extracted nothing.

Replaced with jinja2.meta.find_undeclared_variables() over the parsed
AST, which handles all of Jinja2's syntax correctly and excludes names
bound within the template (loop targets, {% set %}) by construction.
Since that call returns an unordered set, sort by first textual
occurrence to keep extraction order deterministic for callers that rely
on positional outputs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YArD9ZjBWKsAvazmS48amA
2026-07-24 21:59:23 +01:00
James VeitchandClaude Sonnet 5 eef0f1ff59 feat(format-string): inline read-only display of formatted_string
FormatString is now OUTPUT_NODE=True and returns {"ui": {"text": [...]},
"result": (...)} instead of a bare tuple, so the rendered output shows
directly on the node — no separate Show Text node needed to inspect it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 13:43:37 +01:00
darth-veitcher 522b7978e0 progress 2025-11-05 12:54:02 +00:00
darth-veitcher 130c57f88b Add comprehensive pytest test suite and fix FormatString node issues
- Fixed Jinja2 regex pattern to handle spaces around filters ({{ var | filter }})
- Added null safety in IS_CHANGED method for empty/None templates
- Restored dynamic output functionality for variable chaining
- Created 47 comprehensive tests with 78% coverage on format_string.py
- Set up test infrastructure with ComfyUI dependency mocking
- Used importlib to bypass package imports during testing
- Added conditional imports in root __init__.py for test compatibility
- Configured pytest in pyproject.toml (removed outdated pytest.ini)
- Added pytest and pytest-cov to dev dependencies
- Updated .gitignore for test artifacts
- Removed deprecated model_unload.py
2025-11-05 11:59:31 +00:00