Add scene fragments to portrait prompts after clothing.

Thing, room, yard and climate precipitation can contribute a short prompt when they are in frame, with a budget so chairs stay silent.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leonid Pershin
2026-08-20 23:35:17 +03:00
co-authored by Cursor
parent f046f145ec
commit 3c682a2b74
26 changed files with 1020 additions and 26 deletions
@@ -109,6 +109,65 @@ public class PortraitPromptBuilderTests
Assert.Contains("wearing a torn white shirt", positive, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void Build_AppendsSceneAfterClothing()
{
var profile = SamplePreset().ToProfile(PortraitKind.Avatar);
var scene = new PortraitScene(
["a classroom blackboard with chalk notes"],
[],
[],
[],
[new SwarmUiLoraEntry { Name = "winter-embed", Weight = 1 }],
[]);
var (positive, _) = PortraitPromptBuilder.Build(SampleCard(), profile, PortraitKind.Avatar, scene: scene);
var clothesAt = positive.IndexOf("wearing a white shirt", StringComparison.OrdinalIgnoreCase);
var sceneAt = positive.IndexOf("a classroom blackboard with chalk notes", StringComparison.Ordinal);
Assert.True(clothesAt >= 0 && sceneAt > clothesAt);
Assert.Contains("<embed:winter-embed>", positive, StringComparison.Ordinal);
Assert.DoesNotContain("snow.safetensors", positive, StringComparison.Ordinal);
}
[Fact]
public void Build_DoesNotPutSceneLoraInText_ApplySceneAddsLoraParams()
{
var profile = SamplePreset().ToProfile(PortraitKind.Avatar);
var scene = new PortraitScene(
["a winter prop"],
[],
[new SwarmUiLoraEntry { Name = "snow.safetensors", Weight = 0.7 }],
[],
[],
[]);
var (positive, _) = PortraitPromptBuilder.Build(SampleCard(), profile, PortraitKind.Avatar, scene: scene);
var withLoras = PortraitPromptBuilder.ApplyScene(profile, scene);
Assert.Contains("a winter prop", positive, StringComparison.Ordinal);
Assert.DoesNotContain("snow.safetensors", positive, StringComparison.Ordinal);
Assert.DoesNotContain("<lora:", positive, StringComparison.Ordinal);
Assert.Contains(withLoras.PositiveLoras, entry => entry.Name == "snow.safetensors");
}
[Fact]
public void Build_PromptAndGenerateShareTheSameAssembly()
{
var profile = SamplePreset().ToProfile(PortraitKind.Avatar);
var scene = new PortraitScene(
["a classroom blackboard with chalk notes"],
["messy desk"],
[new SwarmUiLoraEntry { Name = "snow.safetensors", Weight = 0.7 }],
[],
[new SwarmUiLoraEntry { Name = "winter-embed", Weight = 1 }],
[]);
var prompt = PortraitPromptBuilder.Build(SampleCard(), profile, PortraitKind.Avatar, scene: scene);
var generate = PortraitPromptBuilder.Build(SampleCard(), profile, PortraitKind.Avatar, scene: scene);
Assert.Equal(prompt, generate);
Assert.Contains("<embed:winter-embed>", prompt.Positive, StringComparison.Ordinal);
Assert.Contains("messy desk", prompt.Negative, StringComparison.Ordinal);
}
private static SwarmUiPresetDefinition SamplePreset()
{
var preset = SwarmUiPresetDefinition.CreateDefault();