Spaces:
Runtime error
Runtime error
fix: simplify creator-first generation flow
Browse files- .gitignore +1 -1
- app.py +220 -115
- docs/HANDOFF_QUOTA_EXHAUST_V4_2.md +142 -0
- src/nexus_visual_weaver/render.py +24 -35
- src/nexus_visual_weaver/styles.py +112 -0
- tests/test_app_callbacks.py +58 -7
- tests/test_command_center.py +5 -6
.gitignore
CHANGED
|
@@ -39,6 +39,7 @@ venv.bak/
|
|
| 39 |
*.pfx
|
| 40 |
.huggingface/
|
| 41 |
.cache/huggingface/
|
|
|
|
| 42 |
.modal.toml
|
| 43 |
.netrc
|
| 44 |
.pypirc
|
|
@@ -66,4 +67,3 @@ Thumbs.db
|
|
| 66 |
.idea/
|
| 67 |
.vscode/
|
| 68 |
tempCodeRunnerFile.py
|
| 69 |
-
|
|
|
|
| 39 |
*.pfx
|
| 40 |
.huggingface/
|
| 41 |
.cache/huggingface/
|
| 42 |
+
.hf-upload-cache/
|
| 43 |
.modal.toml
|
| 44 |
.netrc
|
| 45 |
.pypirc
|
|
|
|
| 67 |
.idea/
|
| 68 |
.vscode/
|
| 69 |
tempCodeRunnerFile.py
|
|
|
app.py
CHANGED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
| 5 |
import os
|
| 6 |
import sys
|
| 7 |
import hashlib
|
|
|
|
| 8 |
from pathlib import Path
|
| 9 |
from typing import Any
|
| 10 |
from urllib.parse import urlparse
|
|
@@ -48,6 +49,17 @@ DEFAULT_PROMPT = (
|
|
| 48 |
|
| 49 |
MODEL_RELAY = WeaverModelRelay()
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
def _default_operator_state() -> dict[str, Any]:
|
| 53 |
return {
|
|
@@ -194,6 +206,9 @@ def _creator_controls(
|
|
| 194 |
palette: str | None = None,
|
| 195 |
hardware: str | None = None,
|
| 196 |
locate_focus: list[str] | None = None,
|
|
|
|
|
|
|
|
|
|
| 197 |
) -> dict[str, Any]:
|
| 198 |
"""
|
| 199 |
Create a control object combining wardrobe selections with generation policy and reasoning configuration.
|
|
@@ -220,10 +235,32 @@ def _creator_controls(
|
|
| 220 |
"flux_primary": "black-forest-labs/FLUX.2-klein-9B",
|
| 221 |
"flux_sidecar": "black-forest-labs/FLUX.2-klein-4B",
|
| 222 |
"lora_policy": "attempt compatible runtime adapter; report loaded/skipped/failed",
|
|
|
|
|
|
|
|
|
|
| 223 |
},
|
| 224 |
}
|
| 225 |
|
| 226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
|
| 228 |
"""
|
| 229 |
Augments a prompt with wardrobe control parameters.
|
|
@@ -247,7 +284,12 @@ def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
|
|
| 247 |
wardrobe.get("hardware"),
|
| 248 |
]
|
| 249 |
suffix = ", ".join(str(item) for item in additions if item)
|
| 250 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 251 |
|
| 252 |
|
| 253 |
def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
|
|
@@ -312,6 +354,18 @@ def _wardrobe_summary(run: Any) -> str:
|
|
| 312 |
SECTIONS = ["Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"]
|
| 313 |
|
| 314 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
def _dashboard_regions(
|
| 316 |
run: Any | None = None,
|
| 317 |
adult_mode: bool = False,
|
|
@@ -344,6 +398,9 @@ def run_weave(
|
|
| 344 |
palette: str | None = None,
|
| 345 |
hardware: str | None = None,
|
| 346 |
reference_url: str | None = None,
|
|
|
|
|
|
|
|
|
|
| 347 |
) -> tuple[Any, ...]:
|
| 348 |
"""
|
| 349 |
Execute the complete weaving workflow from prompt through image generation and evaluation.
|
|
@@ -354,6 +411,8 @@ def run_weave(
|
|
| 354 |
Tuple containing dashboard region HTML fragments (topbar, command_rail, workflow, operations, inspector, drawer, status, artifacts, providers), catalog HTML, run data, catalog summary, scan results, operator state with generation details and judge evidence, and button state updates.
|
| 355 |
"""
|
| 356 |
prompt = prompt.strip() or DEFAULT_PROMPT
|
|
|
|
|
|
|
| 357 |
controls = _creator_controls(
|
| 358 |
reasoning_mode=reasoning_mode,
|
| 359 |
video_preset=video_preset,
|
|
@@ -363,6 +422,9 @@ def run_weave(
|
|
| 363 |
footwear=footwear,
|
| 364 |
palette=palette,
|
| 365 |
hardware=hardware,
|
|
|
|
|
|
|
|
|
|
| 366 |
)
|
| 367 |
controlled_prompt = _prompt_with_controls(prompt, controls)
|
| 368 |
reference_scan = scan_file(_file_path(upload))
|
|
@@ -377,7 +439,9 @@ def run_weave(
|
|
| 377 |
)
|
| 378 |
generation = generate_flux_image(
|
| 379 |
run.refined_prompt.refined,
|
| 380 |
-
seed=
|
|
|
|
|
|
|
| 381 |
adult_mode=adult_mode,
|
| 382 |
)
|
| 383 |
generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
|
|
@@ -392,14 +456,17 @@ def run_weave(
|
|
| 392 |
run_packet=run.to_dict(),
|
| 393 |
minicpm_result=minicpm.to_dict(),
|
| 394 |
)
|
| 395 |
-
provider_state = generation.provider_state if generation.status in {"success", "error", "missing_runtime", "no_cuda"} else "checkpointed"
|
| 396 |
if generation.status == "success":
|
| 397 |
provider_state = "generated"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
operator_state = {
|
| 399 |
"provider_state": provider_state,
|
| 400 |
"checkpoint": "pending_review",
|
| 401 |
"export": generated_scan.get("export_gate", "pending"),
|
| 402 |
-
"message": generation.message or "
|
| 403 |
"generation": generation.to_dict(),
|
| 404 |
"creator_controls": controls,
|
| 405 |
"reference_metadata": reference_metadata,
|
|
@@ -433,7 +500,7 @@ def run_weave(
|
|
| 433 |
run,
|
| 434 |
generated_scan,
|
| 435 |
operator_state,
|
| 436 |
-
|
| 437 |
)
|
| 438 |
|
| 439 |
|
|
@@ -545,7 +612,7 @@ def _render_stateful(
|
|
| 545 |
catalog_summary(adult_mode),
|
| 546 |
scan,
|
| 547 |
operator_state,
|
| 548 |
-
|
| 549 |
)
|
| 550 |
|
| 551 |
|
|
@@ -613,7 +680,7 @@ def approve_checkpoint(
|
|
| 613 |
state = operator_state or _default_operator_state()
|
| 614 |
scan = _authoritative_generated_scan(state)
|
| 615 |
if run is None:
|
| 616 |
-
next_state = {**_default_operator_state(), "provider_state": "blocked", "message": "No run exists yet.
|
| 617 |
elif not _generated_output_path(state):
|
| 618 |
next_state = {
|
| 619 |
**state,
|
|
@@ -632,7 +699,7 @@ def approve_checkpoint(
|
|
| 632 |
"message": (
|
| 633 |
"Checkpoint approved. Export is ready after clear ST3GG scan."
|
| 634 |
if export_state == "clear"
|
| 635 |
-
else "Checkpoint approved.
|
| 636 |
),
|
| 637 |
}
|
| 638 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
|
@@ -670,11 +737,11 @@ def export_packet(
|
|
| 670 |
scan = _authoritative_generated_scan(state)
|
| 671 |
override_reason = (override_reason or "").strip()
|
| 672 |
if run is None:
|
| 673 |
-
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export
|
| 674 |
elif state.get("checkpoint") != "approved":
|
| 675 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: approve the human checkpoint before release."}
|
| 676 |
elif not _generated_output_path(state):
|
| 677 |
-
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export
|
| 678 |
elif scan.get("export_gate") != "clear" and not override_reason:
|
| 679 |
next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export gate active: ST3GG is not clear. Add an explicit override reason to write an audit packet."}
|
| 680 |
else:
|
|
@@ -716,7 +783,7 @@ def stop_provider_job(
|
|
| 716 |
next_state = {
|
| 717 |
**(operator_state or _default_operator_state()),
|
| 718 |
"provider_state": "stopped",
|
| 719 |
-
"message": "Provider handoff stopped. Local
|
| 720 |
}
|
| 721 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
| 722 |
|
|
@@ -752,6 +819,8 @@ def reset_demo(
|
|
| 752 |
scan,
|
| 753 |
operator_state,
|
| 754 |
gr.update(interactive=False),
|
|
|
|
|
|
|
| 755 |
)
|
| 756 |
|
| 757 |
|
|
@@ -762,114 +831,116 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 762 |
active_run_state = gr.State(None)
|
| 763 |
scan_state = gr.State(scan_file(None))
|
| 764 |
operator_state = gr.State(initial_operator_state)
|
| 765 |
-
topbar_html = gr.HTML(initial_regions["topbar"], container=False)
|
| 766 |
|
| 767 |
-
with gr.
|
| 768 |
-
gr.
|
| 769 |
-
|
|
|
|
| 770 |
prompt = gr.Textbox(
|
| 771 |
value=DEFAULT_PROMPT,
|
| 772 |
-
label="
|
| 773 |
-
lines=
|
| 774 |
max_lines=6,
|
| 775 |
-
scale=5,
|
| 776 |
)
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
|
|
|
|
|
|
| 782 |
)
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 787 |
)
|
| 788 |
-
with gr.Row():
|
| 789 |
-
silhouette = gr.Dropdown(
|
| 790 |
-
["structured long coat", "fitted gothic bodice", "layered tactical silhouette"],
|
| 791 |
-
value="structured long coat",
|
| 792 |
-
label="Silhouette",
|
| 793 |
-
)
|
| 794 |
-
outerwear = gr.Dropdown(
|
| 795 |
-
["black patent leather long coat", "faux fur collar coat", "tailored rain slicker"],
|
| 796 |
-
value="black patent leather long coat",
|
| 797 |
-
label="Outerwear",
|
| 798 |
-
)
|
| 799 |
-
upper_body = gr.Dropdown(
|
| 800 |
-
["Chantilly lace neckline", "black mesh layer", "structured corset bodice"],
|
| 801 |
-
value="Chantilly lace neckline",
|
| 802 |
-
label="Upper Body",
|
| 803 |
-
)
|
| 804 |
-
footwear = gr.Dropdown(
|
| 805 |
-
["platform boots", "patent leather heels", "armored couture boots"],
|
| 806 |
-
value="platform boots",
|
| 807 |
-
label="Footwear",
|
| 808 |
-
)
|
| 809 |
-
with gr.Row():
|
| 810 |
-
palette = gr.Dropdown(
|
| 811 |
-
["black, crimson, cyan neon", "obsidian, pearl, crimson", "graphite, magenta, cold blue"],
|
| 812 |
-
value="black, crimson, cyan neon",
|
| 813 |
-
label="Palette",
|
| 814 |
-
)
|
| 815 |
-
hardware = gr.Dropdown(
|
| 816 |
-
["crimson hardware", "silver occult buckles", "holographic NEXUS sigils"],
|
| 817 |
-
value="crimson hardware",
|
| 818 |
-
label="Hardware",
|
| 819 |
-
)
|
| 820 |
-
reference_url = gr.Textbox(
|
| 821 |
-
label="Reference URL (metadata only)",
|
| 822 |
-
placeholder="https://shop.example/reference-garment",
|
| 823 |
-
scale=2,
|
| 824 |
-
)
|
| 825 |
-
with gr.Row():
|
| 826 |
-
adult_mode = gr.Checkbox(
|
| 827 |
-
value=False,
|
| 828 |
-
label="Adult Mode 18+ catalog scope",
|
| 829 |
-
info="Off by default. Enables adult-tagged catalog entries but does not disable security, consent, or export gates.",
|
| 830 |
-
scale=2,
|
| 831 |
-
)
|
| 832 |
-
run_btn = gr.Button("Run Active Weave", variant="primary", scale=2)
|
| 833 |
-
checkpoint_btn = gr.Button("Approve Checkpoint", scale=1)
|
| 834 |
-
export_btn = gr.Button("Prepare Export Packet", scale=1)
|
| 835 |
-
reset_btn = gr.Button("Reset Demo State", scale=1)
|
| 836 |
-
with gr.Row(elem_id="nw-operator-actions", elem_classes=["nw-operator-actions"]):
|
| 837 |
-
stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
|
| 838 |
-
with gr.Accordion("Optional ST3GG file/reference scan", open=False):
|
| 839 |
-
gr.Markdown("Upload only when you want ST3GG to inspect an external reference or output file. Generation does not require an upload.")
|
| 840 |
-
upload = gr.File(
|
| 841 |
-
label="Optional file for ST3GG scan",
|
| 842 |
-
file_count="single",
|
| 843 |
-
type="filepath",
|
| 844 |
-
)
|
| 845 |
-
scan_btn = gr.Button("Scan Uploaded File", scale=1)
|
| 846 |
-
override_reason = gr.Textbox(
|
| 847 |
-
label="ST3GG Override Reason",
|
| 848 |
-
placeholder="Required when ST3GG is review/blocked; explain why this audit packet may be written.",
|
| 849 |
-
lines=2,
|
| 850 |
-
max_lines=3,
|
| 851 |
-
)
|
| 852 |
|
| 853 |
-
|
| 854 |
-
|
| 855 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
| 860 |
-
|
| 861 |
-
|
| 862 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 863 |
artifact_html = gr.HTML(initial_regions["artifacts"], container=False)
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 873 |
|
| 874 |
with gr.Accordion("Catalog, run record, and security evidence", open=False):
|
| 875 |
catalog_html = gr.HTML(render_catalog_table(False), container=False)
|
|
@@ -894,13 +965,30 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 894 |
scan_json,
|
| 895 |
]
|
| 896 |
|
| 897 |
-
stateful_outputs = dashboard_outputs + [active_run_state, scan_state, operator_state, stop_btn]
|
| 898 |
|
| 899 |
-
operator_outputs = dashboard_outputs + [operator_state, stop_btn]
|
| 900 |
|
| 901 |
run_click = run_btn.click(
|
| 902 |
fn=run_weave,
|
| 903 |
-
inputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 904 |
outputs=stateful_outputs,
|
| 905 |
api_name="run_active_weave",
|
| 906 |
concurrency_limit=1,
|
|
@@ -908,7 +996,24 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 908 |
)
|
| 909 |
run_submit = prompt.submit(
|
| 910 |
fn=run_weave,
|
| 911 |
-
inputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 912 |
outputs=stateful_outputs,
|
| 913 |
api_name=False,
|
| 914 |
concurrency_limit=1,
|
|
@@ -942,7 +1047,7 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 942 |
scan_btn.click(
|
| 943 |
fn=scan_reference,
|
| 944 |
inputs=[active_run_state, adult_mode, upload, section_nav, operator_state, reference_url],
|
| 945 |
-
outputs=dashboard_outputs + [operator_state, stop_btn, scan_state],
|
| 946 |
api_name="scan_reference",
|
| 947 |
queue=False,
|
| 948 |
)
|
|
|
|
| 5 |
import os
|
| 6 |
import sys
|
| 7 |
import hashlib
|
| 8 |
+
import secrets
|
| 9 |
from pathlib import Path
|
| 10 |
from typing import Any
|
| 11 |
from urllib.parse import urlparse
|
|
|
|
| 49 |
|
| 50 |
MODEL_RELAY = WeaverModelRelay()
|
| 51 |
|
| 52 |
+
STYLE_MODIFIERS = {
|
| 53 |
+
"Balanced": "balanced editorial lighting, precise garment detail, clean composition",
|
| 54 |
+
"High Fashion": "haute couture editorial styling, premium material finish, runway-grade silhouette",
|
| 55 |
+
"Cinematic": "cinematic rain-lit atmosphere, dramatic lensing, high contrast neon reflections",
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
ASPECT_DIMENSIONS = {
|
| 59 |
+
"Square": (1024, 1024),
|
| 60 |
+
"Portrait": (832, 1216),
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
|
| 64 |
def _default_operator_state() -> dict[str, Any]:
|
| 65 |
return {
|
|
|
|
| 206 |
palette: str | None = None,
|
| 207 |
hardware: str | None = None,
|
| 208 |
locate_focus: list[str] | None = None,
|
| 209 |
+
seed: int | None = None,
|
| 210 |
+
style_strength: str = "High Fashion",
|
| 211 |
+
aspect: str = "Portrait",
|
| 212 |
) -> dict[str, Any]:
|
| 213 |
"""
|
| 214 |
Create a control object combining wardrobe selections with generation policy and reasoning configuration.
|
|
|
|
| 235 |
"flux_primary": "black-forest-labs/FLUX.2-klein-9B",
|
| 236 |
"flux_sidecar": "black-forest-labs/FLUX.2-klein-4B",
|
| 237 |
"lora_policy": "attempt compatible runtime adapter; report loaded/skipped/failed",
|
| 238 |
+
"seed": seed,
|
| 239 |
+
"style_strength": style_strength,
|
| 240 |
+
"aspect": aspect,
|
| 241 |
},
|
| 242 |
}
|
| 243 |
|
| 244 |
|
| 245 |
+
def _resolve_seed(seed_value: Any) -> int:
|
| 246 |
+
"""Resolve user seed input. Empty or -1 means randomize."""
|
| 247 |
+
try:
|
| 248 |
+
if seed_value is None or str(seed_value).strip() == "":
|
| 249 |
+
return secrets.randbelow(1_000_000_000)
|
| 250 |
+
seed = int(float(seed_value))
|
| 251 |
+
except (TypeError, ValueError):
|
| 252 |
+
return secrets.randbelow(1_000_000_000)
|
| 253 |
+
return secrets.randbelow(1_000_000_000) if seed < 0 else seed
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def _generation_dimensions(aspect: str | None) -> tuple[int, int]:
|
| 257 |
+
return ASPECT_DIMENSIONS.get(str(aspect or "Portrait"), ASPECT_DIMENSIONS["Portrait"])
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
def _style_modifier(style_strength: str | None) -> str:
|
| 261 |
+
return STYLE_MODIFIERS.get(str(style_strength or "High Fashion"), STYLE_MODIFIERS["High Fashion"])
|
| 262 |
+
|
| 263 |
+
|
| 264 |
def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
|
| 265 |
"""
|
| 266 |
Augments a prompt with wardrobe control parameters.
|
|
|
|
| 284 |
wardrobe.get("hardware"),
|
| 285 |
]
|
| 286 |
suffix = ", ".join(str(item) for item in additions if item)
|
| 287 |
+
generation = controls.get("generation", {})
|
| 288 |
+
if not suffix and not generation:
|
| 289 |
+
return prompt
|
| 290 |
+
style = _style_modifier(str(generation.get("style_strength", "High Fashion")))
|
| 291 |
+
prompt = f"{prompt}\nWardrobe controls: {suffix}" if suffix else prompt
|
| 292 |
+
return f"{prompt}\nStyle direction: {style}"
|
| 293 |
|
| 294 |
|
| 295 |
def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
|
|
|
|
| 354 |
SECTIONS = ["Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"]
|
| 355 |
|
| 356 |
|
| 357 |
+
def _button_updates(run: Any | None, operator_state: dict[str, Any] | None) -> tuple[Any, Any, Any]:
|
| 358 |
+
state = operator_state or {}
|
| 359 |
+
generated = bool(_generated_output_path(state)) and (state.get("generation") or {}).get("status") == "success"
|
| 360 |
+
checkpoint_approved = state.get("checkpoint") == "approved"
|
| 361 |
+
exported = state.get("provider_state") == "exported"
|
| 362 |
+
return (
|
| 363 |
+
gr.update(interactive=generated and not checkpoint_approved and not exported),
|
| 364 |
+
gr.update(interactive=generated and checkpoint_approved and not exported),
|
| 365 |
+
gr.update(interactive=False),
|
| 366 |
+
)
|
| 367 |
+
|
| 368 |
+
|
| 369 |
def _dashboard_regions(
|
| 370 |
run: Any | None = None,
|
| 371 |
adult_mode: bool = False,
|
|
|
|
| 398 |
palette: str | None = None,
|
| 399 |
hardware: str | None = None,
|
| 400 |
reference_url: str | None = None,
|
| 401 |
+
seed_value: Any = -1,
|
| 402 |
+
style_strength: str = "High Fashion",
|
| 403 |
+
aspect: str = "Portrait",
|
| 404 |
) -> tuple[Any, ...]:
|
| 405 |
"""
|
| 406 |
Execute the complete weaving workflow from prompt through image generation and evaluation.
|
|
|
|
| 411 |
Tuple containing dashboard region HTML fragments (topbar, command_rail, workflow, operations, inspector, drawer, status, artifacts, providers), catalog HTML, run data, catalog summary, scan results, operator state with generation details and judge evidence, and button state updates.
|
| 412 |
"""
|
| 413 |
prompt = prompt.strip() or DEFAULT_PROMPT
|
| 414 |
+
resolved_seed = _resolve_seed(seed_value)
|
| 415 |
+
width, height = _generation_dimensions(aspect)
|
| 416 |
controls = _creator_controls(
|
| 417 |
reasoning_mode=reasoning_mode,
|
| 418 |
video_preset=video_preset,
|
|
|
|
| 422 |
footwear=footwear,
|
| 423 |
palette=palette,
|
| 424 |
hardware=hardware,
|
| 425 |
+
seed=resolved_seed,
|
| 426 |
+
style_strength=style_strength,
|
| 427 |
+
aspect=aspect,
|
| 428 |
)
|
| 429 |
controlled_prompt = _prompt_with_controls(prompt, controls)
|
| 430 |
reference_scan = scan_file(_file_path(upload))
|
|
|
|
| 439 |
)
|
| 440 |
generation = generate_flux_image(
|
| 441 |
run.refined_prompt.refined,
|
| 442 |
+
seed=resolved_seed,
|
| 443 |
+
width=width,
|
| 444 |
+
height=height,
|
| 445 |
adult_mode=adult_mode,
|
| 446 |
)
|
| 447 |
generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
|
|
|
|
| 456 |
run_packet=run.to_dict(),
|
| 457 |
minicpm_result=minicpm.to_dict(),
|
| 458 |
)
|
|
|
|
| 459 |
if generation.status == "success":
|
| 460 |
provider_state = "generated"
|
| 461 |
+
elif generation.status in {"disabled", "missing_runtime", "no_cuda", "error"}:
|
| 462 |
+
provider_state = generation.provider_state
|
| 463 |
+
else:
|
| 464 |
+
provider_state = "checkpointed"
|
| 465 |
operator_state = {
|
| 466 |
"provider_state": provider_state,
|
| 467 |
"checkpoint": "pending_review",
|
| 468 |
"export": generated_scan.get("export_gate", "pending"),
|
| 469 |
+
"message": generation.message or "Image run complete. Human checkpoint required before export.",
|
| 470 |
"generation": generation.to_dict(),
|
| 471 |
"creator_controls": controls,
|
| 472 |
"reference_metadata": reference_metadata,
|
|
|
|
| 500 |
run,
|
| 501 |
generated_scan,
|
| 502 |
operator_state,
|
| 503 |
+
*_button_updates(run, operator_state),
|
| 504 |
)
|
| 505 |
|
| 506 |
|
|
|
|
| 612 |
catalog_summary(adult_mode),
|
| 613 |
scan,
|
| 614 |
operator_state,
|
| 615 |
+
*_button_updates(run, operator_state),
|
| 616 |
)
|
| 617 |
|
| 618 |
|
|
|
|
| 680 |
state = operator_state or _default_operator_state()
|
| 681 |
scan = _authoritative_generated_scan(state)
|
| 682 |
if run is None:
|
| 683 |
+
next_state = {**_default_operator_state(), "provider_state": "blocked", "message": "No run exists yet. Generate an image first."}
|
| 684 |
elif not _generated_output_path(state):
|
| 685 |
next_state = {
|
| 686 |
**state,
|
|
|
|
| 699 |
"message": (
|
| 700 |
"Checkpoint approved. Export is ready after clear ST3GG scan."
|
| 701 |
if export_state == "clear"
|
| 702 |
+
else "Checkpoint approved. Add an override reason and click Prepare Audit Export to write an audit packet."
|
| 703 |
),
|
| 704 |
}
|
| 705 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
|
|
|
| 737 |
scan = _authoritative_generated_scan(state)
|
| 738 |
override_reason = (override_reason or "").strip()
|
| 739 |
if run is None:
|
| 740 |
+
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export waits for review: generate an image before preparing an audit packet."}
|
| 741 |
elif state.get("checkpoint") != "approved":
|
| 742 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export gate active: approve the human checkpoint before release."}
|
| 743 |
elif not _generated_output_path(state):
|
| 744 |
+
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export waits for review: generate an artifact before preparing evidence."}
|
| 745 |
elif scan.get("export_gate") != "clear" and not override_reason:
|
| 746 |
next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export gate active: ST3GG is not clear. Add an explicit override reason to write an audit packet."}
|
| 747 |
else:
|
|
|
|
| 783 |
next_state = {
|
| 784 |
**(operator_state or _default_operator_state()),
|
| 785 |
"provider_state": "stopped",
|
| 786 |
+
"message": "Provider handoff stopped. Local run packet and evidence remain available.",
|
| 787 |
}
|
| 788 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
| 789 |
|
|
|
|
| 819 |
scan,
|
| 820 |
operator_state,
|
| 821 |
gr.update(interactive=False),
|
| 822 |
+
gr.update(interactive=False),
|
| 823 |
+
gr.update(interactive=False),
|
| 824 |
)
|
| 825 |
|
| 826 |
|
|
|
|
| 831 |
active_run_state = gr.State(None)
|
| 832 |
scan_state = gr.State(scan_file(None))
|
| 833 |
operator_state = gr.State(initial_operator_state)
|
| 834 |
+
topbar_html = gr.HTML(initial_regions["topbar"], container=False, visible=False)
|
| 835 |
|
| 836 |
+
with gr.Row(elem_id="nw-creator-workbench", elem_classes=["nw-creator-workbench"]):
|
| 837 |
+
with gr.Column(scale=5, min_width=520, elem_id="nw-creator-panel"):
|
| 838 |
+
gr.Markdown("### Create Couture Image")
|
| 839 |
+
gr.Markdown("Describe the look, choose wardrobe controls, then generate. Reference upload is optional.")
|
| 840 |
prompt = gr.Textbox(
|
| 841 |
value=DEFAULT_PROMPT,
|
| 842 |
+
label="Describe the look",
|
| 843 |
+
lines=4,
|
| 844 |
max_lines=6,
|
|
|
|
| 845 |
)
|
| 846 |
+
|
| 847 |
+
with gr.Row():
|
| 848 |
+
seed_value = gr.Number(value=-1, precision=0, label="Seed (-1 randomizes)")
|
| 849 |
+
style_strength = gr.Dropdown(
|
| 850 |
+
["Balanced", "High Fashion", "Cinematic"],
|
| 851 |
+
value="High Fashion",
|
| 852 |
+
label="Style Strength",
|
| 853 |
)
|
| 854 |
+
aspect = gr.Dropdown(["Portrait", "Square"], value="Portrait", label="Aspect")
|
| 855 |
+
with gr.Row(elem_classes=["nw-primary-actions"]):
|
| 856 |
+
run_btn = gr.Button("Generate Image", variant="primary", scale=2)
|
| 857 |
+
reset_btn = gr.Button("Reset", scale=1)
|
| 858 |
+
|
| 859 |
+
with gr.Row():
|
| 860 |
+
silhouette = gr.Dropdown(
|
| 861 |
+
["structured long coat", "fitted gothic bodice", "layered tactical silhouette"],
|
| 862 |
+
value="structured long coat",
|
| 863 |
+
label="Silhouette",
|
| 864 |
+
)
|
| 865 |
+
outerwear = gr.Dropdown(
|
| 866 |
+
["black patent leather long coat", "faux fur collar coat", "tailored rain slicker"],
|
| 867 |
+
value="black patent leather long coat",
|
| 868 |
+
label="Outerwear",
|
| 869 |
+
)
|
| 870 |
+
with gr.Row():
|
| 871 |
+
upper_body = gr.Dropdown(
|
| 872 |
+
["Chantilly lace neckline", "black mesh layer", "structured corset bodice"],
|
| 873 |
+
value="Chantilly lace neckline",
|
| 874 |
+
label="Upper Body",
|
| 875 |
+
)
|
| 876 |
+
footwear = gr.Dropdown(
|
| 877 |
+
["platform boots", "patent leather heels", "armored couture boots"],
|
| 878 |
+
value="platform boots",
|
| 879 |
+
label="Footwear",
|
| 880 |
+
)
|
| 881 |
+
with gr.Row():
|
| 882 |
+
palette = gr.Dropdown(
|
| 883 |
+
["black, crimson, cyan neon", "obsidian, pearl, crimson", "graphite, magenta, cold blue"],
|
| 884 |
+
value="black, crimson, cyan neon",
|
| 885 |
+
label="Palette",
|
| 886 |
+
)
|
| 887 |
+
hardware = gr.Dropdown(
|
| 888 |
+
["crimson hardware", "silver occult buckles", "holographic NEXUS sigils"],
|
| 889 |
+
value="crimson hardware",
|
| 890 |
+
label="Hardware",
|
| 891 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 892 |
|
| 893 |
+
with gr.Accordion("Advanced: scan external file", open=False):
|
| 894 |
+
gr.Markdown("Optional. Generate directly unless you need ST3GG to inspect an uploaded reference or output file.")
|
| 895 |
+
with gr.Row():
|
| 896 |
+
reasoning_mode = gr.Radio(["Strict", "Frontier"], value="Strict", label="Reasoning Mode")
|
| 897 |
+
video_preset = gr.Dropdown(["Wan2.2 I2V", "LTX-2.3"], value="Wan2.2 I2V", label="Video preset (deferred)")
|
| 898 |
+
with gr.Row():
|
| 899 |
+
adult_mode = gr.Checkbox(
|
| 900 |
+
value=False,
|
| 901 |
+
label="Adult Mode 18+ catalog scope",
|
| 902 |
+
info="Off by default. Never disables security, consent, or export gates.",
|
| 903 |
+
)
|
| 904 |
+
reference_url = gr.Textbox(
|
| 905 |
+
label="Reference URL (metadata only)",
|
| 906 |
+
placeholder="https://shop.example/reference-garment",
|
| 907 |
+
)
|
| 908 |
+
upload = gr.File(label="Optional file for ST3GG scan", file_count="single", type="filepath")
|
| 909 |
+
with gr.Row():
|
| 910 |
+
scan_btn = gr.Button("Scan Uploaded File", scale=1)
|
| 911 |
+
stop_btn = gr.Button("Stop Job", variant="stop", interactive=False, scale=1)
|
| 912 |
+
|
| 913 |
+
with gr.Column(scale=4, min_width=460, elem_id="nw-output-panel"):
|
| 914 |
+
gr.Markdown("### Output")
|
| 915 |
artifact_html = gr.HTML(initial_regions["artifacts"], container=False)
|
| 916 |
+
with gr.Row(elem_id="nw-checkpoint-actions", elem_classes=["nw-checkpoint-actions"]):
|
| 917 |
+
checkpoint_btn = gr.Button("Approve Checkpoint", scale=1, interactive=False)
|
| 918 |
+
export_btn = gr.Button("Prepare Audit Export", scale=1, interactive=False)
|
| 919 |
+
override_reason = gr.Textbox(
|
| 920 |
+
label="ST3GG Override Reason",
|
| 921 |
+
placeholder="Required only when ST3GG asks for review; explain why this audit packet may be written.",
|
| 922 |
+
lines=2,
|
| 923 |
+
max_lines=3,
|
| 924 |
+
)
|
| 925 |
+
gr.Markdown("Generation is not export. Every artifact stays behind ST3GG review and human checkpoint.")
|
| 926 |
+
|
| 927 |
+
with gr.Accordion("Run Anatomy", open=False):
|
| 928 |
+
with gr.Row(elem_id="nw-workspace", elem_classes=["nw-workspace"]):
|
| 929 |
+
with gr.Column(scale=1, min_width=160, elem_id="nw-native-rail"):
|
| 930 |
+
section_nav = gr.Radio(SECTIONS, value="Forge", label="Technical Section", elem_id="nw-section-nav")
|
| 931 |
+
command_rail_html = gr.HTML(initial_regions["command_rail"], container=False)
|
| 932 |
+
with gr.Column(scale=5, min_width=620, elem_id="nw-main-column"):
|
| 933 |
+
workflow_html = gr.HTML(initial_regions["workflow"], container=False)
|
| 934 |
+
|
| 935 |
+
with gr.Accordion("Wardrobe Evidence", open=False):
|
| 936 |
+
operations_html = gr.HTML(initial_regions["operations"], container=False)
|
| 937 |
+
drawer_html = gr.HTML(initial_regions["drawer"], container=False)
|
| 938 |
+
|
| 939 |
+
with gr.Accordion("Technical Evidence", open=False):
|
| 940 |
+
status_html = gr.HTML(initial_regions["status"], container=False)
|
| 941 |
+
inspector_html = gr.HTML(initial_regions["inspector"], container=False)
|
| 942 |
+
with gr.Accordion("Provider Diagnostics", open=False):
|
| 943 |
+
provider_html = gr.HTML(initial_regions["providers"], container=False)
|
| 944 |
|
| 945 |
with gr.Accordion("Catalog, run record, and security evidence", open=False):
|
| 946 |
catalog_html = gr.HTML(render_catalog_table(False), container=False)
|
|
|
|
| 965 |
scan_json,
|
| 966 |
]
|
| 967 |
|
| 968 |
+
stateful_outputs = dashboard_outputs + [active_run_state, scan_state, operator_state, checkpoint_btn, export_btn, stop_btn]
|
| 969 |
|
| 970 |
+
operator_outputs = dashboard_outputs + [operator_state, checkpoint_btn, export_btn, stop_btn]
|
| 971 |
|
| 972 |
run_click = run_btn.click(
|
| 973 |
fn=run_weave,
|
| 974 |
+
inputs=[
|
| 975 |
+
prompt,
|
| 976 |
+
reasoning_mode,
|
| 977 |
+
video_preset,
|
| 978 |
+
adult_mode,
|
| 979 |
+
upload,
|
| 980 |
+
section_nav,
|
| 981 |
+
silhouette,
|
| 982 |
+
outerwear,
|
| 983 |
+
upper_body,
|
| 984 |
+
footwear,
|
| 985 |
+
palette,
|
| 986 |
+
hardware,
|
| 987 |
+
reference_url,
|
| 988 |
+
seed_value,
|
| 989 |
+
style_strength,
|
| 990 |
+
aspect,
|
| 991 |
+
],
|
| 992 |
outputs=stateful_outputs,
|
| 993 |
api_name="run_active_weave",
|
| 994 |
concurrency_limit=1,
|
|
|
|
| 996 |
)
|
| 997 |
run_submit = prompt.submit(
|
| 998 |
fn=run_weave,
|
| 999 |
+
inputs=[
|
| 1000 |
+
prompt,
|
| 1001 |
+
reasoning_mode,
|
| 1002 |
+
video_preset,
|
| 1003 |
+
adult_mode,
|
| 1004 |
+
upload,
|
| 1005 |
+
section_nav,
|
| 1006 |
+
silhouette,
|
| 1007 |
+
outerwear,
|
| 1008 |
+
upper_body,
|
| 1009 |
+
footwear,
|
| 1010 |
+
palette,
|
| 1011 |
+
hardware,
|
| 1012 |
+
reference_url,
|
| 1013 |
+
seed_value,
|
| 1014 |
+
style_strength,
|
| 1015 |
+
aspect,
|
| 1016 |
+
],
|
| 1017 |
outputs=stateful_outputs,
|
| 1018 |
api_name=False,
|
| 1019 |
concurrency_limit=1,
|
|
|
|
| 1047 |
scan_btn.click(
|
| 1048 |
fn=scan_reference,
|
| 1049 |
inputs=[active_run_state, adult_mode, upload, section_nav, operator_state, reference_url],
|
| 1050 |
+
outputs=dashboard_outputs + [operator_state, checkpoint_btn, export_btn, stop_btn, scan_state],
|
| 1051 |
api_name="scan_reference",
|
| 1052 |
queue=False,
|
| 1053 |
)
|
docs/HANDOFF_QUOTA_EXHAUST_V4_2.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# NEXUS Visual Weaver v4.2 Handoff - Quota Exhaustion Coverage
|
| 2 |
+
|
| 3 |
+
Date: 2026-06-15
|
| 4 |
+
|
| 5 |
+
This handoff captures the current live state after the practical UX recovery pass. Use it if the current Codex session or quota expires.
|
| 6 |
+
|
| 7 |
+
## Current State
|
| 8 |
+
|
| 9 |
+
- GitHub branch: `main`
|
| 10 |
+
- Latest GitHub commit: `4b9ab3f fix: make creation path practical and visible`
|
| 11 |
+
- Latest HF Space commit: `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
|
| 12 |
+
- HF Space: `build-small-hackathon/NEXUS_Visual_Weaver`
|
| 13 |
+
- Live URL: <https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/>
|
| 14 |
+
- HF runtime verified after deploy:
|
| 15 |
+
- `dev_mode=false`
|
| 16 |
+
- runtime stage `RUNNING`
|
| 17 |
+
- domain stage `READY`
|
| 18 |
+
- runtime SHA equals Space SHA: `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
|
| 19 |
+
|
| 20 |
+
## Important Discovery
|
| 21 |
+
|
| 22 |
+
The live UI was stale because Hugging Face Dev Mode kept an older container running. The repository already had newer code, but the visible Space did not reflect it.
|
| 23 |
+
|
| 24 |
+
Fixed with:
|
| 25 |
+
|
| 26 |
+
```powershell
|
| 27 |
+
$env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
|
| 28 |
+
hf spaces dev-mode build-small-hackathon/NEXUS_Visual_Weaver --stop
|
| 29 |
+
hf spaces restart build-small-hackathon/NEXUS_Visual_Weaver --factory-reboot
|
| 30 |
+
```
|
| 31 |
+
|
| 32 |
+
If future screenshots show old labels again, check `runtime.dev_mode` and `runtime.raw.sha` before editing more code.
|
| 33 |
+
|
| 34 |
+
## Practical UX Fixes Shipped
|
| 35 |
+
|
| 36 |
+
Commit `4b9ab3f` changes:
|
| 37 |
+
|
| 38 |
+
- Moves `Artifact Preview Lane` above the workflow graph so real output is visible sooner.
|
| 39 |
+
- Collapses provider lanes by default under `Optional provider lanes`.
|
| 40 |
+
- Moves file upload into a collapsed `Optional ST3GG file/reference scan` section.
|
| 41 |
+
- Makes `Run Active Weave` the primary action.
|
| 42 |
+
- Keeps checkpoint/export/reset as immediate operator actions.
|
| 43 |
+
- Changes generated/export-ready states in the footer from red failure styling to green success styling.
|
| 44 |
+
- Enlarges the artifact preview frame so the generated image reads as the product outcome.
|
| 45 |
+
|
| 46 |
+
Files changed:
|
| 47 |
+
|
| 48 |
+
- `app.py`
|
| 49 |
+
- `src/nexus_visual_weaver/render.py`
|
| 50 |
+
- `src/nexus_visual_weaver/styles.py`
|
| 51 |
+
- `.gitignore` now ignores `.hf-upload-cache/`
|
| 52 |
+
|
| 53 |
+
## What "Missing Secret" Means
|
| 54 |
+
|
| 55 |
+
`MISSING_SECRET` was not asking for more Hugging Face access. It referred to optional sponsor/provider lanes, mainly:
|
| 56 |
+
|
| 57 |
+
- OpenBMB/MiniCPM: `MINICPM_BASE_URL` plus `MINICPM_API_KEY` or `OPENBMB_API_KEY`
|
| 58 |
+
- NVIDIA/Nemotron: `NEMOTRON_BASE_URL` plus `NEMOTRON_API_KEY` or `NVIDIA_API_KEY`
|
| 59 |
+
- Other optional gateways: `FAL_KEY`, Netlify, Cloudflare
|
| 60 |
+
|
| 61 |
+
Those lanes are not the P0 demo. They should remain collapsed or framed as optional. Do not make the main flow depend on them.
|
| 62 |
+
|
| 63 |
+
## Verification Already Run Locally
|
| 64 |
+
|
| 65 |
+
Before commit:
|
| 66 |
+
|
| 67 |
+
```powershell
|
| 68 |
+
python -m compileall app.py src tests
|
| 69 |
+
$env:NEXUS_DISABLE_REAL_HF='1'
|
| 70 |
+
$env:PYTEST_DISABLE_PLUGIN_AUTOLOAD='1'
|
| 71 |
+
python -m pytest -q tests -p no:cacheprovider --basetemp=C:\tmp\pytest-nvw-full
|
| 72 |
+
git grep -n -I -E "hf_[A-Za-z0-9]{20,}|Bearer [A-Za-z0-9._-]+|sk-[A-Za-z0-9_-]{20,}|api[_-]?key\s*=" -- .
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
Result:
|
| 76 |
+
|
| 77 |
+
- Compile clean
|
| 78 |
+
- `288 passed, 1 warning`
|
| 79 |
+
- Secret scan clean
|
| 80 |
+
|
| 81 |
+
After deploy:
|
| 82 |
+
|
| 83 |
+
```powershell
|
| 84 |
+
$env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
|
| 85 |
+
hf spaces info build-small-hackathon/NEXUS_Visual_Weaver --format json
|
| 86 |
+
Invoke-WebRequest -UseBasicParsing https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/
|
| 87 |
+
Invoke-WebRequest -UseBasicParsing https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/gradio_api/info
|
| 88 |
+
```
|
| 89 |
+
|
| 90 |
+
Result:
|
| 91 |
+
|
| 92 |
+
- Space SHA and runtime SHA both `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`
|
| 93 |
+
- Root returned HTTP 200
|
| 94 |
+
- `/gradio_api/info` returned HTTP 200
|
| 95 |
+
|
| 96 |
+
## Deployment Commands Used
|
| 97 |
+
|
| 98 |
+
The standard upload failed once because Hugging Face Xet tried to write into a locked local cache. The successful upload disabled Xet while keeping the existing auth token:
|
| 99 |
+
|
| 100 |
+
```powershell
|
| 101 |
+
$env:HTTP_PROXY=''; $env:HTTPS_PROXY=''; $env:ALL_PROXY=''; $env:NO_PROXY='*'
|
| 102 |
+
$env:HF_HUB_DISABLE_XET='1'
|
| 103 |
+
Remove-Item Env:\HF_HOME -ErrorAction SilentlyContinue
|
| 104 |
+
hf upload build-small-hackathon/NEXUS_Visual_Weaver C:\tmp\nvw-v422-4b9ab3f . --repo-type=space --commit-message "fix: practical creation path layout"
|
| 105 |
+
hf spaces restart build-small-hackathon/NEXUS_Visual_Weaver --factory-reboot
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
## Next Visual QA Checklist
|
| 109 |
+
|
| 110 |
+
Open the Space in a browser and verify:
|
| 111 |
+
|
| 112 |
+
- Provider cards are collapsed by default.
|
| 113 |
+
- Upload is inside `Optional ST3GG file/reference scan`, not dominating the main screen.
|
| 114 |
+
- `Artifact Preview Lane` appears before the workflow graph.
|
| 115 |
+
- Footer state after generation reads as success/green, not a red `Generated` block.
|
| 116 |
+
- The main visible path is: controls -> `Run Active Weave` -> artifact preview -> checkpoint/export.
|
| 117 |
+
- Optional provider lanes do not visually dominate with missing-secret labels.
|
| 118 |
+
|
| 119 |
+
If any of these fail, first confirm the browser is not cached and HF runtime SHA is still `4c4521d9e88aedcbf2bd01d1394fe9fa683a01b5`.
|
| 120 |
+
|
| 121 |
+
## Remaining Work
|
| 122 |
+
|
| 123 |
+
P0 next:
|
| 124 |
+
|
| 125 |
+
- Browser visual inspection of the live Space after rebuild.
|
| 126 |
+
- One live run through `Run Active Weave`.
|
| 127 |
+
- Confirm export packet after checkpoint/override.
|
| 128 |
+
|
| 129 |
+
Do not spend more time on generated README images, Gamma deck polish, Modal, or video until the practical live UI is confirmed usable.
|
| 130 |
+
|
| 131 |
+
## Demo Framing
|
| 132 |
+
|
| 133 |
+
Main proof line:
|
| 134 |
+
|
| 135 |
+
> NEXUS Visual Weaver generates a real FLUX.2 Klein artifact, keeps ST3GG review and human checkpoint visible, and writes audit evidence instead of silently exporting.
|
| 136 |
+
|
| 137 |
+
Avoid claiming:
|
| 138 |
+
|
| 139 |
+
- Sponsor judge success unless secrets are configured and a real call returns evidence.
|
| 140 |
+
- Video success unless a real `.mp4` is produced by the Space.
|
| 141 |
+
- Dynamic LoRA success unless export evidence reports `loaded`.
|
| 142 |
+
|
src/nexus_visual_weaver/render.py
CHANGED
|
@@ -77,6 +77,8 @@ def _gate_label(export_gate: str) -> str:
|
|
| 77 |
return "Export Blocked - Override Available"
|
| 78 |
if normalized == "CLEAR":
|
| 79 |
return "EXPORT CLEAR"
|
|
|
|
|
|
|
| 80 |
return f"EXPORT {normalized}"
|
| 81 |
|
| 82 |
|
|
@@ -214,6 +216,7 @@ def render_trust_strip(scan: dict | None = None, operator_state: dict | None = N
|
|
| 214 |
scan = scan or {"status": "idle", "export_gate": "pending", "findings": [], "purification_actions": []}
|
| 215 |
operator_state = operator_state or {}
|
| 216 |
status = str(scan.get("status", "idle")).upper()
|
|
|
|
| 217 |
export_gate = str(scan.get("export_gate", "pending")).upper()
|
| 218 |
checkpoint = str(operator_state.get("checkpoint", "pending")).replace("_", " ").title()
|
| 219 |
raw_findings = scan.get("findings")
|
|
@@ -236,7 +239,7 @@ def render_trust_strip(scan: dict | None = None, operator_state: dict | None = N
|
|
| 236 |
<strong>Generation is not export.</strong>
|
| 237 |
<span>Every artifact must pass ST3GG scan, purification, and human checkpoint before release.</span>
|
| 238 |
</div>
|
| 239 |
-
<div class="nw-trust-card">{badge(f"ST3GG {
|
| 240 |
<div class="nw-trust-card">{badge(_gate_label(export_gate), "pass" if export_gate == "CLEAR" else "warn" if export_gate == "BLOCKED" else "muted")}<span>{escape(str(actions[0]))}</span></div>
|
| 241 |
<div class="nw-trust-card">{badge(f"CHECKPOINT {checkpoint.upper()}", "pass" if checkpoint == "Approved" else "muted")}<span>Adult Mode never bypasses safety, consent, provenance, or dataset gates.</span></div>
|
| 242 |
<div class="nw-trust-card nw-trust-examples">{badge("FIXTURE EVIDENCE", "cyan")}<span>Clean PNG -> pass. PNG trailing bytes -> blocked.</span></div>
|
|
@@ -493,17 +496,14 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
|
|
| 493 |
"""
|
| 494 |
scan = scan or {"status": "idle", "export_gate": "pending"}
|
| 495 |
operator_state = operator_state or {}
|
| 496 |
-
|
| 497 |
-
outfit_label = "Outfit map"
|
| 498 |
-
locate_label = "Grounding overlay"
|
| 499 |
-
video_label = run.video.preset if run else "Video path"
|
| 500 |
-
active_prompt = run.refined_prompt.refined[:150] if run else "Awaiting first weave. Real output and export evidence appear here after generation."
|
| 501 |
checkpoint = operator_state.get("checkpoint", getattr(run.checkpoint, "recommendation", "pending") if run else "pending")
|
| 502 |
provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
|
| 503 |
generation = operator_state.get("generation") or {}
|
| 504 |
generated_uri = _image_data_uri(generation.get("output_path")) if isinstance(generation, dict) else None
|
| 505 |
generated_status = str(generation.get("status", "")) if isinstance(generation, dict) else ""
|
| 506 |
generated_message = str(generation.get("message", "")) if isinstance(generation, dict) else ""
|
|
|
|
| 507 |
preview_mode = {
|
| 508 |
"idle": "Idle",
|
| 509 |
"dry-run": "Dry Run",
|
|
@@ -512,32 +512,22 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
|
|
| 512 |
"exported": "Exported",
|
| 513 |
"blocked": "Export Gate Active",
|
| 514 |
"stopped": "Stopped",
|
|
|
|
| 515 |
}.get(provider_state, provider_state.replace("_", " ").title())
|
| 516 |
demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
|
| 517 |
-
artifacts = [
|
| 518 |
-
(prompt_label, "Taste-refined brief", "dry-run", "material-0", "01"),
|
| 519 |
-
(outfit_label, "Wardrobe slots and locks", "checkpointed", "material-1", "02"),
|
| 520 |
-
(locate_label, "LocateAnything region plan", "configured", "material-4", "03"),
|
| 521 |
-
(video_label, "Checkpointed storyboard", "deferred" if scan.get("export_gate") == "blocked" or provider_state == "blocked" else "ready", "story-2", "04"),
|
| 522 |
-
]
|
| 523 |
-
cards = "".join(
|
| 524 |
-
f"""
|
| 525 |
-
<div class="nw-artifact-card">
|
| 526 |
-
<small>{escape(index)}</small>
|
| 527 |
-
<i class="nw-{texture}"></i>
|
| 528 |
-
<strong>{escape(title)}</strong>
|
| 529 |
-
<span>{escape(body)}</span>
|
| 530 |
-
{badge("Gated" if status == "deferred" else status.upper(), "warn" if status in {"blocked", "deferred"} else "muted")}
|
| 531 |
-
</div>
|
| 532 |
-
"""
|
| 533 |
-
for title, body, status, texture, index in artifacts
|
| 534 |
-
)
|
| 535 |
export_gate = str(scan.get("export_gate", "pending")).upper()
|
| 536 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
return f"""
|
| 538 |
<section class="nw-panel nw-artifacts">
|
| 539 |
<div class="nw-panel-head">
|
| 540 |
-
<div><strong>
|
| 541 |
{badge(_gate_label(export_gate), "warn" if export_gate == "BLOCKED" else "pass" if export_gate == "CLEAR" else "muted")}
|
| 542 |
</div>
|
| 543 |
<div class="nw-preview-stage">
|
|
@@ -545,22 +535,21 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
|
|
| 545 |
{'<img class="nw-preview-real-image" src="' + generated_uri + '" alt="Generated FLUX artifact" />' if generated_uri else '<i class="nw-preview-image"></i>'}
|
| 546 |
<div class="nw-preview-caption">
|
| 547 |
<small>PRIMARY OUTPUT STAGE / {escape(generated_status.upper() or "JUDGE-SAFE DEMO OUTPUT")} / SEED {escape(demo_seed)}</small>
|
| 548 |
-
<strong>{'Real FLUX.2 Klein artifact' if generated_uri else '
|
| 549 |
<span>{escape(generated_message or active_prompt)}</span>
|
| 550 |
</div>
|
| 551 |
</div>
|
| 552 |
<div class="nw-preview-meta">
|
| 553 |
-
<div><small>
|
| 554 |
-
<div><small>
|
| 555 |
-
<div><small>
|
| 556 |
</div>
|
| 557 |
</div>
|
| 558 |
-
<div class="nw-
|
| 559 |
-
<
|
| 560 |
-
<
|
| 561 |
-
<
|
| 562 |
</div>
|
| 563 |
-
<div class="nw-artifact-grid">{cards}</div>
|
| 564 |
</section>
|
| 565 |
"""
|
| 566 |
|
|
|
|
| 77 |
return "Export Blocked - Override Available"
|
| 78 |
if normalized == "CLEAR":
|
| 79 |
return "EXPORT CLEAR"
|
| 80 |
+
if normalized == "PENDING":
|
| 81 |
+
return "Export waits for review"
|
| 82 |
return f"EXPORT {normalized}"
|
| 83 |
|
| 84 |
|
|
|
|
| 216 |
scan = scan or {"status": "idle", "export_gate": "pending", "findings": [], "purification_actions": []}
|
| 217 |
operator_state = operator_state or {}
|
| 218 |
status = str(scan.get("status", "idle")).upper()
|
| 219 |
+
status_label = "READY" if status == "IDLE" else status
|
| 220 |
export_gate = str(scan.get("export_gate", "pending")).upper()
|
| 221 |
checkpoint = str(operator_state.get("checkpoint", "pending")).replace("_", " ").title()
|
| 222 |
raw_findings = scan.get("findings")
|
|
|
|
| 239 |
<strong>Generation is not export.</strong>
|
| 240 |
<span>Every artifact must pass ST3GG scan, purification, and human checkpoint before release.</span>
|
| 241 |
</div>
|
| 242 |
+
<div class="nw-trust-card">{badge(f"ST3GG {status_label}", tone)}<span>{escape(str(findings[0]))}</span></div>
|
| 243 |
<div class="nw-trust-card">{badge(_gate_label(export_gate), "pass" if export_gate == "CLEAR" else "warn" if export_gate == "BLOCKED" else "muted")}<span>{escape(str(actions[0]))}</span></div>
|
| 244 |
<div class="nw-trust-card">{badge(f"CHECKPOINT {checkpoint.upper()}", "pass" if checkpoint == "Approved" else "muted")}<span>Adult Mode never bypasses safety, consent, provenance, or dataset gates.</span></div>
|
| 245 |
<div class="nw-trust-card nw-trust-examples">{badge("FIXTURE EVIDENCE", "cyan")}<span>Clean PNG -> pass. PNG trailing bytes -> blocked.</span></div>
|
|
|
|
| 496 |
"""
|
| 497 |
scan = scan or {"status": "idle", "export_gate": "pending"}
|
| 498 |
operator_state = operator_state or {}
|
| 499 |
+
active_prompt = run.refined_prompt.refined[:150] if run else "Describe the look and click Generate Image."
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
checkpoint = operator_state.get("checkpoint", getattr(run.checkpoint, "recommendation", "pending") if run else "pending")
|
| 501 |
provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
|
| 502 |
generation = operator_state.get("generation") or {}
|
| 503 |
generated_uri = _image_data_uri(generation.get("output_path")) if isinstance(generation, dict) else None
|
| 504 |
generated_status = str(generation.get("status", "")) if isinstance(generation, dict) else ""
|
| 505 |
generated_message = str(generation.get("message", "")) if isinstance(generation, dict) else ""
|
| 506 |
+
output_ready = bool(generated_uri)
|
| 507 |
preview_mode = {
|
| 508 |
"idle": "Idle",
|
| 509 |
"dry-run": "Dry Run",
|
|
|
|
| 512 |
"exported": "Exported",
|
| 513 |
"blocked": "Export Gate Active",
|
| 514 |
"stopped": "Stopped",
|
| 515 |
+
"generated": "Generated",
|
| 516 |
}.get(provider_state, provider_state.replace("_", " ").title())
|
| 517 |
demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 518 |
export_gate = str(scan.get("export_gate", "pending")).upper()
|
| 519 |
+
checkpoint_label = str(checkpoint).replace("_", " ").title()
|
| 520 |
+
next_action = "Generate an image to unlock checkpoint review."
|
| 521 |
+
if output_ready and str(checkpoint) != "approved":
|
| 522 |
+
next_action = "Approve checkpoint to unlock audit export."
|
| 523 |
+
elif output_ready and str(checkpoint) == "approved" and export_gate != "CLEAR":
|
| 524 |
+
next_action = "Add override reason or complete ST3GG review, then prepare audit export."
|
| 525 |
+
elif output_ready and str(checkpoint) == "approved":
|
| 526 |
+
next_action = "Prepare audit export."
|
| 527 |
return f"""
|
| 528 |
<section class="nw-panel nw-artifacts">
|
| 529 |
<div class="nw-panel-head">
|
| 530 |
+
<div><strong>{'Generated image ready' if output_ready else 'Output'}</strong><small>Real output and export evidence appear here</small></div>
|
| 531 |
{badge(_gate_label(export_gate), "warn" if export_gate == "BLOCKED" else "pass" if export_gate == "CLEAR" else "muted")}
|
| 532 |
</div>
|
| 533 |
<div class="nw-preview-stage">
|
|
|
|
| 535 |
{'<img class="nw-preview-real-image" src="' + generated_uri + '" alt="Generated FLUX artifact" />' if generated_uri else '<i class="nw-preview-image"></i>'}
|
| 536 |
<div class="nw-preview-caption">
|
| 537 |
<small>PRIMARY OUTPUT STAGE / {escape(generated_status.upper() or "JUDGE-SAFE DEMO OUTPUT")} / SEED {escape(demo_seed)}</small>
|
| 538 |
+
<strong>{'Real FLUX.2 Klein artifact' if generated_uri else 'No image generated yet'}</strong>
|
| 539 |
<span>{escape(generated_message or active_prompt)}</span>
|
| 540 |
</div>
|
| 541 |
</div>
|
| 542 |
<div class="nw-preview-meta">
|
| 543 |
+
<div><small>Output</small><strong>{'Ready' if output_ready else 'Waiting'}</strong></div>
|
| 544 |
+
<div><small>Checkpoint</small><strong>{escape(checkpoint_label)}</strong></div>
|
| 545 |
+
<div><small>Export</small><strong>{escape(_gate_label(export_gate))}</strong></div>
|
| 546 |
</div>
|
| 547 |
</div>
|
| 548 |
+
<div class="nw-run-summary">
|
| 549 |
+
<div><small>Current state</small><strong>{escape(preview_mode)}</strong></div>
|
| 550 |
+
<div><small>Security</small><strong>ST3GG review active</strong></div>
|
| 551 |
+
<div><small>Next action</small><strong>{escape(next_action)}</strong></div>
|
| 552 |
</div>
|
|
|
|
| 553 |
</section>
|
| 554 |
"""
|
| 555 |
|
src/nexus_visual_weaver/styles.py
CHANGED
|
@@ -598,6 +598,117 @@ footer { display: none !important; }
|
|
| 598 |
z-index: 20;
|
| 599 |
box-shadow: 0 14px 32px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.04);
|
| 600 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
.nw-command-header {
|
| 602 |
display: grid;
|
| 603 |
grid-template-columns: minmax(260px, 1fr) auto;
|
|
@@ -984,6 +1095,7 @@ footer { display: none !important; }
|
|
| 984 |
.nw-rail-main { display: flex; }
|
| 985 |
.nw-rail-foot, .nw-rail::after { display: none; }
|
| 986 |
.nw-bottom { grid-template-columns: 1fr; }
|
|
|
|
| 987 |
#nw-workspace { flex-direction: column; }
|
| 988 |
.nw-command-header, .nw-preview-stage, .nw-preview-frame { grid-template-columns: 1fr; }
|
| 989 |
.nw-command-pills { justify-content: flex-start; }
|
|
|
|
| 598 |
z-index: 20;
|
| 599 |
box-shadow: 0 14px 32px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.04);
|
| 600 |
}
|
| 601 |
+
.nw-creator-workbench {
|
| 602 |
+
padding: 10px 8px 8px;
|
| 603 |
+
gap: 10px !important;
|
| 604 |
+
align-items: stretch;
|
| 605 |
+
}
|
| 606 |
+
#nw-creator-panel,
|
| 607 |
+
#nw-output-panel {
|
| 608 |
+
border: 1px solid var(--nw-line) !important;
|
| 609 |
+
border-radius: 8px !important;
|
| 610 |
+
background:
|
| 611 |
+
linear-gradient(180deg, rgba(12,17,23,.98), rgba(6,9,13,.98)) !important;
|
| 612 |
+
padding: 14px !important;
|
| 613 |
+
box-shadow: 0 16px 34px rgba(0,0,0,.22), inset 0 1px 0 rgba(255,255,255,.035);
|
| 614 |
+
}
|
| 615 |
+
#nw-creator-panel .prose h3,
|
| 616 |
+
#nw-output-panel .prose h3 {
|
| 617 |
+
margin: 0 0 2px !important;
|
| 618 |
+
color: var(--nw-text);
|
| 619 |
+
font-size: 18px !important;
|
| 620 |
+
letter-spacing: 0 !important;
|
| 621 |
+
}
|
| 622 |
+
#nw-creator-panel .prose p,
|
| 623 |
+
#nw-output-panel .prose p {
|
| 624 |
+
margin: 0 0 10px !important;
|
| 625 |
+
color: var(--nw-muted);
|
| 626 |
+
font-size: 12px;
|
| 627 |
+
}
|
| 628 |
+
#nw-creator-panel textarea {
|
| 629 |
+
min-height: 112px !important;
|
| 630 |
+
font-size: 14px !important;
|
| 631 |
+
line-height: 1.45 !important;
|
| 632 |
+
}
|
| 633 |
+
#nw-creator-panel label,
|
| 634 |
+
#nw-output-panel label {
|
| 635 |
+
color: var(--nw-text) !important;
|
| 636 |
+
font-size: 12px !important;
|
| 637 |
+
}
|
| 638 |
+
.nw-primary-actions button {
|
| 639 |
+
min-height: 46px !important;
|
| 640 |
+
font-weight: 760 !important;
|
| 641 |
+
letter-spacing: 0 !important;
|
| 642 |
+
}
|
| 643 |
+
.nw-primary-actions button.primary,
|
| 644 |
+
.nw-primary-actions button[variant="primary"] {
|
| 645 |
+
background: linear-gradient(180deg, #ff3b62, #c51a3b) !important;
|
| 646 |
+
border-color: rgba(255,54,95,.58) !important;
|
| 647 |
+
}
|
| 648 |
+
#nw-checkpoint-actions {
|
| 649 |
+
gap: 8px !important;
|
| 650 |
+
margin-top: 10px;
|
| 651 |
+
}
|
| 652 |
+
#nw-checkpoint-actions button {
|
| 653 |
+
min-height: 38px !important;
|
| 654 |
+
font-size: 12px !important;
|
| 655 |
+
font-weight: 740 !important;
|
| 656 |
+
letter-spacing: 0 !important;
|
| 657 |
+
}
|
| 658 |
+
#nw-output-panel .nw-artifacts {
|
| 659 |
+
margin: 0;
|
| 660 |
+
border: 0;
|
| 661 |
+
background: transparent;
|
| 662 |
+
}
|
| 663 |
+
#nw-output-panel .nw-panel-head {
|
| 664 |
+
padding: 0 0 10px;
|
| 665 |
+
}
|
| 666 |
+
#nw-output-panel .nw-preview-stage {
|
| 667 |
+
grid-template-columns: 1fr;
|
| 668 |
+
padding: 0;
|
| 669 |
+
}
|
| 670 |
+
#nw-output-panel .nw-preview-frame {
|
| 671 |
+
grid-template-columns: 1fr;
|
| 672 |
+
min-height: 500px;
|
| 673 |
+
}
|
| 674 |
+
#nw-output-panel .nw-preview-real-image,
|
| 675 |
+
#nw-output-panel .nw-preview-image {
|
| 676 |
+
min-height: 390px;
|
| 677 |
+
border-right: 0;
|
| 678 |
+
border-bottom: 1px solid rgba(255,255,255,.08);
|
| 679 |
+
}
|
| 680 |
+
#nw-output-panel .nw-preview-caption {
|
| 681 |
+
align-content: start;
|
| 682 |
+
min-height: 110px;
|
| 683 |
+
}
|
| 684 |
+
#nw-output-panel .nw-preview-meta {
|
| 685 |
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
| 686 |
+
}
|
| 687 |
+
.nw-run-summary {
|
| 688 |
+
display: grid;
|
| 689 |
+
grid-template-columns: 1fr;
|
| 690 |
+
gap: 8px;
|
| 691 |
+
margin-top: 10px;
|
| 692 |
+
}
|
| 693 |
+
.nw-run-summary div {
|
| 694 |
+
border: 1px solid var(--nw-line);
|
| 695 |
+
border-radius: 6px;
|
| 696 |
+
background: rgba(46,229,157,.035);
|
| 697 |
+
padding: 10px;
|
| 698 |
+
}
|
| 699 |
+
.nw-run-summary small {
|
| 700 |
+
display: block;
|
| 701 |
+
color: var(--nw-faint);
|
| 702 |
+
font-size: 10px;
|
| 703 |
+
font-weight: 760;
|
| 704 |
+
letter-spacing: 0;
|
| 705 |
+
margin-bottom: 4px;
|
| 706 |
+
}
|
| 707 |
+
.nw-run-summary strong {
|
| 708 |
+
color: var(--nw-text);
|
| 709 |
+
font-size: 12px;
|
| 710 |
+
line-height: 1.35;
|
| 711 |
+
}
|
| 712 |
.nw-command-header {
|
| 713 |
display: grid;
|
| 714 |
grid-template-columns: minmax(260px, 1fr) auto;
|
|
|
|
| 1095 |
.nw-rail-main { display: flex; }
|
| 1096 |
.nw-rail-foot, .nw-rail::after { display: none; }
|
| 1097 |
.nw-bottom { grid-template-columns: 1fr; }
|
| 1098 |
+
.nw-creator-workbench { flex-direction: column; }
|
| 1099 |
#nw-workspace { flex-direction: column; }
|
| 1100 |
.nw-command-header, .nw-preview-stage, .nw-preview-frame { grid-template-columns: 1fr; }
|
| 1101 |
.nw-command-pills { justify-content: flex-start; }
|
tests/test_app_callbacks.py
CHANGED
|
@@ -93,10 +93,12 @@ def test_run_weave_returns_stateful_dashboard_packet() -> None:
|
|
| 93 |
"Forge",
|
| 94 |
)
|
| 95 |
|
| 96 |
-
assert len(result) ==
|
| 97 |
assert result[13].checkpoint.checkpoint_id.startswith("nw-")
|
| 98 |
-
assert result[15]["provider_state"] == "
|
| 99 |
-
assert result[16]["interactive"] is
|
|
|
|
|
|
|
| 100 |
assert result[15]["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
|
| 101 |
assert result[15]["generation"]["lora_status"] == "disabled"
|
| 102 |
|
|
@@ -123,6 +125,9 @@ def test_run_weave_persists_additive_creator_controls_and_reference_url_metadata
|
|
| 123 |
|
| 124 |
assert state["creator_controls"]["reasoning_mode"] == "Frontier"
|
| 125 |
assert state["creator_controls"]["wardrobe"]["footwear"] == "patent leather heels"
|
|
|
|
|
|
|
|
|
|
| 126 |
assert state["reference_metadata"][0]["source"] == "url"
|
| 127 |
assert state["reference_metadata"][0]["domain"] == "shop.example.test"
|
| 128 |
assert "url_hash" in state["reference_metadata"][0]
|
|
@@ -227,9 +232,9 @@ def test_reference_scan_cannot_clear_blocked_generated_artifact() -> None:
|
|
| 227 |
scanned = app.scan_reference(run, False, str(clean_reference), "Forge", state)
|
| 228 |
assert scanned[13]["reference_scan"]["export_gate"] == "clear"
|
| 229 |
assert scanned[13]["export"] == "blocked"
|
| 230 |
-
assert scanned[
|
| 231 |
|
| 232 |
-
approved = app.approve_checkpoint(run, False, scanned[
|
| 233 |
assert approved[13]["provider_state"] == "checkpointed"
|
| 234 |
assert approved[13]["export"] == "blocked"
|
| 235 |
|
|
@@ -257,9 +262,9 @@ def test_blocked_reference_scan_does_not_block_clear_generated_artifact() -> Non
|
|
| 257 |
scanned = app.scan_reference(run, False, str(blocked_reference), "Forge", state)
|
| 258 |
assert scanned[13]["reference_scan"]["export_gate"] == "blocked"
|
| 259 |
assert scanned[13]["export"] == "clear"
|
| 260 |
-
assert scanned[
|
| 261 |
|
| 262 |
-
approved = app.approve_checkpoint(run, False, scanned[
|
| 263 |
assert approved[13]["provider_state"] == "export_ready"
|
| 264 |
assert approved[13]["export"] == "clear"
|
| 265 |
|
|
@@ -517,6 +522,21 @@ def test_creator_controls_generation_specifies_flux_primary() -> None:
|
|
| 517 |
assert "black-forest-labs/FLUX.2-klein-4B" in generation["flux_sidecar"]
|
| 518 |
|
| 519 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
# --- _prompt_with_controls tests ---
|
| 521 |
|
| 522 |
def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
|
|
@@ -526,6 +546,7 @@ def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
|
|
| 526 |
assert result.startswith("gothic couture portrait")
|
| 527 |
assert "Wardrobe controls:" in result
|
| 528 |
assert "platform boots" in result
|
|
|
|
| 529 |
|
| 530 |
|
| 531 |
def test_prompt_with_controls_returns_prompt_unchanged_when_no_wardrobe() -> None:
|
|
@@ -555,6 +576,36 @@ def test_prompt_with_controls_includes_all_wardrobe_fields() -> None:
|
|
| 555 |
assert "crimson hardware" in result
|
| 556 |
|
| 557 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 558 |
def test_prompt_with_controls_does_not_duplicate_prompt() -> None:
|
| 559 |
controls = app._creator_controls("Strict", "Wan2.2 I2V")
|
| 560 |
prompt = "gothic couture brief"
|
|
|
|
| 93 |
"Forge",
|
| 94 |
)
|
| 95 |
|
| 96 |
+
assert len(result) == 19
|
| 97 |
assert result[13].checkpoint.checkpoint_id.startswith("nw-")
|
| 98 |
+
assert result[15]["provider_state"] == "dry-run"
|
| 99 |
+
assert result[16]["interactive"] is False
|
| 100 |
+
assert result[17]["interactive"] is False
|
| 101 |
+
assert result[18]["interactive"] is False
|
| 102 |
assert result[15]["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
|
| 103 |
assert result[15]["generation"]["lora_status"] == "disabled"
|
| 104 |
|
|
|
|
| 125 |
|
| 126 |
assert state["creator_controls"]["reasoning_mode"] == "Frontier"
|
| 127 |
assert state["creator_controls"]["wardrobe"]["footwear"] == "patent leather heels"
|
| 128 |
+
assert state["creator_controls"]["generation"]["seed"] >= 0
|
| 129 |
+
assert state["creator_controls"]["generation"]["style_strength"] == "High Fashion"
|
| 130 |
+
assert state["creator_controls"]["generation"]["aspect"] == "Portrait"
|
| 131 |
assert state["reference_metadata"][0]["source"] == "url"
|
| 132 |
assert state["reference_metadata"][0]["domain"] == "shop.example.test"
|
| 133 |
assert "url_hash" in state["reference_metadata"][0]
|
|
|
|
| 232 |
scanned = app.scan_reference(run, False, str(clean_reference), "Forge", state)
|
| 233 |
assert scanned[13]["reference_scan"]["export_gate"] == "clear"
|
| 234 |
assert scanned[13]["export"] == "blocked"
|
| 235 |
+
assert scanned[17]["export_gate"] == "blocked"
|
| 236 |
|
| 237 |
+
approved = app.approve_checkpoint(run, False, scanned[17], "Forge", scanned[13])
|
| 238 |
assert approved[13]["provider_state"] == "checkpointed"
|
| 239 |
assert approved[13]["export"] == "blocked"
|
| 240 |
|
|
|
|
| 262 |
scanned = app.scan_reference(run, False, str(blocked_reference), "Forge", state)
|
| 263 |
assert scanned[13]["reference_scan"]["export_gate"] == "blocked"
|
| 264 |
assert scanned[13]["export"] == "clear"
|
| 265 |
+
assert scanned[17]["export_gate"] == "clear"
|
| 266 |
|
| 267 |
+
approved = app.approve_checkpoint(run, False, scanned[17], "Forge", scanned[13])
|
| 268 |
assert approved[13]["provider_state"] == "export_ready"
|
| 269 |
assert approved[13]["export"] == "clear"
|
| 270 |
|
|
|
|
| 522 |
assert "black-forest-labs/FLUX.2-klein-4B" in generation["flux_sidecar"]
|
| 523 |
|
| 524 |
|
| 525 |
+
def test_creator_controls_generation_persists_seed_style_and_aspect() -> None:
|
| 526 |
+
result = app._creator_controls(
|
| 527 |
+
"Strict",
|
| 528 |
+
"Wan2.2 I2V",
|
| 529 |
+
seed=123,
|
| 530 |
+
style_strength="Cinematic",
|
| 531 |
+
aspect="Square",
|
| 532 |
+
)
|
| 533 |
+
generation = result["generation"]
|
| 534 |
+
|
| 535 |
+
assert generation["seed"] == 123
|
| 536 |
+
assert generation["style_strength"] == "Cinematic"
|
| 537 |
+
assert generation["aspect"] == "Square"
|
| 538 |
+
|
| 539 |
+
|
| 540 |
# --- _prompt_with_controls tests ---
|
| 541 |
|
| 542 |
def test_prompt_with_controls_appends_wardrobe_suffix() -> None:
|
|
|
|
| 546 |
assert result.startswith("gothic couture portrait")
|
| 547 |
assert "Wardrobe controls:" in result
|
| 548 |
assert "platform boots" in result
|
| 549 |
+
assert "Style direction:" in result
|
| 550 |
|
| 551 |
|
| 552 |
def test_prompt_with_controls_returns_prompt_unchanged_when_no_wardrobe() -> None:
|
|
|
|
| 576 |
assert "crimson hardware" in result
|
| 577 |
|
| 578 |
|
| 579 |
+
def test_generation_dimensions_support_portrait_and_square() -> None:
|
| 580 |
+
assert app._generation_dimensions("Portrait") == (832, 1216)
|
| 581 |
+
assert app._generation_dimensions("Square") == (1024, 1024)
|
| 582 |
+
assert app._generation_dimensions("unknown") == (832, 1216)
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
def test_resolve_seed_randomizes_negative_and_uses_explicit_seed() -> None:
|
| 586 |
+
assert app._resolve_seed(42) == 42
|
| 587 |
+
assert app._resolve_seed("42") == 42
|
| 588 |
+
assert 0 <= app._resolve_seed(-1) < 1_000_000_000
|
| 589 |
+
|
| 590 |
+
|
| 591 |
+
def test_button_updates_unlock_checkpoint_then_export() -> None:
|
| 592 |
+
state = {
|
| 593 |
+
"provider_state": "generated",
|
| 594 |
+
"checkpoint": "pending_review",
|
| 595 |
+
"generation": {"status": "success", "output_path": "outputs/runtime/test.png"},
|
| 596 |
+
}
|
| 597 |
+
checkpoint, export, stop = app._button_updates(None, state)
|
| 598 |
+
assert checkpoint["interactive"] is True
|
| 599 |
+
assert export["interactive"] is False
|
| 600 |
+
assert stop["interactive"] is False
|
| 601 |
+
|
| 602 |
+
approved_state = {**state, "checkpoint": "approved"}
|
| 603 |
+
checkpoint, export, stop = app._button_updates(None, approved_state)
|
| 604 |
+
assert checkpoint["interactive"] is False
|
| 605 |
+
assert export["interactive"] is True
|
| 606 |
+
assert stop["interactive"] is False
|
| 607 |
+
|
| 608 |
+
|
| 609 |
def test_prompt_with_controls_does_not_duplicate_prompt() -> None:
|
| 610 |
controls = app._creator_controls("Strict", "Wan2.2 I2V")
|
| 611 |
prompt = "gothic couture brief"
|
tests/test_command_center.py
CHANGED
|
@@ -153,12 +153,11 @@ def test_dashboard_regions_expose_artifacts_and_provider_cards() -> None:
|
|
| 153 |
relay_status=relay.dashboard_snapshot(public_demo=True),
|
| 154 |
)
|
| 155 |
|
| 156 |
-
assert "
|
| 157 |
assert "nw-preview-stage" in regions["artifacts"]
|
| 158 |
-
assert "nw-preview-ribbon" in regions["artifacts"]
|
| 159 |
assert "PRIMARY OUTPUT STAGE" in regions["artifacts"]
|
| 160 |
assert "JUDGE-SAFE DEMO OUTPUT" in regions["artifacts"]
|
| 161 |
-
assert "
|
| 162 |
assert "Forge Operations" in regions["operations"]
|
| 163 |
assert "Optional Provider Lanes" in regions["providers"]
|
| 164 |
assert "nw-provider-meter" in regions["providers"]
|
|
@@ -185,7 +184,7 @@ def test_dashboard_regions_render_with_empty_relay_and_default_scan() -> None:
|
|
| 185 |
assert "not-started" in regions["operations"]
|
| 186 |
assert "snapshot pending" in regions["providers"]
|
| 187 |
assert "Selected: Forge" in regions["command_rail"]
|
| 188 |
-
assert "
|
| 189 |
|
| 190 |
|
| 191 |
def test_dashboard_operations_follow_selected_section() -> None:
|
|
@@ -265,8 +264,8 @@ def test_render_trust_strip_defaults_to_idle_state() -> None:
|
|
| 265 |
|
| 266 |
assert "TRUST MODEL" in html
|
| 267 |
assert "Generation is not export." in html
|
| 268 |
-
assert "ST3GG
|
| 269 |
-
assert "
|
| 270 |
assert "Clean PNG -> pass." in html
|
| 271 |
assert "FIXTURE EVIDENCE" in html
|
| 272 |
|
|
|
|
| 153 |
relay_status=relay.dashboard_snapshot(public_demo=True),
|
| 154 |
)
|
| 155 |
|
| 156 |
+
assert "Output" in regions["artifacts"]
|
| 157 |
assert "nw-preview-stage" in regions["artifacts"]
|
|
|
|
| 158 |
assert "PRIMARY OUTPUT STAGE" in regions["artifacts"]
|
| 159 |
assert "JUDGE-SAFE DEMO OUTPUT" in regions["artifacts"]
|
| 160 |
+
assert "Generate an image to unlock checkpoint review." in regions["artifacts"]
|
| 161 |
assert "Forge Operations" in regions["operations"]
|
| 162 |
assert "Optional Provider Lanes" in regions["providers"]
|
| 163 |
assert "nw-provider-meter" in regions["providers"]
|
|
|
|
| 184 |
assert "not-started" in regions["operations"]
|
| 185 |
assert "snapshot pending" in regions["providers"]
|
| 186 |
assert "Selected: Forge" in regions["command_rail"]
|
| 187 |
+
assert "Real output and export evidence appear here" in regions["artifacts"]
|
| 188 |
|
| 189 |
|
| 190 |
def test_dashboard_operations_follow_selected_section() -> None:
|
|
|
|
| 264 |
|
| 265 |
assert "TRUST MODEL" in html
|
| 266 |
assert "Generation is not export." in html
|
| 267 |
+
assert "ST3GG READY" in html
|
| 268 |
+
assert "Export waits for review" in html
|
| 269 |
assert "Clean PNG -> pass." in html
|
| 270 |
assert "FIXTURE EVIDENCE" in html
|
| 271 |
|