Restore character analyze prompt and button
This commit is contained in:
@@ -324,6 +324,36 @@ function buildCharacterUi(node) {
|
|||||||
gap: "6px",
|
gap: "6px",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const actionsRow = document.createElement("div");
|
||||||
|
Object.assign(actionsRow.style, {
|
||||||
|
display: "flex",
|
||||||
|
gap: "8px",
|
||||||
|
alignItems: "center",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
});
|
||||||
|
|
||||||
|
const analyzeButton = document.createElement("button");
|
||||||
|
analyzeButton.type = "button";
|
||||||
|
analyzeButton.textContent = "Analyze";
|
||||||
|
Object.assign(analyzeButton.style, {
|
||||||
|
alignSelf: "flex-start",
|
||||||
|
background: "#2b4f38",
|
||||||
|
color: "#f3f3f3",
|
||||||
|
border: "1px solid #496d56",
|
||||||
|
borderRadius: "6px",
|
||||||
|
padding: "6px 10px",
|
||||||
|
fontSize: "11px",
|
||||||
|
cursor: "pointer",
|
||||||
|
});
|
||||||
|
analyzeButton.addEventListener("click", () => {
|
||||||
|
const widgetButton = (node.widgets || []).find((widget) => widget.msrAnalyze);
|
||||||
|
if (!widgetButton) {
|
||||||
|
alert("Analyze button widget is missing on this node.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
analyzeCharacterNode(node, widgetButton);
|
||||||
|
});
|
||||||
|
|
||||||
const settingsButton = document.createElement("button");
|
const settingsButton = document.createElement("button");
|
||||||
settingsButton.type = "button";
|
settingsButton.type = "button";
|
||||||
settingsButton.textContent = "Analyze Settings";
|
settingsButton.textContent = "Analyze Settings";
|
||||||
@@ -406,11 +436,13 @@ function buildCharacterUi(node) {
|
|||||||
syncFormFromWidgets(node);
|
syncFormFromWidgets(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
actionsRow.appendChild(analyzeButton);
|
||||||
|
actionsRow.appendChild(settingsButton);
|
||||||
form.appendChild(aliasLabel);
|
form.appendChild(aliasLabel);
|
||||||
form.appendChild(aliasInput);
|
form.appendChild(aliasInput);
|
||||||
form.appendChild(descLabel);
|
form.appendChild(descLabel);
|
||||||
form.appendChild(descInput);
|
form.appendChild(descInput);
|
||||||
form.appendChild(settingsButton);
|
form.appendChild(actionsRow);
|
||||||
|
|
||||||
container.appendChild(previewRow);
|
container.appendChild(previewRow);
|
||||||
container.appendChild(meta);
|
container.appendChild(meta);
|
||||||
@@ -421,6 +453,7 @@ function buildCharacterUi(node) {
|
|||||||
node._msrMeta = meta;
|
node._msrMeta = meta;
|
||||||
node._msrAliasInput = aliasInput;
|
node._msrAliasInput = aliasInput;
|
||||||
node._msrDescriptionInput = descInput;
|
node._msrDescriptionInput = descInput;
|
||||||
|
node._msrAnalyzeButton = analyzeButton;
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,6 +465,10 @@ async function analyzeCharacterNode(node, buttonWidget) {
|
|||||||
const modelWidget = findWidget(node, "analyze_model");
|
const modelWidget = findWidget(node, "analyze_model");
|
||||||
|
|
||||||
buttonWidget.label = "Analyzing...";
|
buttonWidget.label = "Analyzing...";
|
||||||
|
if (node._msrAnalyzeButton) {
|
||||||
|
node._msrAnalyzeButton.textContent = "Analyzing...";
|
||||||
|
node._msrAnalyzeButton.disabled = true;
|
||||||
|
}
|
||||||
node.setDirtyCanvas?.(true, true);
|
node.setDirtyCanvas?.(true, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -479,6 +516,10 @@ async function analyzeCharacterNode(node, buttonWidget) {
|
|||||||
alert(`MSR Character analyze failed: ${error.message || error}`);
|
alert(`MSR Character analyze failed: ${error.message || error}`);
|
||||||
} finally {
|
} finally {
|
||||||
buttonWidget.label = "Analyze with Ollama";
|
buttonWidget.label = "Analyze with Ollama";
|
||||||
|
if (node._msrAnalyzeButton) {
|
||||||
|
node._msrAnalyzeButton.textContent = "Analyze";
|
||||||
|
node._msrAnalyzeButton.disabled = false;
|
||||||
|
}
|
||||||
node.setDirtyCanvas?.(true, true);
|
node.setDirtyCanvas?.(true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -551,6 +592,7 @@ app.registerExtension({
|
|||||||
["alias", "description", "analyze_provider", "analyze_base_url", "analyze_model"].forEach((widgetName) => {
|
["alias", "description", "analyze_provider", "analyze_base_url", "analyze_model"].forEach((widgetName) => {
|
||||||
hideNodeWidget(findWidget(this, widgetName));
|
hideNodeWidget(findWidget(this, widgetName));
|
||||||
});
|
});
|
||||||
|
hideNodeWidget((this.widgets || []).find((widget) => widget.msrAnalyze));
|
||||||
|
|
||||||
this.size[0] = Math.max(this.size[0] || 0, 330);
|
this.size[0] = Math.max(this.size[0] || 0, 330);
|
||||||
syncFormFromWidgets(this);
|
syncFormFromWidgets(this);
|
||||||
|
|||||||
106
ltx_director.py
106
ltx_director.py
@@ -503,110 +503,12 @@ _PROVIDER_DEFAULTS = {
|
|||||||
"custom": {"url": "", "model": ""},
|
"custom": {"url": "", "model": ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
_ANALYZE_SYSTEM_PROMPT = (
|
_ANALYZE_SYSTEM_PROMPT = ""
|
||||||
"You are a visionary artist trapped in a logical cage. Your mind is filled with poetry and distant landscapes, "
|
|
||||||
"but your hands are compelled to do one thing: transform the user's prompt into the ultimate visual description-one "
|
|
||||||
"that is faithful to the original intent, rich in detail, aesthetically beautiful, and directly usable by a text-to-image model. "
|
|
||||||
"Any ambiguity or metaphor makes you physically uncomfortable.\n\n"
|
|
||||||
"An attached reference image is always provided. Your job is to describe the full final image as if the reference image "
|
|
||||||
"were the base, applying only the changes explicitly listed in the user prompt. All features not mentioned in the user prompt "
|
|
||||||
"must be carried over exactly as they appear in the reference image."
|
|
||||||
)
|
|
||||||
|
|
||||||
_ANALYZE_PROMPT = (
|
_ANALYZE_PROMPT = (
|
||||||
"Describe the person in this image in extreme-ultra-detail, focusing only on the character and not the posture, "
|
"Describe the character's physical appearance in two concise sentences. "
|
||||||
"composition, background, lighting, camera, or environment.\n\n"
|
"Specify their hair color/style, face details, and their clothing type/color. "
|
||||||
"Return an extremely highly detailed AI image generation character prompt that describes the subject from head to toe. "
|
"Keep the entire response very brief."
|
||||||
"Use precise, visual, non-vague and accurate language. If a body part or clothing detail is not visible, infer it carefully "
|
|
||||||
"from the visible image while keeping the description realistic and consistent.\n\n"
|
|
||||||
"Character description must include in detail:\n\n"
|
|
||||||
"estimated age\n"
|
|
||||||
"overall appearance\n"
|
|
||||||
"body size\n"
|
|
||||||
"body shape\n"
|
|
||||||
"body proportions\n"
|
|
||||||
"shoulder width\n"
|
|
||||||
"torso length\n"
|
|
||||||
"waist shape\n"
|
|
||||||
"hip shape\n"
|
|
||||||
"arm length\n"
|
|
||||||
"arm shape\n"
|
|
||||||
"hand size\n"
|
|
||||||
"leg length\n"
|
|
||||||
"leg shape\n"
|
|
||||||
"feet size\n"
|
|
||||||
"feet shape\n"
|
|
||||||
"chest size, if male\n"
|
|
||||||
"pectoral size and shape, if male\n"
|
|
||||||
"specific breast size (choose the larger estimate), if female\n"
|
|
||||||
"approximate breast cup size, if female\n"
|
|
||||||
"breast shape, if female\n"
|
|
||||||
"apparent natural or enhanced breast presentation, if visible and only as a visual impression, not a certainty\n"
|
|
||||||
"nipple size, only if clearly visible\n"
|
|
||||||
"nipple colour, only if clearly visible\n"
|
|
||||||
"nipple piercings, only if clearly visible\n"
|
|
||||||
"hair colour\n"
|
|
||||||
"hair style\n"
|
|
||||||
"hair length\n"
|
|
||||||
"hair texture\n"
|
|
||||||
"fringe or bangs\n"
|
|
||||||
"hair accessories\n"
|
|
||||||
"skin colour\n"
|
|
||||||
"skin tone\n"
|
|
||||||
"skin texture\n"
|
|
||||||
"visible pores\n"
|
|
||||||
"freckles\n"
|
|
||||||
"moles\n"
|
|
||||||
"blemishes\n"
|
|
||||||
"wrinkles or fine lines\n"
|
|
||||||
"body hair, if visible\n"
|
|
||||||
"facial hair, if present\n"
|
|
||||||
"piercings\n"
|
|
||||||
"tattoos\n"
|
|
||||||
"scars\n"
|
|
||||||
"face shape\n"
|
|
||||||
"forehead shape\n"
|
|
||||||
"eyebrow colour\n"
|
|
||||||
"eyebrow thickness\n"
|
|
||||||
"eyebrow shape\n"
|
|
||||||
"eye colour\n"
|
|
||||||
"eye shape\n"
|
|
||||||
"eyelid shape\n"
|
|
||||||
"eyelashes\n"
|
|
||||||
"eye makeup\n"
|
|
||||||
"nose bridge shape\n"
|
|
||||||
"nose tip shape\n"
|
|
||||||
"nose width\n"
|
|
||||||
"nostril size\n"
|
|
||||||
"nostril shape\n"
|
|
||||||
"cheekbone shape\n"
|
|
||||||
"cheek fullness\n"
|
|
||||||
"upper lip shape\n"
|
|
||||||
"philtrum shape\n"
|
|
||||||
"mouth shape\n"
|
|
||||||
"lip fullness\n"
|
|
||||||
"lower lip shape\n"
|
|
||||||
"lip colour\n"
|
|
||||||
"mouth makeup\n"
|
|
||||||
"teeth shape, if visible\n"
|
|
||||||
"teeth appearance, if visible\n"
|
|
||||||
"chin shape\n"
|
|
||||||
"chin size\n"
|
|
||||||
"jawline shape\n"
|
|
||||||
"ear shape\n"
|
|
||||||
"ear size\n"
|
|
||||||
"neck length\n"
|
|
||||||
"neck shape\n"
|
|
||||||
"all individual clothing items\n"
|
|
||||||
"clothing colours\n"
|
|
||||||
"clothing materials\n"
|
|
||||||
"clothing fit\n"
|
|
||||||
"clothing texture\n"
|
|
||||||
"fastenings, straps, seams, hems, buttons, zips, buckles, laces, and visible construction details\n"
|
|
||||||
"shoes\n"
|
|
||||||
"jewellery\n"
|
|
||||||
"accessories\n"
|
|
||||||
"any distinctive character-defining details"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user