56 lines
2.6 KiB
Python
56 lines
2.6 KiB
Python
"""Prompt enhancer: a language model rewrites the finished prompt before it is
|
|
encoded. A node-only module, with a small readout route for the Composer.
|
|
|
|
Sits after shortcut expansion and `$variables` (the app resolves both before the
|
|
text reaches the pipeline), so the model is handed exactly the text that would
|
|
otherwise have been encoded. Off by default. Every failure hands the ORIGINAL
|
|
prompt on and says so in the log: a rewrite that did not happen must never empty
|
|
the prompt.
|
|
|
|
One generation per scene -- v5 runs a scene per generation, so a multi-scene
|
|
project is never rewritten as one blob and re-split.
|
|
|
|
Whether a given text encoder writes sensible prose is an open question per model
|
|
(H3's conditioning checkpoint has no trained decoder head; Gemma3/Qwen3 do). v4's
|
|
result: confirmed working on Gemma3-12B. v5 on a rental: works with Gemma 4 E4B (a real rewrite in 2.5 s); H3's own encoder writes no prose, so there the run keeps your prompt and says why. On H3, pick a chat encoder (Gemma 4) in Composer > Enhance > Encoder: verified end to end.
|
|
"""
|
|
|
|
from .nodes import RUNS, FunUIEnhancePrompt
|
|
|
|
ID = "conditioning_prompt_enhancer"
|
|
TITLE = "Prompt enhancer"
|
|
STAGE = "conditioning"
|
|
CATEGORY = "conditioning"
|
|
STATUS = "experimental"
|
|
|
|
NODES = [FunUIEnhancePrompt]
|
|
|
|
|
|
def routes(table, base, web):
|
|
@table.get(base + "/defaults")
|
|
async def _defaults(_req):
|
|
"""What an empty field means, so the Composer can show it."""
|
|
from . import enhance
|
|
return web.json_response({"instructions": enhance.SYSTEM_PROMPT,
|
|
"reference_intro": enhance.REFERENCE_INTRO,
|
|
"styles": enhance.STYLES})
|
|
|
|
@table.get(base + "/runs")
|
|
async def _runs(req):
|
|
"""The last runs' rewrites, newest last. `?prompt_id=` narrows to one run."""
|
|
want = req.rel_url.query.get("prompt_id")
|
|
runs = [r for r in RUNS if not want or r["prompt_id"] == want]
|
|
return web.json_response({"runs": runs})
|
|
|
|
@table.get(base + "/encoders")
|
|
async def _encoders(_req):
|
|
"""Encoder files and families the Enhance panel can offer (read fresh: files come and go)."""
|
|
try:
|
|
from ...loaders.clip import nodes as clip_nodes
|
|
return web.json_response({"files": clip_nodes.encoder_files(), "families": clip_nodes.clip_types()})
|
|
except Exception as exc: # noqa: BLE001 -- the CLIP loader module is another module; its absence empties the picker, not the panel
|
|
return web.json_response({"files": [], "families": [], "why": f"the CLIP loader module is not available: {exc}"})
|
|
|
|
|
|
PROVIDES = {"routes": routes}
|