Skip to content
This repository was archived by the owner on Sep 23, 2026. It is now read-only.

Resolver and Prompt

kunail0804 edited this page Jul 19, 2026 · 1 revision

Resolver & Prompt

Spec reference: MASTER_SPEC §17–19.

The Resolver is the deterministic back half of the pipeline. No Large Language Model is involved in it.

Renamed. This page was "Resolver, Categories & Prompt Builder". V1.1 removed the separate Category Splitter and Prompt Builder stages — the Resolver now does that work itself — so the page is named for what actually ships. Categories still exist, but only as traceability metadata (see Categories).


Resolver

The Resolver converts semantic concepts into Illustrious-compatible tags. It is the first component aware of the target model and is completely deterministic. It ships a single implementation: the Illustrious Resolver.

  • Input: Validated Scene JSON. Output: a flat prompt string (plus the traceable Resolved Tags as JSON for inspection).
  • Must: normalize concepts; resolve aliases; look up canonical concepts; expand; generate Illustrious tags; remove duplicate tags; join the tags into one prompt string; emit warnings.
  • Must not: call an LLM; guess concepts; invent tags; modify Scene JSON.

Pipeline

Concept → Normalize → Alias Resolution → Canonical Concept
        → Knowledge Base Lookup → Expansion → Tag Generation → Resolved Tags
        → join in resolution order → Prompt
  • Normalization — lowercase, trim whitespace, collapse repeated whitespace, Unicode-normalize.
  • Alias resolution & lookup — aliases resolve directly to canonical concepts (girl → female); alias chains are forbidden. Known concepts continue.
  • Head-noun fallback (with modifier preservation) — when a compound concept has no entry, the Resolver drops leading modifiers and looks up the longest matching suffix (white summer dress → dress), emitting an SC0019 (Concept Reduced) warning. As of V2 each dropped modifier is then retried as a <modifier> <head-noun> compound through the normal resolution path and, when it resolves, emitted as its own Resolved Tag in discovery order (open white shirt → white shirt, open shirt). Only the high-precision compound form is tried (never bare single words), so this stays exact and deterministic — no tag is invented — and goldens are unchanged. A concept with no entry even after reduction produces the SC0001 unknown-concept warning.
  • Semantic fallback (V2, opt-in) — see below. When semantic.enabled is on, a concept that misses both deterministic lookup and head-noun reduction gets one last nearest-neighbour attempt against the existing Knowledge Base before being reported unknown.
  • NSFW gating — entries rated explicit are excluded from lookup and expansion unless resolver.include_nsfw is enabled; while disabled, a gated concept resolves as unknown.
  • Expansion — occurs after canonical lookup; recursive; circular expansion is forbidden (detected by the KB loader). Expansion order (normative): a concept emits its own tags first, then, depth-first and in list order, the tags of each expand target, inserted immediately after the concept that generated them. Expansion order is stable. A configurable max expansion depth may be enforced.
  • Unknown concepts — never disappear; the Resolver warns and compilation continues.
  • Duplicate tags — removed after expansion; the first occurrence is kept and ordering preserved. As of V2 this deduplication is gated by prompt_builder.remove_duplicate_tags (default true); when disabled, duplicates are kept and no SC0007 is emitted.
  • Parallel resolution (V2) — for large scenes, independent per-concept resolution can run on a thread pool and merges back in exact discovery order, so output is identical regardless of scheduling. It is threshold-gated and sequential by default.
  • Ordering & category preservation — output preserves discovery order; every tag keeps the category of its Knowledge Base Entry. Categories are never inferred later.

Warnings vs errors

  • Warnings (continue): unknown concept, deprecated concept, invalid expansion, missing Knowledge Base entry.
  • Errors (stop): Knowledge Base unavailable/corrupted, circular expansion, invalid category.

The Resolver should log every decision, e.g.:

gold hair → alias → blonde hair → Knowledge Base `blonde_hair` → tag "blonde hair"

Future Resolvers (Illustrious, Pony, Flux…) consume identical Scene JSON; only the Knowledge Base changes, and the compiler core stays unchanged.

Semantic fallback

Added in V2 and off by default (semantic.enabled). When enabled, a concept that misses both deterministic lookup and head-noun reduction falls back to its nearest Knowledge Base entry in a committed embedding index (data/kb_embedding_index.json), accepted only above semantic.min_similarity and emitting an SC0020 (Semantic Fallback) warning. The default backend (semantic.backend = char_ngram) is a deterministic, offline, dependency-free character-n-gram model.

Guarantees: deterministic lookup always wins; the fallback can only return an entry that already exists in the Knowledge Base, so it can never invent a tag; and identical input yields identical output. Build/refresh the index with scripts/build_embedding_index.py.


Prompt translation

The Resolver is the final stage. After producing the ordered, de-duplicated Resolved Tags, it joins their tag values into a single flat prompt string, comma-separated, in resolution order (character concepts first, then the scene sections). That is the whole "translator" — Scene JSON in, prompt out:

1girl,blonde hair,blue eyes,dress,smile,classroom,sunset

Nothing is reordered, escaped, or optimized at this step, and deduplication already happened during resolution. The Resolver node also emits the Resolved Tags as JSON so a translation problem is inspectable.

Removed in V1.1. Earlier versions split tags into 19 categories (Category Splitter) and emitted one prompt output per category, plus reserved Negative and Scene outputs (Prompt Builder). Those stages and nodes were removed: there is one flat prompt, not per-category outputs. The category field still exists on Knowledge Base entries and Resolved Tags for traceability, but it no longer shapes the output.

Categories (traceability only)

Every Knowledge Base entry still carries exactly one of these 19 categories, surfaced on each Resolved Tag in the json output:

Category Purpose Examples
Character Identity 1girl, 1boy, 2girls
Appearance General appearance young, adult, muscular
Hair Hair-related blonde hair, long hair, ponytail
Face Facial characteristics freckles, beauty mark, lipstick
Eyes Eye-related blue eyes, closed eyes
Expression Emotion smile, crying, blush
Body Body-related abs, tail, wings
Clothing Wearable items dress, shirt, armor
Accessories Portable items glasses, necklace, hat
Pose Static positions standing, kneeling, sitting
Action Independent actions walking, reading, running
Interaction Character relationships hug, holding hands, kiss
Objects Scene objects chair, book, tree
Environment Scene location forest, classroom, beach
Camera Camera descriptors close-up, wide shot, low angle
Lighting Lighting descriptors sunset, moonlight, studio lighting
Style Reserved for workflow integration — (not generated)
Quality Reserved for workflow integration — (not generated)
Miscellaneous Fallback should remain nearly empty
  • Style is reserved for workflow integration; the curated Knowledge Base does not target it, though the generated Danbooru vocabulary maps a few style-ish concepts (e.g. colour scheme) here, so it may occasionally carry a tag. Quality is reserved and never generated in V1.
  • Miscellaneous is a fallback that should stay nearly empty.
  • Composition and Background were considered and intentionally excluded from V1; they may return in a future version.

The category of a concept is decided by the category field of its Knowledge Base Entry, not by the Scene JSON section it appeared in. Style is reserved for workflow integration (the generated vocabulary maps a few style-ish concepts here); Quality is reserved and never generated; Miscellaneous is a rarely used fallback. Composition and Background were intentionally excluded and may return later.

EasyIllustrious compatibility is achieved by connecting the Resolver's prompt output to the appropriate node; the compiler implements no EasyIllustrious-specific logic.

Related pages


A note on AI assistance

This project — its code, tests, and documentation — is built with heavy help from AI coding assistants and maintained by a solo author. AI makes mistakes: despite testing and review, parts of this may be inaccurate, out of date, or wrong. Treat it as a good-faith best effort, not authoritative truth — if the docs and the code disagree, the code wins. Please open an issue when something looks off.

Clone this wiki locally