Files
transcendedhacker-Mode_pers…/ARCHITECTURE.md
T
transcendedhacker af352d46ed Add modular prompt system with clean architecture
Introduces a scalable, production-grade prompt composition system for ComfyUI. Adds pure data libraries, schema-driven rules, a content-agnostic engine, and minimal node interface. Includes documentation (ARCHITECTURE.md, MIGRATION.md, QUICKSTART.md, README.md), three example libraries, and schema configuration for block order, weights, and model profiles.
2026-01-17 20:12:02 +05:30

4.6 KiB

Architecture Documentation

Philosophy

Pure Separation of Concerns

  • Libraries = Pure data (no syntax, no weights, no formatting)
  • Schema = Rules defining interpretation (ordering, weights, model profiles)
  • Engine = Content-agnostic composition logic
  • Node = Minimal interface wiring it all together

This allows infinite scalability without touching code.


Folder Structure

Mode_personal_node/
├── __init__.py                 # ComfyUI node interface
├── engine/
│   └── composer.py             # Core composition engine
├── schema/
│   └── connector.json          # Rules and structure
└── libraries/
    ├── realistic_portrait.json
    ├── fantasy_theme.json
    └── cyberpunk_urban.json

How It Works

1. Libraries (Pure Data)

Libraries contain ONLY text descriptions, organized into blocks:

{
  "meta": {
    "name": "Library Name",
    "description": "What this library is for"
  },
  "blocks": {
    "character": {
      "Option Name": "Pure text description"
    },
    "scene": { ... },
    "emotion": { ... }
  }
}

NO weights, NO BREAK, NO syntax - just clean data.

2. Schema (Rules)

The connector defines HOW to interpret libraries:

{
  "structure": {
    "block_order": ["character", "scene", ...],
    "separator": ", ",
    "break_positions": [4, 6]
  },
  "weights": {
    "character": 1.1,
    "emotion": 1.2
  },
  "models": {
    "sdxl": { "weight_multiplier": 1.0 },
    "flux": { "weight_multiplier": 0.85 }
  }
}

3. Engine (Logic)

The composer reads schema + libraries and produces final prompts:

composer.compose(
    library_id="realistic_portrait",
    selections={"character": "Classic Beauty", ...},
    model_profile="sdxl"
)

Output:

(A woman with soft features:1.1), in apartment, ...

4. Node (Interface)

Minimal ComfyUI wrapper that exposes dropdowns and calls composer.


Adding New Libraries

  1. Create libraries/your_theme.json
  2. Follow the structure:
    {
      "meta": { "name": "Theme Name" },
      "blocks": {
        "character": {},
        "scene": {},
        "emotion": {},
        "wardrobe": {},
        "photography": {},
        "technical": {}
      }
    }
    
  3. Restart ComfyUI
  4. New library appears in dropdown

No code changes needed.


Customizing Behavior

Change block order:

Edit schema/connector.json → structure.block_order

Change weights:

Edit schema/connector.json → weights

Add BREAK positions:

Edit schema/connector.json → structure.break_positions

Adjust model profiles:

Edit schema/connector.json → models.sdxl or models.flux


Model Profiles

SDXL

"sdxl": {
  "enable_weights": true,
  "weight_multiplier": 1.0
}

FLUX

"flux": {
  "enable_weights": true,
  "weight_multiplier": 0.85
}

FLUX needs lighter weights, so multiplier is 0.85.


Why This Architecture

Problems with old system:

  • Libraries contained formatting → hard to maintain
  • Weights hardcoded in data → can't change globally
  • Node code knew about content → not scalable
  • Library switching didn't work → dropdowns didn't reload

This system:

  • ✅ Libraries are pure data → easy to create/maintain
  • ✅ Schema defines all rules → change once, affects all
  • ✅ Engine is content-agnostic → infinitely scalable
  • ✅ Clean separation → each part does one thing well

Performance

Old system: 300s generation

  • Likely caused by malformed prompts or inefficient encoding

New system:

  • Clean prompt generation
  • No unnecessary tokens
  • Proper BREAK placement
  • Should return to <100s generation

Migration Notes

From Legacy Dropdown System

Old:

{
  "character": {
    "Name": "(description:1.1) BREAK stuff"
  }
}

New:

{
  "blocks": {
    "character": {
      "Name": "description"
    }
  }
}

Weights and formatting come from schema, not data.


Future Extensibility

Want hierarchical dropdowns? Add to schema:

"dropdown_hierarchy": {
  "character_type": {
    "type": "category",
    "options": ["Natural", "Fantasy", "Cyberpunk"]
  },
  "character": {
    "depends_on": "character_type",
    "filter_by": "category"
  }
}

Engine stays the same, just reads new schema rules.


Key Principle

Data ≠ Logic

Libraries should be pure content that anyone can edit.

Schema should define interpretation rules.

Engine should implement those rules without knowing the content.

This is how you build scalable systems.