v4 execution lock: creator evidence
Browse files- .playwright-mcp/page-2026-06-12T12-58-04-245Z.yml +12 -0
- .playwright-mcp/page-2026-06-12T21-30-33-874Z.yml +3 -0
- .playwright-mcp/page-2026-06-12T21-31-39-288Z.yml +5 -0
- .playwright-mcp/page-2026-06-13T05-01-53-264Z.yml +3 -0
- .playwright-mcp/page-2026-06-13T14-11-22-087Z.yml +5 -0
- .playwright-mcp/page-2026-06-13T14-19-01-146Z.yml +3 -0
- README.md +14 -17
- app.py +195 -90
- docs/HACKATHON_EVALUATION.md +11 -11
- docs/HANDOFF_FINAL_HACKATHON.md +13 -57
- src/nexus_visual_weaver/catalog.py +28 -51
- src/nexus_visual_weaver/exporter.py +123 -37
- src/nexus_visual_weaver/hf_runtime.py +96 -25
- src/nexus_visual_weaver/lora_adapter.py +85 -0
- src/nexus_visual_weaver/model_relay.py +32 -20
- src/nexus_visual_weaver/planner.py +12 -3
- src/nexus_visual_weaver/render.py +10 -70
- src/nexus_visual_weaver/schema.py +7 -0
- src/nexus_visual_weaver/styles.py +0 -73
- src/nexus_visual_weaver/wardrobe.py +17 -3
- tests/test_app_callbacks.py +30 -34
- tests/test_command_center.py +6 -46
- tests/test_exporter.py +86 -28
- tests/test_hf_runtime.py +7 -8
- tests/test_lora_adapter.py +90 -0
- tests/test_model_relay.py +14 -13
.playwright-mcp/page-2026-06-12T12-58-04-245Z.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [active] [ref=e1]:
|
| 2 |
+
- region "Notifications alt+T"
|
| 3 |
+
- alert [ref=e7]
|
| 4 |
+
- dialog "Privacy" [ref=e9]:
|
| 5 |
+
- generic [ref=e10]:
|
| 6 |
+
- generic [ref=e13]: By clicking “Accept All Cookies”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts.
|
| 7 |
+
- generic [ref=e15]:
|
| 8 |
+
- button "Cookies Settings, Opens the preference center dialog" [ref=e16] [cursor=pointer]: Cookies Settings
|
| 9 |
+
- generic [ref=e17]:
|
| 10 |
+
- button "Reject All" [ref=e18] [cursor=pointer]
|
| 11 |
+
- button "Accept All Cookies" [ref=e19] [cursor=pointer]
|
| 12 |
+
- button "Close" [ref=e21] [cursor=pointer]
|
.playwright-mcp/page-2026-06-12T21-30-33-874Z.yml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [ref=e5]:
|
| 2 |
+
- img [ref=e9]
|
| 3 |
+
- paragraph [ref=e20]: Loading...
|
.playwright-mcp/page-2026-06-12T21-31-39-288Z.yml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [ref=e4]:
|
| 2 |
+
- generic [ref=e5]:
|
| 3 |
+
- img [ref=e9]
|
| 4 |
+
- paragraph [ref=e20]: Loading...
|
| 5 |
+
- main [ref=e22]
|
.playwright-mcp/page-2026-06-13T05-01-53-264Z.yml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [ref=e5]:
|
| 2 |
+
- img [ref=e9]
|
| 3 |
+
- paragraph [ref=e20]: Loading...
|
.playwright-mcp/page-2026-06-13T14-11-22-087Z.yml
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [ref=e4]:
|
| 2 |
+
- generic [ref=e5]:
|
| 3 |
+
- img [ref=e9]
|
| 4 |
+
- paragraph [ref=e20]: Loading...
|
| 5 |
+
- main [ref=e22]
|
.playwright-mcp/page-2026-06-13T14-19-01-146Z.yml
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
- generic [ref=e5]:
|
| 2 |
+
- img [ref=e9]
|
| 3 |
+
- paragraph [ref=e20]: Loading...
|
README.md
CHANGED
|
@@ -12,14 +12,9 @@ short_description: Governed gothic couture visual creation command center
|
|
| 12 |
models:
|
| 13 |
- black-forest-labs/FLUX.2-klein-9B
|
| 14 |
- black-forest-labs/FLUX.2-klein-4B
|
| 15 |
-
- Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf
|
| 16 |
- nvidia/LocateAnything-3B
|
| 17 |
- openbmb/MiniCPM-V-4.6
|
| 18 |
- nvidia/NVIDIA-Nemotron-Parse-v1.2
|
| 19 |
-
- openbmb/MiniCPM5-1B
|
| 20 |
-
- onnx-community/functiongemma-270m-it-ONNX
|
| 21 |
-
- hexgrad/Kokoro-82M
|
| 22 |
-
- netflix/void-model
|
| 23 |
tags:
|
| 24 |
- gradio
|
| 25 |
- mcp-server
|
|
@@ -30,8 +25,6 @@ tags:
|
|
| 30 |
- best-agent
|
| 31 |
- best-demo
|
| 32 |
- openbmb
|
| 33 |
-
- nvidia
|
| 34 |
-
- modal
|
| 35 |
- codex
|
| 36 |
---
|
| 37 |
|
|
@@ -57,17 +50,14 @@ The interface is built around a command-center surface:
|
|
| 57 |
|
| 58 |
Pinned lanes do not rotate:
|
| 59 |
|
| 60 |
-
- `image_generation`: Raven Quality
|
| 61 |
- `grounding`: NVIDIA LocateAnything-3B grounding anchor
|
| 62 |
- `security`: ST3GG defensive scanner/export gate
|
| 63 |
|
| 64 |
Sponsor/evidence lanes are optional but first-class when secrets are configured:
|
| 65 |
|
| 66 |
-
- `Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf` (11.91B): quality/taste/lore critique lane for private or configured judge use.
|
| 67 |
- `openbmb/MiniCPM-V-4.6` (1.30B): visual judge for wardrobe, footwear, material drift, lore continuity, and export notes.
|
| 68 |
- `nvidia/NVIDIA-Nemotron-Parse-v1.2` (0.94B): structured evidence/parser lane for NVIDIA/Nemotron claim support.
|
| 69 |
-
- `hexgrad/Kokoro-82M` (0.082B): optional lore narration lane.
|
| 70 |
-
- `netflix/void-model` (5B CogVideoX-based): Modal/offline video repair sample lane, not a blocking Space runtime default.
|
| 71 |
|
| 72 |
Helper lanes may rotate with quota, license, health, and parameter-budget checks:
|
| 73 |
|
|
@@ -78,12 +68,12 @@ Helper lanes may rotate with quota, license, health, and parameter-budget checks
|
|
| 78 |
- HF catalog research
|
| 79 |
- Modal job runner
|
| 80 |
|
| 81 |
-
|
| 82 |
|
| 83 |
## Current Features
|
| 84 |
|
| 85 |
- Gradio Blocks dashboard with split update regions.
|
| 86 |
-
- Real FLUX.2 Klein 9B-first image generation on Hugging Face ZeroGPU when runtime access is configured, with
|
| 87 |
- Above-fold ST3GG trust strip with safe-vs-blocked fixture evidence.
|
| 88 |
- Generated artifact ST3GG scan and checkpoint/export state.
|
| 89 |
- Optional MiniCPM-V and Nemotron provider evidence lanes with explicit configured/missing-secret status.
|
|
@@ -100,18 +90,25 @@ The default preset is **Raven Quality Stack**. `black-forest-labs/FLUX.2-klein-4
|
|
| 100 |
| Target | Evidence status |
|
| 101 |
| --- | --- |
|
| 102 |
| Gradio Space | App runs as a public Hugging Face Gradio Space with `mcp_server=True`. |
|
| 103 |
-
| <=32B models | Raven Quality
|
| 104 |
| Off Brand | Custom command-center UI, dense inspector, workflow graph, wardrobe/lore drawer, and provider cards. |
|
| 105 |
| Best Agent | Multi-step prompt, generation, scan, judge, checkpoint, export workflow. |
|
| 106 |
| OpenBMB | Claimed only when MiniCPM-V returns success status in an export packet. |
|
| 107 |
| NVIDIA | Claimed only when Nemotron returns success status in an export packet. LocateAnything remains visible but is not the Nemotron claim by itself. |
|
| 108 |
-
| Modal | Sidecar-only until a real Modal job is documented; target lane is `netflix/void-model` video repair. |
|
| 109 |
| OpenAI Codex | Development branch and PR include Codex-authored implementation commits. |
|
| 110 |
| Demo / social | Add final links here before submission: `DEMO_VIDEO_URL` and `SOCIAL_POST_URL`. |
|
| 111 |
|
| 112 |
-
Tiny Titan
|
| 113 |
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
## Local Setup
|
| 117 |
|
|
|
|
| 12 |
models:
|
| 13 |
- black-forest-labs/FLUX.2-klein-9B
|
| 14 |
- black-forest-labs/FLUX.2-klein-4B
|
|
|
|
| 15 |
- nvidia/LocateAnything-3B
|
| 16 |
- openbmb/MiniCPM-V-4.6
|
| 17 |
- nvidia/NVIDIA-Nemotron-Parse-v1.2
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
tags:
|
| 19 |
- gradio
|
| 20 |
- mcp-server
|
|
|
|
| 25 |
- best-agent
|
| 26 |
- best-demo
|
| 27 |
- openbmb
|
|
|
|
|
|
|
| 28 |
- codex
|
| 29 |
---
|
| 30 |
|
|
|
|
| 50 |
|
| 51 |
Pinned lanes do not rotate:
|
| 52 |
|
| 53 |
+
- `image_generation`: Raven Quality FLUX.2 Klein 9B image lane, with FLUX.2 Klein 4B as Tiny Titan sidecar/fallback
|
| 54 |
- `grounding`: NVIDIA LocateAnything-3B grounding anchor
|
| 55 |
- `security`: ST3GG defensive scanner/export gate
|
| 56 |
|
| 57 |
Sponsor/evidence lanes are optional but first-class when secrets are configured:
|
| 58 |
|
|
|
|
| 59 |
- `openbmb/MiniCPM-V-4.6` (1.30B): visual judge for wardrobe, footwear, material drift, lore continuity, and export notes.
|
| 60 |
- `nvidia/NVIDIA-Nemotron-Parse-v1.2` (0.94B): structured evidence/parser lane for NVIDIA/Nemotron claim support.
|
|
|
|
|
|
|
| 61 |
|
| 62 |
Helper lanes may rotate with quota, license, health, and parameter-budget checks:
|
| 63 |
|
|
|
|
| 68 |
- HF catalog research
|
| 69 |
- Modal job runner
|
| 70 |
|
| 71 |
+
Public demo mode uses the Raven Quality FLUX.2 Klein 9B lane when Space access is configured, while preserving the 4B sidecar for fallback/Tiny Titan evidence. Private research mode can add OFFELLIA/Gemma routes, but it never disables consent, provenance, ST3GG, export, or dataset-partition gates.
|
| 72 |
|
| 73 |
## Current Features
|
| 74 |
|
| 75 |
- Gradio Blocks dashboard with split update regions.
|
| 76 |
+
- Real FLUX.2 Klein 9B-first image generation on Hugging Face ZeroGPU when runtime access is configured, with honest 4B sidecar fallback.
|
| 77 |
- Above-fold ST3GG trust strip with safe-vs-blocked fixture evidence.
|
| 78 |
- Generated artifact ST3GG scan and checkpoint/export state.
|
| 79 |
- Optional MiniCPM-V and Nemotron provider evidence lanes with explicit configured/missing-secret status.
|
|
|
|
| 90 |
| Target | Evidence status |
|
| 91 |
| --- | --- |
|
| 92 |
| Gradio Space | App runs as a public Hugging Face Gradio Space with `mcp_server=True`. |
|
| 93 |
+
| <=32B models | Raven Quality stack is 16.42B: FLUX.2 Klein 9B + LocateAnything 3.83B + MiniCPM-V 1.30B + Nemotron Parse 0.94B + MiniCPM5 1.08B + FunctionGemma 0.27B. |
|
| 94 |
| Off Brand | Custom command-center UI, dense inspector, workflow graph, wardrobe/lore drawer, and provider cards. |
|
| 95 |
| Best Agent | Multi-step prompt, generation, scan, judge, checkpoint, export workflow. |
|
| 96 |
| OpenBMB | Claimed only when MiniCPM-V returns success status in an export packet. |
|
| 97 |
| NVIDIA | Claimed only when Nemotron returns success status in an export packet. LocateAnything remains visible but is not the Nemotron claim by itself. |
|
|
|
|
| 98 |
| OpenAI Codex | Development branch and PR include Codex-authored implementation commits. |
|
| 99 |
| Demo / social | Add final links here before submission: `DEMO_VIDEO_URL` and `SOCIAL_POST_URL`. |
|
| 100 |
|
| 101 |
+
Tiny Titan can be claimed only from a successful sidecar export packet using the 4B mode. It must not weaken the main Raven Quality stack.
|
| 102 |
|
| 103 |
+
## Merit Badges
|
| 104 |
+
|
| 105 |
+
| Badge | Bonus Quest | Status | Evidence |
|
| 106 |
+
| --- | --- | --- | --- |
|
| 107 |
+
| `off-brand` | Off-Brand | Ready | Gothic couture command-center UI with workflow graph, inspector, wardrobe/lore drawer, and ST3GG trust strip. |
|
| 108 |
+
| `best-agent` | Best Agent | Ready when export packet exists | Multi-step weave: prompt refinement, generation, scan, optional judges, checkpoint, and governed export. |
|
| 109 |
+
| `best-demo` | Best Demo | Pending final asset | Requires final demo video link and social post link before submission. |
|
| 110 |
+
| `openbmb` | OpenBMB sponsor | Conditional | Claimed only when MiniCPM-V returns `success` in an export packet. |
|
| 111 |
+
| `nvidia` | NVIDIA/Nemotron sponsor | Conditional | Claimed only when Nemotron returns `success`; LocateAnything remains grounding evidence, not a Nemotron claim. |
|
| 112 |
|
| 113 |
## Local Setup
|
| 114 |
|
app.py
CHANGED
|
@@ -4,8 +4,10 @@ from __future__ import annotations
|
|
| 4 |
|
| 5 |
import os
|
| 6 |
import sys
|
|
|
|
| 7 |
from pathlib import Path
|
| 8 |
from typing import Any
|
|
|
|
| 9 |
|
| 10 |
import gradio as gr
|
| 11 |
|
|
@@ -49,32 +51,10 @@ MODEL_RELAY = WeaverModelRelay()
|
|
| 49 |
|
| 50 |
def _default_operator_state() -> dict[str, Any]:
|
| 51 |
return {
|
| 52 |
-
"active_preset": "Raven Quality Stack",
|
| 53 |
"provider_state": "idle",
|
| 54 |
"checkpoint": "pending",
|
| 55 |
"export": "pending",
|
| 56 |
"message": "No operator action yet.",
|
| 57 |
-
"modal_video_repair": {
|
| 58 |
-
"status": "deferred",
|
| 59 |
-
"repo_id": "netflix/void-model",
|
| 60 |
-
"provider": "modal",
|
| 61 |
-
"message": "Offline/Modal VOID repair sample is documented but not a blocking runtime default.",
|
| 62 |
-
},
|
| 63 |
-
"offellia_judge": {
|
| 64 |
-
"status": "deferred_local",
|
| 65 |
-
"repo_id": "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 66 |
-
"message": "Quality/taste judge lane is declared in the Raven stack and runs only when local GGUF runtime is configured.",
|
| 67 |
-
},
|
| 68 |
-
"audio_lore_tts": {
|
| 69 |
-
"status": "optional",
|
| 70 |
-
"repo_id": "hexgrad/Kokoro-82M",
|
| 71 |
-
"message": "Lore narration lane is off by default for the public demo.",
|
| 72 |
-
},
|
| 73 |
-
"tiny_titan_sidecar": {
|
| 74 |
-
"status": "available",
|
| 75 |
-
"repo_id": "black-forest-labs/FLUX.2-klein-4B",
|
| 76 |
-
"message": "Public-safe 4B sidecar remains selectable without weakening the quality preset.",
|
| 77 |
-
},
|
| 78 |
}
|
| 79 |
|
| 80 |
|
|
@@ -83,7 +63,7 @@ def _zero_gpu_entrypoint(fn: Any) -> Any:
|
|
| 83 |
gpu_decorator = getattr(spaces, "GPU", None) if spaces is not None else None
|
| 84 |
if gpu_decorator is None:
|
| 85 |
return fn
|
| 86 |
-
return gpu_decorator(duration=
|
| 87 |
|
| 88 |
|
| 89 |
def _relay_snapshot(adult_mode: bool = False) -> dict[str, Any]:
|
|
@@ -99,6 +79,103 @@ def _file_path(uploaded: Any) -> str | None:
|
|
| 99 |
return str(path) if path else None
|
| 100 |
|
| 101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
|
| 103 |
generation = (operator_state or {}).get("generation") or {}
|
| 104 |
output_path = generation.get("output_path")
|
|
@@ -159,16 +236,41 @@ def run_weave(
|
|
| 159 |
adult_mode: bool,
|
| 160 |
upload: Any,
|
| 161 |
active_section: str,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 162 |
) -> tuple[Any, ...]:
|
| 163 |
prompt = prompt.strip() or DEFAULT_PROMPT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
run = build_command_center_run(
|
| 165 |
-
prompt=
|
| 166 |
mode=reasoning_mode,
|
| 167 |
video_preset=video_preset,
|
| 168 |
adult_mode=adult_mode,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
)
|
| 170 |
-
reference_scan = scan_file(_file_path(upload))
|
| 171 |
-
generation = generate_flux_image(run.refined_prompt.refined, seed=_checkpoint_seed(run.checkpoint.checkpoint_id))
|
| 172 |
generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
|
| 173 |
minicpm = judge_with_minicpm(
|
| 174 |
prompt=run.refined_prompt.refined,
|
|
@@ -185,31 +287,17 @@ def run_weave(
|
|
| 185 |
if generation.status == "success":
|
| 186 |
provider_state = "generated"
|
| 187 |
operator_state = {
|
| 188 |
-
**_default_operator_state(),
|
| 189 |
-
"active_preset": "Raven Quality Stack",
|
| 190 |
"provider_state": provider_state,
|
| 191 |
"checkpoint": "pending_review",
|
| 192 |
"export": generated_scan.get("export_gate", "pending"),
|
| 193 |
"message": generation.message or "Run packet generated. Human checkpoint required before provider promotion or export.",
|
| 194 |
"generation": generation.to_dict(),
|
|
|
|
|
|
|
| 195 |
"reference_scan": reference_scan,
|
| 196 |
"generated_scan": generated_scan,
|
| 197 |
"minicpm_judge": minicpm.to_dict(),
|
| 198 |
"nemotron_evidence": nemotron.to_dict(),
|
| 199 |
-
"locateanything_grounding": {
|
| 200 |
-
"status": run.inspection.status,
|
| 201 |
-
"repo_id": run.inspection.locate_model,
|
| 202 |
-
"targets": [
|
| 203 |
-
{
|
| 204 |
-
"slot_name": target.slot_name,
|
| 205 |
-
"query": target.query,
|
| 206 |
-
"expected_region": target.expected_region,
|
| 207 |
-
"confidence": target.confidence,
|
| 208 |
-
}
|
| 209 |
-
for target in run.inspection.targets[:6]
|
| 210 |
-
],
|
| 211 |
-
"drift_flags": run.inspection.drift_flags,
|
| 212 |
-
},
|
| 213 |
}
|
| 214 |
regions = _dashboard_regions(
|
| 215 |
run=run,
|
|
@@ -329,10 +417,12 @@ def scan_reference(
|
|
| 329 |
upload: Any,
|
| 330 |
active_section: str,
|
| 331 |
operator_state: dict[str, Any] | None,
|
|
|
|
| 332 |
) -> tuple[Any, ...]:
|
| 333 |
state = operator_state or _default_operator_state()
|
| 334 |
reference_path = _file_path(upload)
|
| 335 |
reference_scan = scan_file(reference_path)
|
|
|
|
| 336 |
generated_scan = _authoritative_generated_scan(state)
|
| 337 |
minicpm = None
|
| 338 |
if run is not None and reference_path:
|
|
@@ -342,27 +432,10 @@ def scan_reference(
|
|
| 342 |
scan=reference_scan,
|
| 343 |
wardrobe_summary=_wardrobe_summary(run),
|
| 344 |
)
|
| 345 |
-
locate_plan = {}
|
| 346 |
-
if run is not None:
|
| 347 |
-
locate_plan = {
|
| 348 |
-
"status": run.inspection.status,
|
| 349 |
-
"repo_id": run.inspection.locate_model,
|
| 350 |
-
"source": "reference_scan",
|
| 351 |
-
"targets": [
|
| 352 |
-
{
|
| 353 |
-
"slot_name": target.slot_name,
|
| 354 |
-
"query": target.query,
|
| 355 |
-
"expected_region": target.expected_region,
|
| 356 |
-
"confidence": target.confidence,
|
| 357 |
-
}
|
| 358 |
-
for target in run.inspection.targets[:6]
|
| 359 |
-
],
|
| 360 |
-
"drift_flags": run.inspection.drift_flags,
|
| 361 |
-
}
|
| 362 |
next_state = {
|
| 363 |
**state,
|
| 364 |
**({"reference_judge": minicpm.to_dict()} if minicpm else {}),
|
| 365 |
-
|
| 366 |
"reference_scan": reference_scan,
|
| 367 |
"reference_export_gate": reference_scan.get("export_gate", "pending"),
|
| 368 |
"export": state.get("export", generated_scan.get("export_gate", "pending")),
|
|
@@ -413,36 +486,25 @@ def export_packet(
|
|
| 413 |
scan: dict[str, Any] | None,
|
| 414 |
active_section: str,
|
| 415 |
operator_state: dict[str, Any] | None,
|
| 416 |
-
override_reason: str = "",
|
| 417 |
) -> tuple[Any, ...]:
|
| 418 |
state = operator_state or _default_operator_state()
|
| 419 |
scan = _authoritative_generated_scan(state)
|
| 420 |
-
override_reason = (override_reason or "").strip()
|
| 421 |
if run is None:
|
| 422 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: no active run packet exists."}
|
| 423 |
elif state.get("checkpoint") != "approved":
|
| 424 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: human checkpoint has not been approved."}
|
| 425 |
elif not _generated_output_path(state):
|
| 426 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: no generated artifact exists."}
|
| 427 |
-
elif scan.get("export_gate") != "clear"
|
| 428 |
-
next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export blocked: ST3GG gate is not clear.
|
| 429 |
else:
|
| 430 |
-
|
| 431 |
-
export_input_state = {
|
| 432 |
-
**state,
|
| 433 |
-
**({"st3gg_override_reason": override_reason} if override_reason and scan.get("export_gate") != "clear" else {}),
|
| 434 |
-
}
|
| 435 |
-
export = write_export_packet(run=run, scan=scan, operator_state=export_input_state, adult_mode=adult_mode)
|
| 436 |
next_state = {
|
| 437 |
-
**
|
| 438 |
"provider_state": "exported",
|
| 439 |
-
"export":
|
| 440 |
"export_packet": {"path": export["path"]},
|
| 441 |
-
"message":
|
| 442 |
-
f"Governed export packet prepared with ST3GG override recorded: {export['path']}"
|
| 443 |
-
if export_state == "override"
|
| 444 |
-
else f"Governed export packet prepared: {export['path']}"
|
| 445 |
-
),
|
| 446 |
}
|
| 447 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
| 448 |
|
|
@@ -521,6 +583,43 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 521 |
value="Wan2.2 I2V",
|
| 522 |
label="Video Path Preset",
|
| 523 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
with gr.Row():
|
| 525 |
upload = gr.File(
|
| 526 |
label="Reference / Output For ST3GG Scan",
|
|
@@ -536,13 +635,6 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 536 |
)
|
| 537 |
run_btn = gr.Button("Run Active Weave", variant="primary", scale=1)
|
| 538 |
stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
|
| 539 |
-
override_reason = gr.Textbox(
|
| 540 |
-
value="",
|
| 541 |
-
label="ST3GG Override Reason",
|
| 542 |
-
placeholder="Required only to export a reviewed/blocked artifact. Explain why the evidence packet may be written.",
|
| 543 |
-
lines=2,
|
| 544 |
-
max_lines=3,
|
| 545 |
-
)
|
| 546 |
with gr.Row(elem_id="nw-operator-actions", elem_classes=["nw-operator-actions"]):
|
| 547 |
scan_btn = gr.Button("Scan Reference", scale=1)
|
| 548 |
checkpoint_btn = gr.Button("Approve Checkpoint", scale=1)
|
|
@@ -596,17 +688,21 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 596 |
|
| 597 |
operator_outputs = dashboard_outputs + [operator_state, stop_btn]
|
| 598 |
|
| 599 |
-
run_btn.click(
|
| 600 |
fn=run_weave,
|
| 601 |
-
inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
|
| 602 |
outputs=stateful_outputs,
|
| 603 |
api_name="run_active_weave",
|
|
|
|
|
|
|
| 604 |
)
|
| 605 |
-
prompt.submit(
|
| 606 |
fn=run_weave,
|
| 607 |
-
inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
|
| 608 |
outputs=stateful_outputs,
|
| 609 |
api_name=False,
|
|
|
|
|
|
|
| 610 |
)
|
| 611 |
adult_mode.change(
|
| 612 |
fn=toggle_adult_visibility,
|
|
@@ -624,42 +720,51 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
|
|
| 624 |
operator_state,
|
| 625 |
],
|
| 626 |
api_name="toggle_adult_catalog",
|
|
|
|
| 627 |
)
|
| 628 |
section_nav.change(
|
| 629 |
fn=refresh_section,
|
| 630 |
inputs=[section_nav, adult_mode, active_run_state, scan_state, operator_state],
|
| 631 |
outputs=[command_rail_html, operations_html, inspector_html, artifact_html, provider_html, scan_json],
|
| 632 |
api_name=False,
|
|
|
|
| 633 |
)
|
| 634 |
scan_btn.click(
|
| 635 |
fn=scan_reference,
|
| 636 |
-
inputs=[active_run_state, adult_mode, upload, section_nav, operator_state],
|
| 637 |
outputs=dashboard_outputs + [operator_state, stop_btn, scan_state],
|
| 638 |
api_name="scan_reference",
|
|
|
|
| 639 |
)
|
| 640 |
checkpoint_btn.click(
|
| 641 |
fn=approve_checkpoint,
|
| 642 |
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
|
| 643 |
outputs=operator_outputs,
|
| 644 |
api_name="approve_checkpoint",
|
|
|
|
| 645 |
)
|
| 646 |
export_btn.click(
|
| 647 |
fn=export_packet,
|
| 648 |
-
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state
|
| 649 |
outputs=operator_outputs,
|
| 650 |
api_name="prepare_export_packet",
|
|
|
|
| 651 |
)
|
| 652 |
stop_btn.click(
|
| 653 |
fn=stop_provider_job,
|
| 654 |
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
|
| 655 |
outputs=operator_outputs,
|
| 656 |
api_name="stop_provider_job",
|
|
|
|
|
|
|
| 657 |
)
|
| 658 |
reset_btn.click(
|
| 659 |
fn=reset_demo,
|
| 660 |
inputs=[adult_mode, section_nav],
|
| 661 |
outputs=stateful_outputs,
|
| 662 |
api_name="reset_demo_state",
|
|
|
|
|
|
|
| 663 |
)
|
| 664 |
demo.load(
|
| 665 |
fn=lambda: (render_catalog_table(False), catalog_summary(False), scan_file(None), scan_file(None), _default_operator_state()),
|
|
|
|
| 4 |
|
| 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
|
| 11 |
|
| 12 |
import gradio as gr
|
| 13 |
|
|
|
|
| 51 |
|
| 52 |
def _default_operator_state() -> dict[str, Any]:
|
| 53 |
return {
|
|
|
|
| 54 |
"provider_state": "idle",
|
| 55 |
"checkpoint": "pending",
|
| 56 |
"export": "pending",
|
| 57 |
"message": "No operator action yet.",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
}
|
| 59 |
|
| 60 |
|
|
|
|
| 63 |
gpu_decorator = getattr(spaces, "GPU", None) if spaces is not None else None
|
| 64 |
if gpu_decorator is None:
|
| 65 |
return fn
|
| 66 |
+
return gpu_decorator(duration=300)(fn)
|
| 67 |
|
| 68 |
|
| 69 |
def _relay_snapshot(adult_mode: bool = False) -> dict[str, Any]:
|
|
|
|
| 79 |
return str(path) if path else None
|
| 80 |
|
| 81 |
|
| 82 |
+
def _safe_file_hash(path: str | None) -> tuple[str | None, int | None]:
|
| 83 |
+
if not path:
|
| 84 |
+
return None, None
|
| 85 |
+
try:
|
| 86 |
+
target = Path(path)
|
| 87 |
+
data = target.read_bytes()
|
| 88 |
+
except OSError:
|
| 89 |
+
return None, None
|
| 90 |
+
return hashlib.sha256(data).hexdigest(), len(data)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def _safe_reference_url_metadata(reference_url: str | None) -> dict[str, Any] | None:
|
| 94 |
+
if not reference_url:
|
| 95 |
+
return None
|
| 96 |
+
parsed = urlparse(reference_url.strip())
|
| 97 |
+
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
|
| 98 |
+
return {"source": "url", "status": "invalid_url", "message": "Reference URL must be http(s)."}
|
| 99 |
+
url_hash = hashlib.sha256(reference_url.strip().encode("utf-8")).hexdigest()
|
| 100 |
+
return {
|
| 101 |
+
"source": "url",
|
| 102 |
+
"status": "metadata_only",
|
| 103 |
+
"domain": parsed.netloc.lower(),
|
| 104 |
+
"url_hash": url_hash,
|
| 105 |
+
"message": "URL stored as metadata only; Space runtime does not crawl or copy shop images.",
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def _reference_metadata(uploaded: Any, reference_url: str | None, scan: dict[str, Any]) -> list[dict[str, Any]]:
|
| 110 |
+
records: list[dict[str, Any]] = []
|
| 111 |
+
path = _file_path(uploaded)
|
| 112 |
+
if path:
|
| 113 |
+
file_hash, size = _safe_file_hash(path)
|
| 114 |
+
records.append(
|
| 115 |
+
{
|
| 116 |
+
"source": "upload",
|
| 117 |
+
"basename": Path(path).name,
|
| 118 |
+
"sha256": file_hash,
|
| 119 |
+
"size_bytes": size,
|
| 120 |
+
"st3gg_status": scan.get("status"),
|
| 121 |
+
"export_gate": scan.get("export_gate"),
|
| 122 |
+
"magic": scan.get("magic"),
|
| 123 |
+
"extension": scan.get("extension"),
|
| 124 |
+
}
|
| 125 |
+
)
|
| 126 |
+
url_record = _safe_reference_url_metadata(reference_url)
|
| 127 |
+
if url_record:
|
| 128 |
+
records.append(url_record)
|
| 129 |
+
return records
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def _creator_controls(
|
| 133 |
+
reasoning_mode: str,
|
| 134 |
+
video_preset: str,
|
| 135 |
+
silhouette: str | None = None,
|
| 136 |
+
outerwear: str | None = None,
|
| 137 |
+
upper_body: str | None = None,
|
| 138 |
+
footwear: str | None = None,
|
| 139 |
+
palette: str | None = None,
|
| 140 |
+
hardware: str | None = None,
|
| 141 |
+
locate_focus: list[str] | None = None,
|
| 142 |
+
) -> dict[str, Any]:
|
| 143 |
+
wardrobe = {
|
| 144 |
+
"silhouette": silhouette or "structured long coat",
|
| 145 |
+
"outerwear": outerwear or "black patent leather long coat",
|
| 146 |
+
"upper_body": upper_body or "Chantilly lace neckline",
|
| 147 |
+
"footwear": footwear or "platform boots",
|
| 148 |
+
"palette": palette or "black, crimson, cyan neon",
|
| 149 |
+
"hardware": hardware or "crimson hardware",
|
| 150 |
+
"locked_slots": ["outerwear", "upper_body", "footwear", "jewelry"],
|
| 151 |
+
"locate_focus": locate_focus or ["outerwear", "footwear", "jewelry"],
|
| 152 |
+
}
|
| 153 |
+
return {
|
| 154 |
+
"reasoning_mode": reasoning_mode,
|
| 155 |
+
"video_preset": video_preset,
|
| 156 |
+
"wardrobe": wardrobe,
|
| 157 |
+
"generation": {
|
| 158 |
+
"flux_primary": "black-forest-labs/FLUX.2-klein-9B",
|
| 159 |
+
"flux_sidecar": "black-forest-labs/FLUX.2-klein-4B",
|
| 160 |
+
"lora_policy": "attempt compatible runtime adapter; report loaded/skipped/failed",
|
| 161 |
+
},
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
def _prompt_with_controls(prompt: str, controls: dict[str, Any]) -> str:
|
| 166 |
+
wardrobe = controls.get("wardrobe", {})
|
| 167 |
+
additions = [
|
| 168 |
+
wardrobe.get("silhouette"),
|
| 169 |
+
wardrobe.get("outerwear"),
|
| 170 |
+
wardrobe.get("upper_body"),
|
| 171 |
+
wardrobe.get("footwear"),
|
| 172 |
+
wardrobe.get("palette"),
|
| 173 |
+
wardrobe.get("hardware"),
|
| 174 |
+
]
|
| 175 |
+
suffix = ", ".join(str(item) for item in additions if item)
|
| 176 |
+
return f"{prompt}\nWardrobe controls: {suffix}" if suffix else prompt
|
| 177 |
+
|
| 178 |
+
|
| 179 |
def _generated_output_path(operator_state: dict[str, Any] | None) -> str | None:
|
| 180 |
generation = (operator_state or {}).get("generation") or {}
|
| 181 |
output_path = generation.get("output_path")
|
|
|
|
| 236 |
adult_mode: bool,
|
| 237 |
upload: Any,
|
| 238 |
active_section: str,
|
| 239 |
+
silhouette: str | None = None,
|
| 240 |
+
outerwear: str | None = None,
|
| 241 |
+
upper_body: str | None = None,
|
| 242 |
+
footwear: str | None = None,
|
| 243 |
+
palette: str | None = None,
|
| 244 |
+
hardware: str | None = None,
|
| 245 |
+
reference_url: str | None = None,
|
| 246 |
) -> tuple[Any, ...]:
|
| 247 |
prompt = prompt.strip() or DEFAULT_PROMPT
|
| 248 |
+
controls = _creator_controls(
|
| 249 |
+
reasoning_mode=reasoning_mode,
|
| 250 |
+
video_preset=video_preset,
|
| 251 |
+
silhouette=silhouette,
|
| 252 |
+
outerwear=outerwear,
|
| 253 |
+
upper_body=upper_body,
|
| 254 |
+
footwear=footwear,
|
| 255 |
+
palette=palette,
|
| 256 |
+
hardware=hardware,
|
| 257 |
+
)
|
| 258 |
+
controlled_prompt = _prompt_with_controls(prompt, controls)
|
| 259 |
+
reference_scan = scan_file(_file_path(upload))
|
| 260 |
+
reference_metadata = _reference_metadata(upload, reference_url, reference_scan)
|
| 261 |
run = build_command_center_run(
|
| 262 |
+
prompt=controlled_prompt,
|
| 263 |
mode=reasoning_mode,
|
| 264 |
video_preset=video_preset,
|
| 265 |
adult_mode=adult_mode,
|
| 266 |
+
creator_controls=controls,
|
| 267 |
+
reference_metadata=reference_metadata,
|
| 268 |
+
)
|
| 269 |
+
generation = generate_flux_image(
|
| 270 |
+
run.refined_prompt.refined,
|
| 271 |
+
seed=_checkpoint_seed(run.checkpoint.checkpoint_id),
|
| 272 |
+
adult_mode=adult_mode,
|
| 273 |
)
|
|
|
|
|
|
|
| 274 |
generated_scan = scan_file(generation.output_path) if generation.output_path else scan_file(None)
|
| 275 |
minicpm = judge_with_minicpm(
|
| 276 |
prompt=run.refined_prompt.refined,
|
|
|
|
| 287 |
if generation.status == "success":
|
| 288 |
provider_state = "generated"
|
| 289 |
operator_state = {
|
|
|
|
|
|
|
| 290 |
"provider_state": provider_state,
|
| 291 |
"checkpoint": "pending_review",
|
| 292 |
"export": generated_scan.get("export_gate", "pending"),
|
| 293 |
"message": generation.message or "Run packet generated. Human checkpoint required before provider promotion or export.",
|
| 294 |
"generation": generation.to_dict(),
|
| 295 |
+
"creator_controls": controls,
|
| 296 |
+
"reference_metadata": reference_metadata,
|
| 297 |
"reference_scan": reference_scan,
|
| 298 |
"generated_scan": generated_scan,
|
| 299 |
"minicpm_judge": minicpm.to_dict(),
|
| 300 |
"nemotron_evidence": nemotron.to_dict(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
}
|
| 302 |
regions = _dashboard_regions(
|
| 303 |
run=run,
|
|
|
|
| 417 |
upload: Any,
|
| 418 |
active_section: str,
|
| 419 |
operator_state: dict[str, Any] | None,
|
| 420 |
+
reference_url: str | None = None,
|
| 421 |
) -> tuple[Any, ...]:
|
| 422 |
state = operator_state or _default_operator_state()
|
| 423 |
reference_path = _file_path(upload)
|
| 424 |
reference_scan = scan_file(reference_path)
|
| 425 |
+
reference_metadata = _reference_metadata(upload, reference_url, reference_scan)
|
| 426 |
generated_scan = _authoritative_generated_scan(state)
|
| 427 |
minicpm = None
|
| 428 |
if run is not None and reference_path:
|
|
|
|
| 432 |
scan=reference_scan,
|
| 433 |
wardrobe_summary=_wardrobe_summary(run),
|
| 434 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
next_state = {
|
| 436 |
**state,
|
| 437 |
**({"reference_judge": minicpm.to_dict()} if minicpm else {}),
|
| 438 |
+
"reference_metadata": reference_metadata,
|
| 439 |
"reference_scan": reference_scan,
|
| 440 |
"reference_export_gate": reference_scan.get("export_gate", "pending"),
|
| 441 |
"export": state.get("export", generated_scan.get("export_gate", "pending")),
|
|
|
|
| 486 |
scan: dict[str, Any] | None,
|
| 487 |
active_section: str,
|
| 488 |
operator_state: dict[str, Any] | None,
|
|
|
|
| 489 |
) -> tuple[Any, ...]:
|
| 490 |
state = operator_state or _default_operator_state()
|
| 491 |
scan = _authoritative_generated_scan(state)
|
|
|
|
| 492 |
if run is None:
|
| 493 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: no active run packet exists."}
|
| 494 |
elif state.get("checkpoint") != "approved":
|
| 495 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: human checkpoint has not been approved."}
|
| 496 |
elif not _generated_output_path(state):
|
| 497 |
next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: no generated artifact exists."}
|
| 498 |
+
elif scan.get("export_gate") != "clear":
|
| 499 |
+
next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export blocked: ST3GG gate is not clear."}
|
| 500 |
else:
|
| 501 |
+
export = write_export_packet(run=run, scan=scan, operator_state=state, adult_mode=adult_mode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 502 |
next_state = {
|
| 503 |
+
**state,
|
| 504 |
"provider_state": "exported",
|
| 505 |
+
"export": "clear",
|
| 506 |
"export_packet": {"path": export["path"]},
|
| 507 |
+
"message": f"Governed export packet prepared: {export['path']}",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 508 |
}
|
| 509 |
return _render_stateful(run, adult_mode, scan, active_section, next_state)
|
| 510 |
|
|
|
|
| 583 |
value="Wan2.2 I2V",
|
| 584 |
label="Video Path Preset",
|
| 585 |
)
|
| 586 |
+
with gr.Row():
|
| 587 |
+
silhouette = gr.Dropdown(
|
| 588 |
+
["structured long coat", "fitted gothic bodice", "layered tactical silhouette"],
|
| 589 |
+
value="structured long coat",
|
| 590 |
+
label="Silhouette",
|
| 591 |
+
)
|
| 592 |
+
outerwear = gr.Dropdown(
|
| 593 |
+
["black patent leather long coat", "faux fur collar coat", "tailored rain slicker"],
|
| 594 |
+
value="black patent leather long coat",
|
| 595 |
+
label="Outerwear",
|
| 596 |
+
)
|
| 597 |
+
upper_body = gr.Dropdown(
|
| 598 |
+
["Chantilly lace neckline", "black mesh layer", "structured corset bodice"],
|
| 599 |
+
value="Chantilly lace neckline",
|
| 600 |
+
label="Upper Body",
|
| 601 |
+
)
|
| 602 |
+
footwear = gr.Dropdown(
|
| 603 |
+
["platform boots", "patent leather heels", "armored couture boots"],
|
| 604 |
+
value="platform boots",
|
| 605 |
+
label="Footwear",
|
| 606 |
+
)
|
| 607 |
+
with gr.Row():
|
| 608 |
+
palette = gr.Dropdown(
|
| 609 |
+
["black, crimson, cyan neon", "obsidian, pearl, crimson", "graphite, magenta, cold blue"],
|
| 610 |
+
value="black, crimson, cyan neon",
|
| 611 |
+
label="Palette",
|
| 612 |
+
)
|
| 613 |
+
hardware = gr.Dropdown(
|
| 614 |
+
["crimson hardware", "silver occult buckles", "holographic NEXUS sigils"],
|
| 615 |
+
value="crimson hardware",
|
| 616 |
+
label="Hardware",
|
| 617 |
+
)
|
| 618 |
+
reference_url = gr.Textbox(
|
| 619 |
+
label="Reference URL (metadata only)",
|
| 620 |
+
placeholder="https://shop.example/reference-garment",
|
| 621 |
+
scale=2,
|
| 622 |
+
)
|
| 623 |
with gr.Row():
|
| 624 |
upload = gr.File(
|
| 625 |
label="Reference / Output For ST3GG Scan",
|
|
|
|
| 635 |
)
|
| 636 |
run_btn = gr.Button("Run Active Weave", variant="primary", scale=1)
|
| 637 |
stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 638 |
with gr.Row(elem_id="nw-operator-actions", elem_classes=["nw-operator-actions"]):
|
| 639 |
scan_btn = gr.Button("Scan Reference", scale=1)
|
| 640 |
checkpoint_btn = gr.Button("Approve Checkpoint", scale=1)
|
|
|
|
| 688 |
|
| 689 |
operator_outputs = dashboard_outputs + [operator_state, stop_btn]
|
| 690 |
|
| 691 |
+
run_click = run_btn.click(
|
| 692 |
fn=run_weave,
|
| 693 |
+
inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav, silhouette, outerwear, upper_body, footwear, palette, hardware, reference_url],
|
| 694 |
outputs=stateful_outputs,
|
| 695 |
api_name="run_active_weave",
|
| 696 |
+
concurrency_limit=1,
|
| 697 |
+
concurrency_id="flux-gpu",
|
| 698 |
)
|
| 699 |
+
run_submit = prompt.submit(
|
| 700 |
fn=run_weave,
|
| 701 |
+
inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav, silhouette, outerwear, upper_body, footwear, palette, hardware, reference_url],
|
| 702 |
outputs=stateful_outputs,
|
| 703 |
api_name=False,
|
| 704 |
+
concurrency_limit=1,
|
| 705 |
+
concurrency_id="flux-gpu",
|
| 706 |
)
|
| 707 |
adult_mode.change(
|
| 708 |
fn=toggle_adult_visibility,
|
|
|
|
| 720 |
operator_state,
|
| 721 |
],
|
| 722 |
api_name="toggle_adult_catalog",
|
| 723 |
+
queue=False,
|
| 724 |
)
|
| 725 |
section_nav.change(
|
| 726 |
fn=refresh_section,
|
| 727 |
inputs=[section_nav, adult_mode, active_run_state, scan_state, operator_state],
|
| 728 |
outputs=[command_rail_html, operations_html, inspector_html, artifact_html, provider_html, scan_json],
|
| 729 |
api_name=False,
|
| 730 |
+
queue=False,
|
| 731 |
)
|
| 732 |
scan_btn.click(
|
| 733 |
fn=scan_reference,
|
| 734 |
+
inputs=[active_run_state, adult_mode, upload, section_nav, operator_state, reference_url],
|
| 735 |
outputs=dashboard_outputs + [operator_state, stop_btn, scan_state],
|
| 736 |
api_name="scan_reference",
|
| 737 |
+
queue=False,
|
| 738 |
)
|
| 739 |
checkpoint_btn.click(
|
| 740 |
fn=approve_checkpoint,
|
| 741 |
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
|
| 742 |
outputs=operator_outputs,
|
| 743 |
api_name="approve_checkpoint",
|
| 744 |
+
queue=False,
|
| 745 |
)
|
| 746 |
export_btn.click(
|
| 747 |
fn=export_packet,
|
| 748 |
+
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
|
| 749 |
outputs=operator_outputs,
|
| 750 |
api_name="prepare_export_packet",
|
| 751 |
+
queue=False,
|
| 752 |
)
|
| 753 |
stop_btn.click(
|
| 754 |
fn=stop_provider_job,
|
| 755 |
inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
|
| 756 |
outputs=operator_outputs,
|
| 757 |
api_name="stop_provider_job",
|
| 758 |
+
queue=False,
|
| 759 |
+
cancels=[run_click, run_submit],
|
| 760 |
)
|
| 761 |
reset_btn.click(
|
| 762 |
fn=reset_demo,
|
| 763 |
inputs=[adult_mode, section_nav],
|
| 764 |
outputs=stateful_outputs,
|
| 765 |
api_name="reset_demo_state",
|
| 766 |
+
queue=False,
|
| 767 |
+
cancels=[run_click, run_submit],
|
| 768 |
)
|
| 769 |
demo.load(
|
| 770 |
fn=lambda: (render_catalog_table(False), catalog_summary(False), scan_file(None), scan_file(None), _default_operator_state()),
|
docs/HACKATHON_EVALUATION.md
CHANGED
|
@@ -13,11 +13,11 @@ NEXUS Visual Weaver should open as a working command center, not a landing page.
|
|
| 13 |
## Current Strengths
|
| 14 |
|
| 15 |
- Gradio-compatible app shape with `mcp_server=True`.
|
| 16 |
-
- Pinned model governance is visible: FLUX.2 Klein
|
| 17 |
-
- Real FLUX.2 Klein
|
| 18 |
- Generated artifacts are scanned by ST3GG before checkpoint/export.
|
| 19 |
- Above-fold trust strip makes ST3GG verdict, export gate, fixture evidence, and adult-mode safety boundaries visible immediately.
|
| 20 |
-
- OpenBMB MiniCPM-V 4.6
|
| 21 |
- Adult Mode starts off and is framed as catalog scope, not a safety bypass.
|
| 22 |
- ModelRelay/GMR helper rotation is represented without replacing pinned lanes.
|
| 23 |
- Tests cover catalog scope, workflow planning, ModelRelay behavior, scanner evidence, and dashboard fallback rendering.
|
|
@@ -32,21 +32,21 @@ NEXUS Visual Weaver should open as a working command center, not a landing page.
|
|
| 32 |
|
| 33 |
## Next Implementation Priority
|
| 34 |
|
| 35 |
-
1.
|
| 36 |
-
2.
|
| 37 |
-
3.
|
| 38 |
-
4.
|
| 39 |
-
5.
|
| 40 |
|
| 41 |
## Prize Claim Evidence Rules
|
| 42 |
|
| 43 |
| Prize or badge | Current stance |
|
| 44 |
| --- | --- |
|
| 45 |
-
| Build Small base eligibility | Gradio Space,
|
| 46 |
| Off Brand | Strong custom command-center UI signal. |
|
| 47 |
| Best Agent | Multi-step governed workflow is implemented through callbacks and export packet. |
|
| 48 |
| OpenBMB | Claim only after MiniCPM-V returns `success` in export evidence. |
|
| 49 |
| NVIDIA | Claim only after Nemotron returns `success` in export evidence. |
|
| 50 |
| OpenAI Codex | GitHub branch/PR provides Codex development trail. |
|
| 51 |
-
| Tiny Titan |
|
| 52 |
-
| Modal | Not claimed unless a real
|
|
|
|
| 13 |
## Current Strengths
|
| 14 |
|
| 15 |
- Gradio-compatible app shape with `mcp_server=True`.
|
| 16 |
+
- Pinned model governance is visible: FLUX.2 Klein 4B, LocateAnything-3B, and ST3GG.
|
| 17 |
+
- Real FLUX.2 Klein 4B generation is wired for HF Space and falls back to an honest dry-run state outside Space.
|
| 18 |
- Generated artifacts are scanned by ST3GG before checkpoint/export.
|
| 19 |
- Above-fold trust strip makes ST3GG verdict, export gate, fixture evidence, and adult-mode safety boundaries visible immediately.
|
| 20 |
+
- OpenBMB MiniCPM-V 4.6 and NVIDIA Nemotron evidence lanes are represented as real optional provider adapters with missing-secret/failed/success states.
|
| 21 |
- Adult Mode starts off and is framed as catalog scope, not a safety bypass.
|
| 22 |
- ModelRelay/GMR helper rotation is represented without replacing pinned lanes.
|
| 23 |
- Tests cover catalog scope, workflow planning, ModelRelay behavior, scanner evidence, and dashboard fallback rendering.
|
|
|
|
| 32 |
|
| 33 |
## Next Implementation Priority
|
| 34 |
|
| 35 |
+
1. Configure OpenBMB and Nemotron Space secrets if prize claims are desired.
|
| 36 |
+
2. Run one live Space weave and prepare an export packet.
|
| 37 |
+
3. Capture demo video and create social post.
|
| 38 |
+
4. Add final demo/social URLs to README.
|
| 39 |
+
5. Add Playwright/browser visual checks for desktop and mobile overflow once CI is unblocked.
|
| 40 |
|
| 41 |
## Prize Claim Evidence Rules
|
| 42 |
|
| 43 |
| Prize or badge | Current stance |
|
| 44 |
| --- | --- |
|
| 45 |
+
| Build Small base eligibility | Gradio Space, <=32B stack, and public app path are ready; demo/social links still required. |
|
| 46 |
| Off Brand | Strong custom command-center UI signal. |
|
| 47 |
| Best Agent | Multi-step governed workflow is implemented through callbacks and export packet. |
|
| 48 |
| OpenBMB | Claim only after MiniCPM-V returns `success` in export evidence. |
|
| 49 |
| NVIDIA | Claim only after Nemotron returns `success` in export evidence. |
|
| 50 |
| OpenAI Codex | GitHub branch/PR provides Codex development trail. |
|
| 51 |
+
| Tiny Titan | Public demo stack is eligible: active public models are each <=4B. |
|
| 52 |
+
| Modal | Not claimed unless a real Modal job runs. |
|
docs/HANDOFF_FINAL_HACKATHON.md
CHANGED
|
@@ -3,30 +3,24 @@
|
|
| 3 |
## Current Target
|
| 4 |
|
| 5 |
- GitHub repo: `https://github.com/specimba/NEXUS-Visual-Weaver`
|
| 6 |
-
- Working branch: `
|
| 7 |
- HF Space: `build-small-hackathon/NEXUS_Visual_Weaver`
|
| 8 |
- Public Space URL: `https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/`
|
| 9 |
- HF rollback SHA: `410a467c55d11e7308249198bd5fe0b2c190aec6`.
|
| 10 |
-
- Stable rollback tag: `stable-raven-quality-20260615` -> `aa37d4d`.
|
| 11 |
-
- Last verified code commit: `aa37d4d` (`fix: load flux2 klein pipeline`).
|
| 12 |
-
- Last verified HF Space commit: `effbdb4c6a1ea98410165310caea10097ffa0ca6`.
|
| 13 |
-
- Last verified HF runtime: `RUNNING`, ZeroGPU, dev mode disabled, `/data` bucket mounted.
|
| 14 |
- Branch discipline: use only `main` and `codex/specimba/ui-polish-command-center`; no extra recovery branches.
|
| 15 |
-
- Primary goal: finish a countable Build Small submission with
|
| 16 |
|
| 17 |
## Secrets Needed
|
| 18 |
|
| 19 |
Do not paste these into chat, commits, logs, or export packets.
|
| 20 |
|
| 21 |
-
-
|
| 22 |
-
- `HF_TOKEN`: required for gated FLUX.2 Klein 9B access after license acceptance; the app can honestly fall back to the 4B Tiny Titan sidecar if the 9B lane is unavailable.
|
| 23 |
- `MINICPM_BASE_URL`: OpenBMB OpenAI-compatible endpoint base URL.
|
| 24 |
- `MINICPM_API_KEY`: OpenBMB bearer token.
|
| 25 |
- `MINICPM_MODEL`: default `MiniCPM-V-4.6`.
|
| 26 |
- `NEMOTRON_BASE_URL`: OpenAI-compatible Nemotron endpoint if available.
|
| 27 |
- `NEMOTRON_API_KEY` or `NVIDIA_API_KEY`: Nemotron provider token.
|
| 28 |
- `NEMOTRON_MODEL`: default `nvidia/NVIDIA-Nemotron-Parse-v1.2`.
|
| 29 |
-
- `MODAL_TOKEN_ID` and `MODAL_TOKEN_SECRET`: optional for a documented `netflix/void-model` video repair sidecar job.
|
| 30 |
|
| 31 |
## Verification Commands
|
| 32 |
|
|
@@ -35,76 +29,38 @@ python -m compileall app.py src tests
|
|
| 35 |
$env:NEXUS_DISABLE_REAL_HF='1'
|
| 36 |
python -c "import app; print('app import ok')"
|
| 37 |
$env:PYTEST_DISABLE_PLUGIN_AUTOLOAD='1'
|
| 38 |
-
python -m pytest -q tests -p no:cacheprovider
|
| 39 |
hf auth whoami --format json
|
| 40 |
hf spaces info build-small-hackathon/NEXUS_Visual_Weaver --format json
|
| 41 |
```
|
| 42 |
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
## HF Space Log Observation
|
| 46 |
-
|
| 47 |
-
Use the authenticated Hugging Face SSE log APIs for final runtime/build evidence. Do not paste tokens into chat or files; use a local environment variable or the local `huggingface_hub` token cache.
|
| 48 |
-
|
| 49 |
-
```powershell
|
| 50 |
-
# Container logs
|
| 51 |
-
curl.exe -N -H "Authorization: Bearer $env:HF_TOKEN" `
|
| 52 |
-
"https://huggingface.co/api/spaces/build-small-hackathon/NEXUS_Visual_Weaver/logs/run"
|
| 53 |
-
|
| 54 |
-
# Build logs
|
| 55 |
-
curl.exe -N -H "Authorization: Bearer $env:HF_TOKEN" `
|
| 56 |
-
"https://huggingface.co/api/spaces/build-small-hackathon/NEXUS_Visual_Weaver/logs/build"
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
If local proxy/TLS settings break PowerShell or `curl`, use a bounded Python/httpx stream with `trust_env=False`, loaded from the local HF token cache. Redact the token from any printed output.
|
| 60 |
-
|
| 61 |
-
Current evidence from the SSE API:
|
| 62 |
-
|
| 63 |
-
- `logs/run` returns HTTP 200 and shows the Gradio/MCP startup stream.
|
| 64 |
-
- `logs/build` returns HTTP 200 and shows Build Queued for Space commit `dc6756e`.
|
| 65 |
-
- During the final sprint, HF CLI logs hit local Windows proxy/Unicode issues. Public no-proxy probes verified root HTTP 200 and `/gradio_api/info` callback exposure.
|
| 66 |
|
| 67 |
## Runtime Flow
|
| 68 |
|
| 69 |
-
1. `run_active_weave` builds the Raven Chronicle run packet
|
| 70 |
-
2. FLUX.2 Klein
|
| 71 |
3. Generated artifact is scanned by ST3GG.
|
| 72 |
4. MiniCPM-V judge runs when OpenBMB secrets are present.
|
| 73 |
5. Nemotron evidence runs when Nemotron/NVIDIA endpoint secrets are present.
|
| 74 |
-
6.
|
| 75 |
-
7. `
|
| 76 |
-
8. `prepare_export_packet` writes a governed JSON packet to `/data/nexus_visual_weaver/exports` or `outputs/exports`.
|
| 77 |
|
| 78 |
## Claim Rules
|
| 79 |
|
| 80 |
- OpenBMB prize claim requires `minicpm_judge.status == "success"` in an export packet.
|
| 81 |
- NVIDIA prize claim requires `nemotron_evidence.status == "success"` in an export packet.
|
| 82 |
- LocateAnything supports the grounding story but does not replace Nemotron for the NVIDIA prize.
|
| 83 |
-
- Tiny Titan can be claimed only from a successful
|
| 84 |
-
-
|
| 85 |
-
- Modal is not claimed unless a real
|
| 86 |
|
| 87 |
## Known Risks
|
| 88 |
|
| 89 |
- GitHub CLI may fail behind proxy `127.0.0.1:9`; use local git status and HF verification when blocked.
|
| 90 |
-
- Real FLUX generation depends on Space GPU availability and
|
| 91 |
- OpenBMB and Nemotron endpoints are optional and must show `missing secret` rather than fake success when not configured.
|
| 92 |
- Demo video and social post links must be added before final submission.
|
| 93 |
-
- Dev mode served stale `dc6756e` until disabled through the HF API. Keep dev mode off for final judging unless you immediately verify `/config` after re-enabling.
|
| 94 |
-
- The app now supports an explicit ST3GG override reason for evidence-packet export when a generated artifact is review/blocked. This does not mark ST3GG as clear; it records the blocked gate and the human reason.
|
| 95 |
-
|
| 96 |
-
## Last Verified Checks
|
| 97 |
-
|
| 98 |
-
- Local compile: `python -m compileall app.py src tests` passed.
|
| 99 |
-
- Local import: `NEXUS_DISABLE_REAL_HF=1 python -c "import app; print('app import ok')"` passed.
|
| 100 |
-
- Local tests: `123 passed, 1 warning`.
|
| 101 |
-
- Secret scan: no `hf_`, `Bearer`, `sk-`, or obvious API-key literals in tracked files.
|
| 102 |
-
- Public Space: root HTTP 200.
|
| 103 |
-
- Public Space API: `/gradio_api/info` exposed `run_active_weave`, `scan_reference`, `approve_checkpoint`, `prepare_export_packet`, and `toggle_adult_catalog`.
|
| 104 |
-
- Public Space config: `Raven Quality Stack` and `FLUX.2 9B PINNED` present; old `Dark Couture v2.4` and `FLUX.2 4B PINNED` absent.
|
| 105 |
-
- Live weave: real FLUX image generated after switching to `Flux2KleinPipeline`; ST3GG marked the generated PNG `review` and blocked export due high entropy review, proving the export gate is active.
|
| 106 |
-
- Readiness: the UI now shows explicit gates for Space/API, Raven Stack, ST3GG, FLUX artifact, checkpoint, export packet, sponsor evidence, and demo/social.
|
| 107 |
-
- Submission assets: see `docs/SUBMISSION_ASSETS.md` for demo script, social draft, thumbnail direction, and final link checklist.
|
| 108 |
|
| 109 |
## Last-Step Checklist
|
| 110 |
|
|
|
|
| 3 |
## Current Target
|
| 4 |
|
| 5 |
- GitHub repo: `https://github.com/specimba/NEXUS-Visual-Weaver`
|
| 6 |
+
- Working branch: `codex/specimba/ui-polish-command-center`
|
| 7 |
- HF Space: `build-small-hackathon/NEXUS_Visual_Weaver`
|
| 8 |
- Public Space URL: `https://build-small-hackathon-nexus-visual-weaver-a107340.hf.space/`
|
| 9 |
- HF rollback SHA: `410a467c55d11e7308249198bd5fe0b2c190aec6`.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
- Branch discipline: use only `main` and `codex/specimba/ui-polish-command-center`; no extra recovery branches.
|
| 11 |
+
- Primary goal: finish a countable Build Small submission with real FLUX.2 4B generation, ST3GG scan, optional OpenBMB MiniCPM-V judge evidence, optional NVIDIA Nemotron evidence, checkpointed export packet, README prize mapping, demo video, and social post.
|
| 12 |
|
| 13 |
## Secrets Needed
|
| 14 |
|
| 15 |
Do not paste these into chat, commits, logs, or export packets.
|
| 16 |
|
| 17 |
+
- `HF_TOKEN`: optional for public FLUX.2 Klein 4B access and required only if private/gated research lanes are enabled.
|
|
|
|
| 18 |
- `MINICPM_BASE_URL`: OpenBMB OpenAI-compatible endpoint base URL.
|
| 19 |
- `MINICPM_API_KEY`: OpenBMB bearer token.
|
| 20 |
- `MINICPM_MODEL`: default `MiniCPM-V-4.6`.
|
| 21 |
- `NEMOTRON_BASE_URL`: OpenAI-compatible Nemotron endpoint if available.
|
| 22 |
- `NEMOTRON_API_KEY` or `NVIDIA_API_KEY`: Nemotron provider token.
|
| 23 |
- `NEMOTRON_MODEL`: default `nvidia/NVIDIA-Nemotron-Parse-v1.2`.
|
|
|
|
| 24 |
|
| 25 |
## Verification Commands
|
| 26 |
|
|
|
|
| 29 |
$env:NEXUS_DISABLE_REAL_HF='1'
|
| 30 |
python -c "import app; print('app import ok')"
|
| 31 |
$env:PYTEST_DISABLE_PLUGIN_AUTOLOAD='1'
|
| 32 |
+
python -m pytest -q tests -p no:cacheprovider
|
| 33 |
hf auth whoami --format json
|
| 34 |
hf spaces info build-small-hackathon/NEXUS_Visual_Weaver --format json
|
| 35 |
```
|
| 36 |
|
| 37 |
+
Avoid pytest `--basetemp=C:\tmp` in this Windows sandbox if `tmp_path` fixtures fail with `PermissionError`. The current tests avoid `tmp_path`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
## Runtime Flow
|
| 40 |
|
| 41 |
+
1. `run_active_weave` builds the Raven Chronicle run packet.
|
| 42 |
+
2. FLUX.2 Klein 4B generates the image on Space when HF runtime is enabled.
|
| 43 |
3. Generated artifact is scanned by ST3GG.
|
| 44 |
4. MiniCPM-V judge runs when OpenBMB secrets are present.
|
| 45 |
5. Nemotron evidence runs when Nemotron/NVIDIA endpoint secrets are present.
|
| 46 |
+
6. `approve_checkpoint` requires a generated artifact and ST3GG clear/pass state.
|
| 47 |
+
7. `prepare_export_packet` writes a governed JSON packet to `/data/nexus_visual_weaver/exports` or `outputs/exports`.
|
|
|
|
| 48 |
|
| 49 |
## Claim Rules
|
| 50 |
|
| 51 |
- OpenBMB prize claim requires `minicpm_judge.status == "success"` in an export packet.
|
| 52 |
- NVIDIA prize claim requires `nemotron_evidence.status == "success"` in an export packet.
|
| 53 |
- LocateAnything supports the grounding story but does not replace Nemotron for the NVIDIA prize.
|
| 54 |
+
- Tiny Titan can be claimed only from a successful public-demo export packet because each active public model is <=4B.
|
| 55 |
+
- FLUX.2 Klein 9B and OFFELLIA/Gemma remain private research options only.
|
| 56 |
+
- Modal is not claimed unless a real Modal job runs and is documented.
|
| 57 |
|
| 58 |
## Known Risks
|
| 59 |
|
| 60 |
- GitHub CLI may fail behind proxy `127.0.0.1:9`; use local git status and HF verification when blocked.
|
| 61 |
+
- Real FLUX generation depends on Space GPU availability and the public 4B runtime loading successfully.
|
| 62 |
- OpenBMB and Nemotron endpoints are optional and must show `missing secret` rather than fake success when not configured.
|
| 63 |
- Demo video and social post links must be added before final submission.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
## Last-Step Checklist
|
| 66 |
|
src/nexus_visual_weaver/catalog.py
CHANGED
|
@@ -10,7 +10,7 @@ MODEL_CATALOG: list[ModelCandidate] = [
|
|
| 10 |
role="tiny_titan_sidecar_image_generator",
|
| 11 |
task="image-to-image",
|
| 12 |
params_b=4.0,
|
| 13 |
-
runtime="diffusers /
|
| 14 |
license="apache-2.0",
|
| 15 |
source_url="https://hf.co/black-forest-labs/FLUX.2-klein-4B",
|
| 16 |
),
|
|
@@ -19,18 +19,19 @@ MODEL_CATALOG: list[ModelCandidate] = [
|
|
| 19 |
role="quality_image_generator",
|
| 20 |
task="image-to-image",
|
| 21 |
params_b=9.0,
|
| 22 |
-
runtime="diffusers / gated
|
| 23 |
license="other",
|
| 24 |
gated=True,
|
| 25 |
source_url="https://hf.co/black-forest-labs/FLUX.2-klein-9B",
|
| 26 |
),
|
| 27 |
ModelCandidate(
|
| 28 |
repo_id="Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 29 |
-
role="
|
| 30 |
task="image-text-to-text",
|
| 31 |
params_b=12.0,
|
| 32 |
runtime="llama.cpp GGUF",
|
| 33 |
license="apache-2.0",
|
|
|
|
| 34 |
source_url="https://hf.co/Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 35 |
),
|
| 36 |
ModelCandidate(
|
|
@@ -80,7 +81,7 @@ MODEL_CATALOG: list[ModelCandidate] = [
|
|
| 80 |
),
|
| 81 |
ModelCandidate(
|
| 82 |
repo_id="Brunobkr/OFFELLIA_IQ4_XS_gemma-4-12B-it-heretic",
|
| 83 |
-
role="
|
| 84 |
task="text-generation",
|
| 85 |
params_b=12.0,
|
| 86 |
runtime="llama.cpp GGUF",
|
|
@@ -88,34 +89,6 @@ MODEL_CATALOG: list[ModelCandidate] = [
|
|
| 88 |
adult_only=True,
|
| 89 |
source_url="https://hf.co/Brunobkr/OFFELLIA_IQ4_XS_gemma-4-12B-it-heretic",
|
| 90 |
),
|
| 91 |
-
ModelCandidate(
|
| 92 |
-
repo_id="hexgrad/Kokoro-82M",
|
| 93 |
-
role="audio_lore_tts",
|
| 94 |
-
task="text-to-speech",
|
| 95 |
-
params_b=0.082,
|
| 96 |
-
runtime="local / provider",
|
| 97 |
-
license="apache-2.0",
|
| 98 |
-
source_url="https://hf.co/hexgrad/Kokoro-82M",
|
| 99 |
-
),
|
| 100 |
-
ModelCandidate(
|
| 101 |
-
repo_id="ResembleAI/chatterbox",
|
| 102 |
-
role="audio_lore_tts_optional",
|
| 103 |
-
task="text-to-speech",
|
| 104 |
-
params_b=0.5,
|
| 105 |
-
runtime="provider / Modal",
|
| 106 |
-
license="mit",
|
| 107 |
-
source_url="https://hf.co/ResembleAI/chatterbox",
|
| 108 |
-
),
|
| 109 |
-
ModelCandidate(
|
| 110 |
-
repo_id="netflix/void-model",
|
| 111 |
-
role="modal_video_repair",
|
| 112 |
-
task="video-to-video",
|
| 113 |
-
params_b=5.0,
|
| 114 |
-
runtime="Modal / 40GB+ VRAM",
|
| 115 |
-
license="apache-2.0",
|
| 116 |
-
public_demo=False,
|
| 117 |
-
source_url="https://hf.co/netflix/void-model",
|
| 118 |
-
),
|
| 119 |
ModelCandidate(
|
| 120 |
repo_id="Wan-AI/Wan2.2-I2V-A14B-Diffusers",
|
| 121 |
role="video_swap_preset",
|
|
@@ -139,27 +112,43 @@ MODEL_CATALOG: list[ModelCandidate] = [
|
|
| 139 |
ADAPTER_CATALOG: list[AdapterRecipe] = [
|
| 140 |
AdapterRecipe(
|
| 141 |
repo_id="DeverStyle/Flux.2-Klein-Loras",
|
| 142 |
-
adapter_for="black-forest-labs/FLUX.2-klein-
|
| 143 |
task="text-to-image style stack",
|
| 144 |
license="apache-2.0",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
),
|
| 146 |
AdapterRecipe(
|
| 147 |
repo_id="fal/flux-2-klein-4B-outpaint-lora",
|
| 148 |
adapter_for="black-forest-labs/FLUX.2-klein-4B",
|
| 149 |
task="outpaint/inpaint public demo helper",
|
| 150 |
license="apache-2.0",
|
|
|
|
|
|
|
| 151 |
),
|
| 152 |
AdapterRecipe(
|
| 153 |
repo_id="thedeoxen/refcontrol-FLUX.2-klein-4B-reference-depth-lora",
|
| 154 |
adapter_for="black-forest-labs/FLUX.2-klein-base-4B",
|
| 155 |
task="reference-depth control for garment layout",
|
| 156 |
license="apache-2.0",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
),
|
| 158 |
AdapterRecipe(
|
| 159 |
repo_id="nomadoor/flux-2-klein-9B-schematic-lora",
|
| 160 |
adapter_for="black-forest-labs/FLUX.2-klein-base-9B",
|
| 161 |
task="pose/depth/segmentation schematic control",
|
| 162 |
license="other",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
),
|
| 164 |
AdapterRecipe(
|
| 165 |
repo_id="fal/Qwen-Image-Edit-2511-Multiple-Angles-LoRA",
|
|
@@ -195,30 +184,24 @@ ADAPTER_CATALOG: list[AdapterRecipe] = [
|
|
| 195 |
),
|
| 196 |
]
|
| 197 |
|
| 198 |
-
|
| 199 |
"black-forest-labs/FLUX.2-klein-9B",
|
| 200 |
-
"Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 201 |
"nvidia/LocateAnything-3B",
|
| 202 |
"openbmb/MiniCPM-V-4.6",
|
| 203 |
"nvidia/NVIDIA-Nemotron-Parse-v1.2",
|
| 204 |
"openbmb/MiniCPM5-1B",
|
| 205 |
"onnx-community/functiongemma-270m-it-ONNX",
|
| 206 |
-
"hexgrad/Kokoro-82M",
|
| 207 |
]
|
| 208 |
|
| 209 |
-
|
| 210 |
-
"black-forest-labs/FLUX.2-klein-
|
|
|
|
| 211 |
"nvidia/LocateAnything-3B",
|
| 212 |
"openbmb/MiniCPM-V-4.6",
|
| 213 |
"nvidia/NVIDIA-Nemotron-Parse-v1.2",
|
| 214 |
"openbmb/MiniCPM5-1B",
|
| 215 |
-
"onnx-community/functiongemma-270m-it-ONNX",
|
| 216 |
-
"hexgrad/Kokoro-82M",
|
| 217 |
]
|
| 218 |
|
| 219 |
-
DEFAULT_ACTIVE_STACK = RAVEN_QUALITY_STACK
|
| 220 |
-
PRIVATE_RESEARCH_STACK = RAVEN_QUALITY_STACK
|
| 221 |
-
|
| 222 |
|
| 223 |
def filter_catalog(adult_mode: bool = False) -> tuple[list[ModelCandidate], list[AdapterRecipe]]:
|
| 224 |
models = [
|
|
@@ -233,12 +216,8 @@ def filter_catalog(adult_mode: bool = False) -> tuple[list[ModelCandidate], list
|
|
| 233 |
def active_stack(adult_mode: bool = False) -> list[ModelCandidate]:
|
| 234 |
allowed, _ = filter_catalog(adult_mode)
|
| 235 |
by_id = {model.repo_id: model for model in allowed}
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
def tiny_titan_stack() -> list[ModelCandidate]:
|
| 240 |
-
by_id = {model.repo_id: model for model in MODEL_CATALOG}
|
| 241 |
-
return [by_id[repo_id] for repo_id in TINY_TITAN_STACK if repo_id in by_id]
|
| 242 |
|
| 243 |
|
| 244 |
def parameter_budget(stack: list[ModelCandidate] | None = None) -> dict[str, float | str]:
|
|
@@ -259,7 +238,5 @@ def catalog_summary(adult_mode: bool = False) -> dict[str, int | float | str]:
|
|
| 259 |
"models_visible": len(models),
|
| 260 |
"adapters_visible": len(adapters),
|
| 261 |
"adult_catalog": "enabled" if adult_mode else "hidden",
|
| 262 |
-
"active_preset": "Raven Quality Stack",
|
| 263 |
-
"tiny_titan": "sidecar",
|
| 264 |
**budget,
|
| 265 |
}
|
|
|
|
| 10 |
role="tiny_titan_sidecar_image_generator",
|
| 11 |
task="image-to-image",
|
| 12 |
params_b=4.0,
|
| 13 |
+
runtime="diffusers / provider",
|
| 14 |
license="apache-2.0",
|
| 15 |
source_url="https://hf.co/black-forest-labs/FLUX.2-klein-4B",
|
| 16 |
),
|
|
|
|
| 19 |
role="quality_image_generator",
|
| 20 |
task="image-to-image",
|
| 21 |
params_b=9.0,
|
| 22 |
+
runtime="diffusers / gated provider",
|
| 23 |
license="other",
|
| 24 |
gated=True,
|
| 25 |
source_url="https://hf.co/black-forest-labs/FLUX.2-klein-9B",
|
| 26 |
),
|
| 27 |
ModelCandidate(
|
| 28 |
repo_id="Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 29 |
+
role="private_research_multimodal_judge",
|
| 30 |
task="image-text-to-text",
|
| 31 |
params_b=12.0,
|
| 32 |
runtime="llama.cpp GGUF",
|
| 33 |
license="apache-2.0",
|
| 34 |
+
public_demo=False,
|
| 35 |
source_url="https://hf.co/Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 36 |
),
|
| 37 |
ModelCandidate(
|
|
|
|
| 81 |
),
|
| 82 |
ModelCandidate(
|
| 83 |
repo_id="Brunobkr/OFFELLIA_IQ4_XS_gemma-4-12B-it-heretic",
|
| 84 |
+
role="adult_mode_text_judge",
|
| 85 |
task="text-generation",
|
| 86 |
params_b=12.0,
|
| 87 |
runtime="llama.cpp GGUF",
|
|
|
|
| 89 |
adult_only=True,
|
| 90 |
source_url="https://hf.co/Brunobkr/OFFELLIA_IQ4_XS_gemma-4-12B-it-heretic",
|
| 91 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
ModelCandidate(
|
| 93 |
repo_id="Wan-AI/Wan2.2-I2V-A14B-Diffusers",
|
| 94 |
role="video_swap_preset",
|
|
|
|
| 112 |
ADAPTER_CATALOG: list[AdapterRecipe] = [
|
| 113 |
AdapterRecipe(
|
| 114 |
repo_id="DeverStyle/Flux.2-Klein-Loras",
|
| 115 |
+
adapter_for="black-forest-labs/FLUX.2-klein-9B",
|
| 116 |
task="text-to-image style stack",
|
| 117 |
license="apache-2.0",
|
| 118 |
+
trigger_words=["gothic couture", "structured garment"],
|
| 119 |
+
compatible_repo_ids=[
|
| 120 |
+
"black-forest-labs/FLUX.2-klein-9B",
|
| 121 |
+
"black-forest-labs/FLUX.2-klein-4B",
|
| 122 |
+
],
|
| 123 |
),
|
| 124 |
AdapterRecipe(
|
| 125 |
repo_id="fal/flux-2-klein-4B-outpaint-lora",
|
| 126 |
adapter_for="black-forest-labs/FLUX.2-klein-4B",
|
| 127 |
task="outpaint/inpaint public demo helper",
|
| 128 |
license="apache-2.0",
|
| 129 |
+
compatible_repo_ids=["black-forest-labs/FLUX.2-klein-4B"],
|
| 130 |
+
requires_image=True,
|
| 131 |
),
|
| 132 |
AdapterRecipe(
|
| 133 |
repo_id="thedeoxen/refcontrol-FLUX.2-klein-4B-reference-depth-lora",
|
| 134 |
adapter_for="black-forest-labs/FLUX.2-klein-base-4B",
|
| 135 |
task="reference-depth control for garment layout",
|
| 136 |
license="apache-2.0",
|
| 137 |
+
compatible_repo_ids=[
|
| 138 |
+
"black-forest-labs/FLUX.2-klein-base-4B",
|
| 139 |
+
"black-forest-labs/FLUX.2-klein-4B",
|
| 140 |
+
],
|
| 141 |
+
requires_image=True,
|
| 142 |
),
|
| 143 |
AdapterRecipe(
|
| 144 |
repo_id="nomadoor/flux-2-klein-9B-schematic-lora",
|
| 145 |
adapter_for="black-forest-labs/FLUX.2-klein-base-9B",
|
| 146 |
task="pose/depth/segmentation schematic control",
|
| 147 |
license="other",
|
| 148 |
+
compatible_repo_ids=[
|
| 149 |
+
"black-forest-labs/FLUX.2-klein-base-9B",
|
| 150 |
+
"black-forest-labs/FLUX.2-klein-9B",
|
| 151 |
+
],
|
| 152 |
),
|
| 153 |
AdapterRecipe(
|
| 154 |
repo_id="fal/Qwen-Image-Edit-2511-Multiple-Angles-LoRA",
|
|
|
|
| 184 |
),
|
| 185 |
]
|
| 186 |
|
| 187 |
+
DEFAULT_ACTIVE_STACK = [
|
| 188 |
"black-forest-labs/FLUX.2-klein-9B",
|
|
|
|
| 189 |
"nvidia/LocateAnything-3B",
|
| 190 |
"openbmb/MiniCPM-V-4.6",
|
| 191 |
"nvidia/NVIDIA-Nemotron-Parse-v1.2",
|
| 192 |
"openbmb/MiniCPM5-1B",
|
| 193 |
"onnx-community/functiongemma-270m-it-ONNX",
|
|
|
|
| 194 |
]
|
| 195 |
|
| 196 |
+
PRIVATE_RESEARCH_STACK = [
|
| 197 |
+
"black-forest-labs/FLUX.2-klein-9B",
|
| 198 |
+
"Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 199 |
"nvidia/LocateAnything-3B",
|
| 200 |
"openbmb/MiniCPM-V-4.6",
|
| 201 |
"nvidia/NVIDIA-Nemotron-Parse-v1.2",
|
| 202 |
"openbmb/MiniCPM5-1B",
|
|
|
|
|
|
|
| 203 |
]
|
| 204 |
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
def filter_catalog(adult_mode: bool = False) -> tuple[list[ModelCandidate], list[AdapterRecipe]]:
|
| 207 |
models = [
|
|
|
|
| 216 |
def active_stack(adult_mode: bool = False) -> list[ModelCandidate]:
|
| 217 |
allowed, _ = filter_catalog(adult_mode)
|
| 218 |
by_id = {model.repo_id: model for model in allowed}
|
| 219 |
+
stack_ids = PRIVATE_RESEARCH_STACK if adult_mode else DEFAULT_ACTIVE_STACK
|
| 220 |
+
return [by_id[repo_id] for repo_id in stack_ids if repo_id in by_id]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
|
| 222 |
|
| 223 |
def parameter_budget(stack: list[ModelCandidate] | None = None) -> dict[str, float | str]:
|
|
|
|
| 238 |
"models_visible": len(models),
|
| 239 |
"adapters_visible": len(adapters),
|
| 240 |
"adult_catalog": "enabled" if adult_mode else "hidden",
|
|
|
|
|
|
|
| 241 |
**budget,
|
| 242 |
}
|
src/nexus_visual_weaver/exporter.py
CHANGED
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
| 4 |
|
| 5 |
import json
|
| 6 |
import os
|
|
|
|
| 7 |
import time
|
| 8 |
from pathlib import Path
|
| 9 |
from typing import Any
|
|
@@ -48,6 +49,95 @@ def _artifact_name(output_path: Any) -> str | None:
|
|
| 48 |
return Path(str(output_path)).name
|
| 49 |
|
| 50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
def export_root() -> Path:
|
| 52 |
requested = os.environ.get("NEXUS_EXPORT_DIR")
|
| 53 |
candidates = [Path(requested)] if requested else []
|
|
@@ -84,49 +174,51 @@ def write_export_packet(
|
|
| 84 |
artifact = _artifact_name(generation.get("output_path"))
|
| 85 |
if "output_path" in generation:
|
| 86 |
generation["output_path"] = artifact
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
}
|
| 92 |
-
audio_lore = operator_state.get("audio_lore_tts") or {
|
| 93 |
-
"status": "optional",
|
| 94 |
-
"repo_id": "hexgrad/Kokoro-82M",
|
| 95 |
-
}
|
| 96 |
-
offellia = operator_state.get("offellia_judge") or {
|
| 97 |
-
"status": "deferred_local",
|
| 98 |
-
"repo_id": "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 99 |
-
}
|
| 100 |
-
tiny_titan = operator_state.get("tiny_titan_sidecar") or {
|
| 101 |
-
"status": "available",
|
| 102 |
-
"repo_id": "black-forest-labs/FLUX.2-klein-4B",
|
| 103 |
-
}
|
| 104 |
-
locate_grounding = operator_state.get("locateanything_grounding") or {}
|
| 105 |
-
st3gg_override_reason = str(operator_state.get("st3gg_override_reason", "")).strip()
|
| 106 |
packet = {
|
| 107 |
"schema": "nexus_visual_weaver.export_packet.v1",
|
| 108 |
"run_id": run_id,
|
| 109 |
"created_at_epoch": int(time.time()),
|
| 110 |
-
"active_preset": operator_state.get("active_preset", "Raven Quality Stack"),
|
| 111 |
"adult_mode": run_adult_mode,
|
| 112 |
"prompt": getattr(getattr(run, "request", None), "prompt", ""),
|
| 113 |
"refined_prompt": getattr(getattr(run, "refined_prompt", None), "refined", ""),
|
| 114 |
"artifact": artifact,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
"generation": generation,
|
| 116 |
-
"
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
"
|
| 121 |
-
"
|
| 122 |
-
"
|
| 123 |
-
"audio_lore_tts": audio_lore,
|
| 124 |
-
"tiny_titan_sidecar": tiny_titan,
|
| 125 |
"checkpoint": {
|
| 126 |
"status": operator_state.get("checkpoint"),
|
| 127 |
"message": operator_state.get("message"),
|
|
|
|
|
|
|
|
|
|
| 128 |
},
|
| 129 |
"provider_state": operator_state.get("provider_state"),
|
|
|
|
| 130 |
"model_stack": [
|
| 131 |
{
|
| 132 |
"repo_id": model.repo_id,
|
|
@@ -142,15 +234,9 @@ def write_export_packet(
|
|
| 142 |
"build_small_32b": budget["status"] == "pass",
|
| 143 |
"gradio_space": True,
|
| 144 |
"off_brand_custom_ui": True,
|
| 145 |
-
"openbmb_lane":
|
| 146 |
-
"nvidia_nemotron_lane":
|
| 147 |
-
"
|
| 148 |
-
"modal_void_lane": modal_job.get("status") in {"success", "completed", "documented"},
|
| 149 |
-
"tiny_titan_sidecar": tiny_titan.get("status") in {"success", "available", "sidecar"},
|
| 150 |
-
"raven_quality_stack": True,
|
| 151 |
-
"locateanything_grounding": bool(locate_grounding.get("targets") or locate_grounding.get("repo_id")),
|
| 152 |
-
"st3gg_override_recorded": bool(st3gg_override_reason),
|
| 153 |
-
"st3gg_export_gate": scan.get("export_gate"),
|
| 154 |
},
|
| 155 |
}
|
| 156 |
target = export_root() / f"{run_id}.json"
|
|
|
|
| 4 |
|
| 5 |
import json
|
| 6 |
import os
|
| 7 |
+
import re
|
| 8 |
import time
|
| 9 |
from pathlib import Path
|
| 10 |
from typing import Any
|
|
|
|
| 49 |
return Path(str(output_path)).name
|
| 50 |
|
| 51 |
|
| 52 |
+
SENSITIVE_KEY_RE = re.compile(r"(token|secret|api[_-]?key|authorization|payload_excerpt|raw|base64|bytes)", re.IGNORECASE)
|
| 53 |
+
SECRET_VALUE_RE = re.compile(r"(hf_[A-Za-z0-9]{20,}|Bearer [A-Za-z0-9._-]+|sk-[A-Za-z0-9_-]{20,})")
|
| 54 |
+
CREDENTIAL_NAME_RE = re.compile(r"\b[A-Z0-9_]*(?:API_KEY|TOKEN|SECRET)[A-Z0-9_]*\b")
|
| 55 |
+
WINDOWS_PATH_RE = re.compile(r"[A-Za-z]:[\\/][^\s\"']+")
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def _sanitize_text(value: str) -> str:
|
| 59 |
+
text = SECRET_VALUE_RE.sub("[redacted_secret]", value)
|
| 60 |
+
text = CREDENTIAL_NAME_RE.sub("[redacted_credential_name]", text)
|
| 61 |
+
text = WINDOWS_PATH_RE.sub(lambda match: f"[local_path]/{Path(match.group(0)).name}", text)
|
| 62 |
+
repo_text = str(REPO_ROOT)
|
| 63 |
+
if repo_text in text:
|
| 64 |
+
text = text.replace(repo_text, "[repo]")
|
| 65 |
+
if "/data/" in text:
|
| 66 |
+
text = text.replace("/data/", "[data]/")
|
| 67 |
+
if len(text) > 1000:
|
| 68 |
+
text = text[:997] + "..."
|
| 69 |
+
return text
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def _safe_dict(value: Any, *, allow_size_bytes: bool = False) -> Any:
|
| 73 |
+
if isinstance(value, dict):
|
| 74 |
+
clean: dict[str, Any] = {}
|
| 75 |
+
for key, item in value.items():
|
| 76 |
+
key_str = str(key)
|
| 77 |
+
if SENSITIVE_KEY_RE.search(key_str) and not (allow_size_bytes and key_str == "size_bytes"):
|
| 78 |
+
continue
|
| 79 |
+
clean[key_str] = _safe_dict(item, allow_size_bytes=allow_size_bytes)
|
| 80 |
+
return clean
|
| 81 |
+
if isinstance(value, list):
|
| 82 |
+
return [_safe_dict(item, allow_size_bytes=allow_size_bytes) for item in value[:40]]
|
| 83 |
+
if isinstance(value, str):
|
| 84 |
+
return _sanitize_text(value)
|
| 85 |
+
return value
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def _safe_scan(scan: dict[str, Any]) -> dict[str, Any]:
|
| 89 |
+
return {
|
| 90 |
+
"status": scan.get("status"),
|
| 91 |
+
"scanner": scan.get("scanner"),
|
| 92 |
+
"export_gate": scan.get("export_gate"),
|
| 93 |
+
"extension": scan.get("extension"),
|
| 94 |
+
"magic": scan.get("magic"),
|
| 95 |
+
"findings": _safe_dict(scan.get("findings") or []),
|
| 96 |
+
"purification_actions": _safe_dict(scan.get("purification_actions") or []),
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
def _safe_provider(provider: dict[str, Any] | None) -> dict[str, Any]:
|
| 101 |
+
provider = provider or {}
|
| 102 |
+
evidence = provider.get("evidence") if isinstance(provider.get("evidence"), dict) else {}
|
| 103 |
+
return {
|
| 104 |
+
"status": provider.get("status"),
|
| 105 |
+
"provider_state": provider.get("provider_state"),
|
| 106 |
+
"provider": provider.get("provider"),
|
| 107 |
+
"repo_id": provider.get("repo_id"),
|
| 108 |
+
"model": provider.get("model"),
|
| 109 |
+
"message": _safe_dict(provider.get("message", "")),
|
| 110 |
+
"evidence": _safe_dict(evidence),
|
| 111 |
+
"latency_seconds": provider.get("latency_seconds"),
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def _safe_reference_metadata(records: Any) -> list[dict[str, Any]]:
|
| 116 |
+
if not isinstance(records, list):
|
| 117 |
+
return []
|
| 118 |
+
cleaned: list[dict[str, Any]] = []
|
| 119 |
+
for record in records[:20]:
|
| 120 |
+
if not isinstance(record, dict):
|
| 121 |
+
continue
|
| 122 |
+
cleaned.append(
|
| 123 |
+
{
|
| 124 |
+
"source": record.get("source"),
|
| 125 |
+
"status": record.get("status"),
|
| 126 |
+
"basename": _artifact_name(record.get("basename")) if record.get("basename") else None,
|
| 127 |
+
"sha256": record.get("sha256"),
|
| 128 |
+
"size_bytes": record.get("size_bytes"),
|
| 129 |
+
"st3gg_status": record.get("st3gg_status"),
|
| 130 |
+
"export_gate": record.get("export_gate"),
|
| 131 |
+
"magic": record.get("magic"),
|
| 132 |
+
"extension": record.get("extension"),
|
| 133 |
+
"domain": record.get("domain"),
|
| 134 |
+
"url_hash": record.get("url_hash"),
|
| 135 |
+
"message": _safe_dict(record.get("message", "")),
|
| 136 |
+
}
|
| 137 |
+
)
|
| 138 |
+
return cleaned
|
| 139 |
+
|
| 140 |
+
|
| 141 |
def export_root() -> Path:
|
| 142 |
requested = os.environ.get("NEXUS_EXPORT_DIR")
|
| 143 |
candidates = [Path(requested)] if requested else []
|
|
|
|
| 174 |
artifact = _artifact_name(generation.get("output_path"))
|
| 175 |
if "output_path" in generation:
|
| 176 |
generation["output_path"] = artifact
|
| 177 |
+
generation = _safe_dict(generation)
|
| 178 |
+
creator_controls = _safe_dict(operator_state.get("creator_controls") or getattr(getattr(run, "request", None), "creator_controls", {}) or {})
|
| 179 |
+
reference_metadata = _safe_reference_metadata(operator_state.get("reference_metadata") or getattr(getattr(run, "request", None), "reference_metadata", []) or [])
|
| 180 |
+
st3gg_scan = _safe_scan(scan)
|
| 181 |
+
minicpm_judge = _safe_provider(operator_state.get("minicpm_judge") or {})
|
| 182 |
+
nemotron_evidence = _safe_provider(operator_state.get("nemotron_evidence") or {})
|
| 183 |
+
provider_states = {
|
| 184 |
+
"generation": generation.get("provider_state"),
|
| 185 |
+
"minicpm": minicpm_judge.get("status"),
|
| 186 |
+
"nemotron": nemotron_evidence.get("status"),
|
| 187 |
+
"operator": operator_state.get("provider_state"),
|
| 188 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
packet = {
|
| 190 |
"schema": "nexus_visual_weaver.export_packet.v1",
|
| 191 |
"run_id": run_id,
|
| 192 |
"created_at_epoch": int(time.time()),
|
|
|
|
| 193 |
"adult_mode": run_adult_mode,
|
| 194 |
"prompt": getattr(getattr(run, "request", None), "prompt", ""),
|
| 195 |
"refined_prompt": getattr(getattr(run, "refined_prompt", None), "refined", ""),
|
| 196 |
"artifact": artifact,
|
| 197 |
+
"image_basename": artifact,
|
| 198 |
+
"creator_controls": creator_controls,
|
| 199 |
+
"reference_metadata": reference_metadata,
|
| 200 |
+
"lora_status": {
|
| 201 |
+
"status": generation.get("lora_status"),
|
| 202 |
+
"repo_id": generation.get("lora_repo_id"),
|
| 203 |
+
"message": generation.get("lora_message"),
|
| 204 |
+
},
|
| 205 |
"generation": generation,
|
| 206 |
+
"st3gg_verdict": {
|
| 207 |
+
"status": st3gg_scan.get("status"),
|
| 208 |
+
"export_gate": st3gg_scan.get("export_gate"),
|
| 209 |
+
},
|
| 210 |
+
"st3gg_scan": st3gg_scan,
|
| 211 |
+
"minicpm_judge": minicpm_judge,
|
| 212 |
+
"nemotron_evidence": nemotron_evidence,
|
|
|
|
|
|
|
| 213 |
"checkpoint": {
|
| 214 |
"status": operator_state.get("checkpoint"),
|
| 215 |
"message": operator_state.get("message"),
|
| 216 |
+
"recommendation": getattr(getattr(run, "checkpoint", None), "recommendation", None),
|
| 217 |
+
"trust_score": getattr(getattr(run, "checkpoint", None), "trust_score", None),
|
| 218 |
+
"required_actions": getattr(getattr(run, "checkpoint", None), "required_actions", []),
|
| 219 |
},
|
| 220 |
"provider_state": operator_state.get("provider_state"),
|
| 221 |
+
"provider_states": provider_states,
|
| 222 |
"model_stack": [
|
| 223 |
{
|
| 224 |
"repo_id": model.repo_id,
|
|
|
|
| 234 |
"build_small_32b": budget["status"] == "pass",
|
| 235 |
"gradio_space": True,
|
| 236 |
"off_brand_custom_ui": True,
|
| 237 |
+
"openbmb_lane": minicpm_judge.get("status") == "success",
|
| 238 |
+
"nvidia_nemotron_lane": nemotron_evidence.get("status") == "success",
|
| 239 |
+
"st3gg_export_gate": st3gg_scan.get("export_gate"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
},
|
| 241 |
}
|
| 242 |
target = export_root() / f"{run_id}.json"
|
src/nexus_visual_weaver/hf_runtime.py
CHANGED
|
@@ -3,15 +3,22 @@
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
import os
|
|
|
|
| 6 |
import time
|
| 7 |
from dataclasses import dataclass, asdict
|
| 8 |
from pathlib import Path
|
| 9 |
from typing import Any
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
FLUX_REPO_ID = "black-forest-labs/FLUX.2-klein-9B"
|
| 13 |
TINY_TITAN_FLUX_REPO_ID = "black-forest-labs/FLUX.2-klein-4B"
|
| 14 |
PRIVATE_RESEARCH_FLUX_REPO_ID = FLUX_REPO_ID
|
|
|
|
|
|
|
| 15 |
|
| 16 |
|
| 17 |
@dataclass(frozen=True)
|
|
@@ -26,6 +33,11 @@ class HFGenerationResult:
|
|
| 26 |
height: int = 1024
|
| 27 |
steps: int = 4
|
| 28 |
hf_token_present: bool = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
|
| 30 |
def to_dict(self) -> dict[str, Any]:
|
| 31 |
return asdict(self)
|
|
@@ -75,8 +87,51 @@ def active_flux_repo_id() -> str:
|
|
| 75 |
return FLUX_REPO_ID
|
| 76 |
|
| 77 |
|
| 78 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
repo_id = active_flux_repo_id()
|
|
|
|
|
|
|
| 80 |
if not hf_runtime_enabled():
|
| 81 |
return HFGenerationResult(
|
| 82 |
status="disabled",
|
|
@@ -87,6 +142,9 @@ def generate_flux_image(prompt: str, *, seed: int = 0, width: int = 1024, height
|
|
| 87 |
height=height,
|
| 88 |
steps=steps,
|
| 89 |
hf_token_present=bool(_hf_token()),
|
|
|
|
|
|
|
|
|
|
| 90 |
)
|
| 91 |
|
| 92 |
started = time.perf_counter()
|
|
@@ -103,6 +161,9 @@ def generate_flux_image(prompt: str, *, seed: int = 0, width: int = 1024, height
|
|
| 103 |
height=height,
|
| 104 |
steps=steps,
|
| 105 |
hf_token_present=bool(_hf_token()),
|
|
|
|
|
|
|
|
|
|
| 106 |
)
|
| 107 |
|
| 108 |
if not torch.cuda.is_available():
|
|
@@ -115,49 +176,56 @@ def generate_flux_image(prompt: str, *, seed: int = 0, width: int = 1024, height
|
|
| 115 |
height=height,
|
| 116 |
steps=steps,
|
| 117 |
hf_token_present=bool(_hf_token()),
|
|
|
|
|
|
|
|
|
|
| 118 |
)
|
| 119 |
|
| 120 |
token = _hf_token()
|
| 121 |
-
repo_candidates = [repo_id]
|
| 122 |
-
if repo_id != TINY_TITAN_FLUX_REPO_ID and os.environ.get("NEXUS_DISABLE_TINY_TITAN_FALLBACK") != "1":
|
| 123 |
-
repo_candidates.append(TINY_TITAN_FLUX_REPO_ID)
|
| 124 |
errors: list[str] = []
|
| 125 |
-
for candidate in
|
| 126 |
try:
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
output_path = _output_dir() / f"nexus_flux_{int(time.time())}_{seed}.png"
|
| 140 |
image.save(output_path)
|
| 141 |
-
fallback = candidate != repo_id
|
| 142 |
-
message = (
|
| 143 |
-
f"{candidate} generated a Tiny Titan sidecar artifact after the 9B lane was unavailable."
|
| 144 |
-
if fallback
|
| 145 |
-
else f"{candidate} generated a real Raven Quality artifact on HF Space."
|
| 146 |
-
)
|
| 147 |
return HFGenerationResult(
|
| 148 |
status="success",
|
| 149 |
provider_state="generated",
|
| 150 |
repo_id=candidate,
|
| 151 |
output_path=str(output_path),
|
| 152 |
-
message=
|
| 153 |
latency_seconds=round(time.perf_counter() - started, 2),
|
| 154 |
width=width,
|
| 155 |
height=height,
|
| 156 |
steps=steps,
|
| 157 |
hf_token_present=bool(token),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
)
|
| 159 |
except Exception as exc: # pragma: no cover - exercised on HF Space with gated/runtime conditions.
|
| 160 |
errors.append(f"{candidate}: {_short_error(exc)}")
|
|
|
|
|
|
|
|
|
|
| 161 |
return HFGenerationResult(
|
| 162 |
status="error",
|
| 163 |
provider_state="blocked",
|
|
@@ -167,5 +235,8 @@ def generate_flux_image(prompt: str, *, seed: int = 0, width: int = 1024, height
|
|
| 167 |
width=width,
|
| 168 |
height=height,
|
| 169 |
steps=steps,
|
| 170 |
-
hf_token_present=bool(
|
|
|
|
|
|
|
|
|
|
| 171 |
)
|
|
|
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
import os
|
| 6 |
+
import threading
|
| 7 |
import time
|
| 8 |
from dataclasses import dataclass, asdict
|
| 9 |
from pathlib import Path
|
| 10 |
from typing import Any
|
| 11 |
|
| 12 |
+
from .catalog import ADAPTER_CATALOG
|
| 13 |
+
from .lora_adapter import load_and_apply, unload_all
|
| 14 |
+
from .schema import AdapterRecipe
|
| 15 |
+
|
| 16 |
|
| 17 |
FLUX_REPO_ID = "black-forest-labs/FLUX.2-klein-9B"
|
| 18 |
TINY_TITAN_FLUX_REPO_ID = "black-forest-labs/FLUX.2-klein-4B"
|
| 19 |
PRIVATE_RESEARCH_FLUX_REPO_ID = FLUX_REPO_ID
|
| 20 |
+
_PIPELINE_CACHE: dict[str, Any] = {}
|
| 21 |
+
_PIPELINE_CACHE_LOCK = threading.Lock()
|
| 22 |
|
| 23 |
|
| 24 |
@dataclass(frozen=True)
|
|
|
|
| 33 |
height: int = 1024
|
| 34 |
steps: int = 4
|
| 35 |
hf_token_present: bool = False
|
| 36 |
+
lora_status: str = "disabled"
|
| 37 |
+
lora_repo_id: str | None = None
|
| 38 |
+
lora_message: str = "No LoRA adapter selected for this run."
|
| 39 |
+
fallback_used: bool = False
|
| 40 |
+
primary_error: str | None = None
|
| 41 |
|
| 42 |
def to_dict(self) -> dict[str, Any]:
|
| 43 |
return asdict(self)
|
|
|
|
| 87 |
return FLUX_REPO_ID
|
| 88 |
|
| 89 |
|
| 90 |
+
def _repo_candidates(repo_id: str) -> list[str]:
|
| 91 |
+
candidates = [repo_id]
|
| 92 |
+
if repo_id != TINY_TITAN_FLUX_REPO_ID and os.environ.get("NEXUS_DISABLE_TINY_TITAN_FALLBACK") != "1":
|
| 93 |
+
candidates.append(TINY_TITAN_FLUX_REPO_ID)
|
| 94 |
+
return candidates
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def _get_flux_pipe(repo_id: str, torch_module: Any, pipeline_cls: Any, token: str | None) -> Any:
|
| 98 |
+
with _PIPELINE_CACHE_LOCK:
|
| 99 |
+
cached = _PIPELINE_CACHE.get(repo_id)
|
| 100 |
+
if cached is not None:
|
| 101 |
+
return cached
|
| 102 |
+
pipe = pipeline_cls.from_pretrained(repo_id, torch_dtype=torch_module.bfloat16, token=token)
|
| 103 |
+
pipe.enable_model_cpu_offload()
|
| 104 |
+
_PIPELINE_CACHE[repo_id] = pipe
|
| 105 |
+
return pipe
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def _adapter_recipe(repo_id: str | None) -> AdapterRecipe | None:
|
| 109 |
+
if not repo_id:
|
| 110 |
+
return None
|
| 111 |
+
return next((recipe for recipe in ADAPTER_CATALOG if recipe.repo_id == repo_id), None)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def default_lora_repo_id(target_repo_id: str) -> str | None:
|
| 115 |
+
for recipe in ADAPTER_CATALOG:
|
| 116 |
+
compatible_ids = {recipe.adapter_for, *recipe.compatible_repo_ids}
|
| 117 |
+
if recipe.runtime_enabled and not recipe.adult_only and not recipe.requires_image and target_repo_id in compatible_ids:
|
| 118 |
+
return recipe.repo_id
|
| 119 |
+
return None
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def generate_flux_image(
|
| 123 |
+
prompt: str,
|
| 124 |
+
*,
|
| 125 |
+
seed: int = 0,
|
| 126 |
+
width: int = 1024,
|
| 127 |
+
height: int = 1024,
|
| 128 |
+
steps: int = 4,
|
| 129 |
+
lora_repo_id: str | None = None,
|
| 130 |
+
adult_mode: bool = False,
|
| 131 |
+
) -> HFGenerationResult:
|
| 132 |
repo_id = active_flux_repo_id()
|
| 133 |
+
selected_lora = lora_repo_id if lora_repo_id is not None else default_lora_repo_id(repo_id)
|
| 134 |
+
recipe = _adapter_recipe(selected_lora)
|
| 135 |
if not hf_runtime_enabled():
|
| 136 |
return HFGenerationResult(
|
| 137 |
status="disabled",
|
|
|
|
| 142 |
height=height,
|
| 143 |
steps=steps,
|
| 144 |
hf_token_present=bool(_hf_token()),
|
| 145 |
+
lora_status="disabled",
|
| 146 |
+
lora_repo_id=recipe.repo_id if recipe else None,
|
| 147 |
+
lora_message="LoRA loading requires the HF Space GPU runtime.",
|
| 148 |
)
|
| 149 |
|
| 150 |
started = time.perf_counter()
|
|
|
|
| 161 |
height=height,
|
| 162 |
steps=steps,
|
| 163 |
hf_token_present=bool(_hf_token()),
|
| 164 |
+
lora_status="disabled",
|
| 165 |
+
lora_repo_id=recipe.repo_id if recipe else None,
|
| 166 |
+
lora_message="FLUX runtime import failed before LoRA loading.",
|
| 167 |
)
|
| 168 |
|
| 169 |
if not torch.cuda.is_available():
|
|
|
|
| 176 |
height=height,
|
| 177 |
steps=steps,
|
| 178 |
hf_token_present=bool(_hf_token()),
|
| 179 |
+
lora_status="disabled",
|
| 180 |
+
lora_repo_id=recipe.repo_id if recipe else None,
|
| 181 |
+
lora_message="CUDA unavailable before LoRA loading.",
|
| 182 |
)
|
| 183 |
|
| 184 |
token = _hf_token()
|
|
|
|
|
|
|
|
|
|
| 185 |
errors: list[str] = []
|
| 186 |
+
for candidate in _repo_candidates(repo_id):
|
| 187 |
try:
|
| 188 |
+
pipe = _get_flux_pipe(candidate, torch, Flux2KleinPipeline, token)
|
| 189 |
+
if hasattr(pipe, "set_progress_bar_config"):
|
| 190 |
+
pipe.set_progress_bar_config(disable=True)
|
| 191 |
+
lora_result = load_and_apply(pipe, recipe, candidate, adult_mode=adult_mode)
|
| 192 |
+
|
| 193 |
+
try:
|
| 194 |
+
generator = torch.Generator(device="cuda").manual_seed(seed)
|
| 195 |
+
image = pipe(
|
| 196 |
+
prompt=prompt,
|
| 197 |
+
height=height,
|
| 198 |
+
width=width,
|
| 199 |
+
guidance_scale=1.0,
|
| 200 |
+
num_inference_steps=steps,
|
| 201 |
+
generator=generator,
|
| 202 |
+
).images[0]
|
| 203 |
+
finally:
|
| 204 |
+
unload_all(pipe)
|
| 205 |
output_path = _output_dir() / f"nexus_flux_{int(time.time())}_{seed}.png"
|
| 206 |
image.save(output_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
return HFGenerationResult(
|
| 208 |
status="success",
|
| 209 |
provider_state="generated",
|
| 210 |
repo_id=candidate,
|
| 211 |
output_path=str(output_path),
|
| 212 |
+
message=f"{candidate} generated a real Raven Quality artifact on HF Space.",
|
| 213 |
latency_seconds=round(time.perf_counter() - started, 2),
|
| 214 |
width=width,
|
| 215 |
height=height,
|
| 216 |
steps=steps,
|
| 217 |
hf_token_present=bool(token),
|
| 218 |
+
lora_status=str(lora_result.get("status", "disabled")),
|
| 219 |
+
lora_repo_id=lora_result.get("repo_id"),
|
| 220 |
+
lora_message=str(lora_result.get("message", "")),
|
| 221 |
+
fallback_used=candidate != repo_id,
|
| 222 |
+
primary_error=errors[0] if candidate != repo_id and errors else None,
|
| 223 |
)
|
| 224 |
except Exception as exc: # pragma: no cover - exercised on HF Space with gated/runtime conditions.
|
| 225 |
errors.append(f"{candidate}: {_short_error(exc)}")
|
| 226 |
+
with _PIPELINE_CACHE_LOCK:
|
| 227 |
+
_PIPELINE_CACHE.pop(candidate, None)
|
| 228 |
+
continue
|
| 229 |
return HFGenerationResult(
|
| 230 |
status="error",
|
| 231 |
provider_state="blocked",
|
|
|
|
| 235 |
width=width,
|
| 236 |
height=height,
|
| 237 |
steps=steps,
|
| 238 |
+
hf_token_present=bool(_hf_token()),
|
| 239 |
+
lora_status="disabled" if recipe is None else "failed",
|
| 240 |
+
lora_repo_id=recipe.repo_id if recipe else None,
|
| 241 |
+
lora_message="Generation failed before a usable LoRA evidence state could be produced.",
|
| 242 |
)
|
src/nexus_visual_weaver/lora_adapter.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Guarded LoRA adapter loading for HF runtime execution."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
from dataclasses import asdict
|
| 6 |
+
from typing import Any
|
| 7 |
+
|
| 8 |
+
from .schema import AdapterRecipe
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def _status(status: str, recipe: AdapterRecipe | None = None, **extra: Any) -> dict[str, Any]:
|
| 12 |
+
payload: dict[str, Any] = {
|
| 13 |
+
"status": status,
|
| 14 |
+
"repo_id": recipe.repo_id if recipe else None,
|
| 15 |
+
"adapter_for": recipe.adapter_for if recipe else None,
|
| 16 |
+
"weight": recipe.weight if recipe else None,
|
| 17 |
+
}
|
| 18 |
+
payload.update(extra)
|
| 19 |
+
return payload
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def _short_error(exc: BaseException) -> str:
|
| 23 |
+
text = str(exc).replace("\n", " ").strip()
|
| 24 |
+
if len(text) > 240:
|
| 25 |
+
text = text[:237] + "..."
|
| 26 |
+
return f"{exc.__class__.__name__}: {text}"
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def adapter_to_dict(recipe: AdapterRecipe) -> dict[str, Any]:
|
| 30 |
+
return asdict(recipe)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def is_compatible(pipe: Any, recipe: AdapterRecipe, target_repo_id: str, *, adult_mode: bool = False) -> bool:
|
| 34 |
+
if not recipe.runtime_enabled:
|
| 35 |
+
return False
|
| 36 |
+
if recipe.adult_only and not adult_mode:
|
| 37 |
+
return False
|
| 38 |
+
if recipe.requires_image:
|
| 39 |
+
return False
|
| 40 |
+
if not hasattr(pipe, "load_lora_weights"):
|
| 41 |
+
return False
|
| 42 |
+
|
| 43 |
+
compatible_ids = {recipe.adapter_for, *recipe.compatible_repo_ids}
|
| 44 |
+
if compatible_ids and target_repo_id not in compatible_ids:
|
| 45 |
+
return False
|
| 46 |
+
return True
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def load_and_apply(
|
| 50 |
+
pipe: Any,
|
| 51 |
+
recipe: AdapterRecipe | None,
|
| 52 |
+
target_repo_id: str,
|
| 53 |
+
*,
|
| 54 |
+
adult_mode: bool = False,
|
| 55 |
+
adapter_name: str = "nexus_style",
|
| 56 |
+
) -> dict[str, Any]:
|
| 57 |
+
if recipe is None:
|
| 58 |
+
return _status("disabled", message="No LoRA adapter selected for this run.")
|
| 59 |
+
if recipe.adult_only and not adult_mode:
|
| 60 |
+
return _status("skipped_incompatible", recipe, message="Adult-only adapter is not available while Adult Mode is off.")
|
| 61 |
+
if recipe.requires_image:
|
| 62 |
+
return _status("skipped_incompatible", recipe, message="Adapter requires image-conditioning support that is deferred in P0.")
|
| 63 |
+
if not hasattr(pipe, "load_lora_weights"):
|
| 64 |
+
return _status("unsupported_pipeline", recipe, message="Pipeline does not expose load_lora_weights.")
|
| 65 |
+
if not is_compatible(pipe, recipe, target_repo_id, adult_mode=adult_mode):
|
| 66 |
+
return _status("skipped_incompatible", recipe, message=f"Adapter is not declared compatible with {target_repo_id}.")
|
| 67 |
+
|
| 68 |
+
try:
|
| 69 |
+
kwargs: dict[str, Any] = {"adapter_name": adapter_name}
|
| 70 |
+
if recipe.weight_name:
|
| 71 |
+
kwargs["weight_name"] = recipe.weight_name
|
| 72 |
+
pipe.load_lora_weights(recipe.repo_id, **kwargs)
|
| 73 |
+
if hasattr(pipe, "set_adapters"):
|
| 74 |
+
pipe.set_adapters([adapter_name], adapter_weights=[recipe.weight])
|
| 75 |
+
return _status("loaded", recipe, message="Adapter loaded and applied for this generation.", adapter_name=adapter_name)
|
| 76 |
+
except Exception as exc:
|
| 77 |
+
return _status("failed", recipe, message=_short_error(exc), adapter_name=adapter_name)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def unload_all(pipe: Any) -> None:
|
| 81 |
+
try:
|
| 82 |
+
if hasattr(pipe, "unload_lora_weights"):
|
| 83 |
+
pipe.unload_lora_weights()
|
| 84 |
+
except Exception:
|
| 85 |
+
return
|
src/nexus_visual_weaver/model_relay.py
CHANGED
|
@@ -15,7 +15,6 @@ from typing import Any
|
|
| 15 |
|
| 16 |
PINNED_LANES = {"image_generation", "grounding", "security"}
|
| 17 |
ROTATABLE_LANES = {
|
| 18 |
-
"tiny_titan_sidecar",
|
| 19 |
"private_image_research",
|
| 20 |
"prompt_router",
|
| 21 |
"taste_judge",
|
|
@@ -189,11 +188,12 @@ class WeaverModelRelay:
|
|
| 189 |
lane_records = [record for record in self.records.values() if record.lane == lane]
|
| 190 |
if lane in PINNED_LANES:
|
| 191 |
primary = next((record for record in lane_records if record.pinned), None)
|
|
|
|
| 192 |
return LaneDecision(
|
| 193 |
lane=lane,
|
| 194 |
strategy="pinned",
|
| 195 |
primary=primary,
|
| 196 |
-
fallbacks=
|
| 197 |
reason="Pinned core lane; rotation disabled for creative identity, grounding, or security.",
|
| 198 |
expected_cost_hint=primary.cost_hint if primary else "unavailable",
|
| 199 |
quota_impact=self._quota_impact(primary, now) if primary else {},
|
|
@@ -381,7 +381,7 @@ class WeaverModelRelay:
|
|
| 381 |
|
| 382 |
def _decision_reason(self, primary: ModelRecord, strategy: str, public_demo: bool) -> str:
|
| 383 |
if strategy == "license_safe_public":
|
| 384 |
-
return f"{primary.model_id} selected because it is
|
| 385 |
if strategy == "quota_saver":
|
| 386 |
return f"{primary.model_id} selected to preserve provider quota and reuse cheaper metadata paths."
|
| 387 |
if strategy == "latency_first":
|
|
@@ -438,26 +438,26 @@ def default_model_records() -> list[ModelRecord]:
|
|
| 438 |
repo_id="black-forest-labs/FLUX.2-klein-9B",
|
| 439 |
license_gate="review_required",
|
| 440 |
params_b=9.0,
|
| 441 |
-
cost_hint="
|
| 442 |
rpm_limit=6,
|
| 443 |
rpd_limit=40,
|
| 444 |
-
quality_score=0.
|
| 445 |
latency_ms=26000,
|
| 446 |
pinned=True,
|
|
|
|
| 447 |
),
|
| 448 |
ModelRecord(
|
| 449 |
-
model_id="flux2-klein-4b-
|
| 450 |
-
lane="
|
| 451 |
provider="hf",
|
| 452 |
repo_id="black-forest-labs/FLUX.2-klein-4B",
|
| 453 |
license_gate="apache-2.0",
|
| 454 |
params_b=4.0,
|
| 455 |
-
cost_hint="
|
| 456 |
rpm_limit=8,
|
| 457 |
rpd_limit=60,
|
| 458 |
quality_score=0.92,
|
| 459 |
latency_ms=21000,
|
| 460 |
-
fallback_chain=("flux2-klein-9b-quality",),
|
| 461 |
),
|
| 462 |
ModelRecord(
|
| 463 |
model_id="flux2-klein-9b-private",
|
|
@@ -466,12 +466,24 @@ def default_model_records() -> list[ModelRecord]:
|
|
| 466 |
repo_id="black-forest-labs/FLUX.2-klein-9B",
|
| 467 |
license_gate="review_required",
|
| 468 |
params_b=9.0,
|
| 469 |
-
cost_hint="
|
| 470 |
rpm_limit=6,
|
| 471 |
rpd_limit=40,
|
| 472 |
quality_score=0.96,
|
| 473 |
latency_ms=26000,
|
| 474 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
),
|
| 476 |
ModelRecord(
|
| 477 |
model_id="locateanything-3b-anchor",
|
|
@@ -774,13 +786,13 @@ def default_model_records() -> list[ModelRecord]:
|
|
| 774 |
model_id="netflix-void-modal",
|
| 775 |
lane="video_repair",
|
| 776 |
provider="modal",
|
| 777 |
-
repo_id="
|
| 778 |
-
license_gate="
|
| 779 |
-
params_b=
|
| 780 |
-
cost_hint="
|
| 781 |
-
rpm_limit=
|
| 782 |
-
rpd_limit=
|
| 783 |
-
quality_score=0.
|
| 784 |
latency_ms=12000,
|
| 785 |
fallback_chain=("void-q5-offline",),
|
| 786 |
),
|
|
@@ -788,9 +800,9 @@ def default_model_records() -> list[ModelRecord]:
|
|
| 788 |
model_id="void-q5-offline",
|
| 789 |
lane="video_repair",
|
| 790 |
provider="local",
|
| 791 |
-
repo_id="local/
|
| 792 |
license_gate="private_research",
|
| 793 |
-
params_b=
|
| 794 |
cost_hint="offline",
|
| 795 |
rpm_limit=20,
|
| 796 |
rpd_limit=200,
|
|
|
|
| 15 |
|
| 16 |
PINNED_LANES = {"image_generation", "grounding", "security"}
|
| 17 |
ROTATABLE_LANES = {
|
|
|
|
| 18 |
"private_image_research",
|
| 19 |
"prompt_router",
|
| 20 |
"taste_judge",
|
|
|
|
| 188 |
lane_records = [record for record in self.records.values() if record.lane == lane]
|
| 189 |
if lane in PINNED_LANES:
|
| 190 |
primary = next((record for record in lane_records if record.pinned), None)
|
| 191 |
+
fallbacks = [self.records[model_id] for model_id in (primary.fallback_chain if primary else ()) if model_id in self.records]
|
| 192 |
return LaneDecision(
|
| 193 |
lane=lane,
|
| 194 |
strategy="pinned",
|
| 195 |
primary=primary,
|
| 196 |
+
fallbacks=fallbacks,
|
| 197 |
reason="Pinned core lane; rotation disabled for creative identity, grounding, or security.",
|
| 198 |
expected_cost_hint=primary.cost_hint if primary else "unavailable",
|
| 199 |
quota_impact=self._quota_impact(primary, now) if primary else {},
|
|
|
|
| 381 |
|
| 382 |
def _decision_reason(self, primary: ModelRecord, strategy: str, public_demo: bool) -> str:
|
| 383 |
if strategy == "license_safe_public":
|
| 384 |
+
return f"{primary.model_id} selected because it is public-demo safe and within helper budget."
|
| 385 |
if strategy == "quota_saver":
|
| 386 |
return f"{primary.model_id} selected to preserve provider quota and reuse cheaper metadata paths."
|
| 387 |
if strategy == "latency_first":
|
|
|
|
| 438 |
repo_id="black-forest-labs/FLUX.2-klein-9B",
|
| 439 |
license_gate="review_required",
|
| 440 |
params_b=9.0,
|
| 441 |
+
cost_hint="gated_provider_or_private_space",
|
| 442 |
rpm_limit=6,
|
| 443 |
rpd_limit=40,
|
| 444 |
+
quality_score=0.96,
|
| 445 |
latency_ms=26000,
|
| 446 |
pinned=True,
|
| 447 |
+
fallback_chain=("flux2-klein-4b-sidecar",),
|
| 448 |
),
|
| 449 |
ModelRecord(
|
| 450 |
+
model_id="flux2-klein-4b-sidecar",
|
| 451 |
+
lane="image_generation",
|
| 452 |
provider="hf",
|
| 453 |
repo_id="black-forest-labs/FLUX.2-klein-4B",
|
| 454 |
license_gate="apache-2.0",
|
| 455 |
params_b=4.0,
|
| 456 |
+
cost_hint="provider_or_local",
|
| 457 |
rpm_limit=8,
|
| 458 |
rpd_limit=60,
|
| 459 |
quality_score=0.92,
|
| 460 |
latency_ms=21000,
|
|
|
|
| 461 |
),
|
| 462 |
ModelRecord(
|
| 463 |
model_id="flux2-klein-9b-private",
|
|
|
|
| 466 |
repo_id="black-forest-labs/FLUX.2-klein-9B",
|
| 467 |
license_gate="review_required",
|
| 468 |
params_b=9.0,
|
| 469 |
+
cost_hint="gated_provider_or_private_space",
|
| 470 |
rpm_limit=6,
|
| 471 |
rpd_limit=40,
|
| 472 |
quality_score=0.96,
|
| 473 |
latency_ms=26000,
|
| 474 |
+
),
|
| 475 |
+
ModelRecord(
|
| 476 |
+
model_id="offellia-gemma4-12b-private-image-judge",
|
| 477 |
+
lane="private_image_research",
|
| 478 |
+
provider="local",
|
| 479 |
+
repo_id="Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf",
|
| 480 |
+
license_gate="private_research",
|
| 481 |
+
params_b=12.0,
|
| 482 |
+
cost_hint="local_gpu",
|
| 483 |
+
rpm_limit=20,
|
| 484 |
+
rpd_limit=200,
|
| 485 |
+
quality_score=0.95,
|
| 486 |
+
latency_ms=4200,
|
| 487 |
),
|
| 488 |
ModelRecord(
|
| 489 |
model_id="locateanything-3b-anchor",
|
|
|
|
| 786 |
model_id="netflix-void-modal",
|
| 787 |
lane="video_repair",
|
| 788 |
provider="modal",
|
| 789 |
+
repo_id="Netflix/VOID",
|
| 790 |
+
license_gate="private_research",
|
| 791 |
+
params_b=1.3,
|
| 792 |
+
cost_hint="modal_credits",
|
| 793 |
+
rpm_limit=10,
|
| 794 |
+
rpd_limit=120,
|
| 795 |
+
quality_score=0.84,
|
| 796 |
latency_ms=12000,
|
| 797 |
fallback_chain=("void-q5-offline",),
|
| 798 |
),
|
|
|
|
| 800 |
model_id="void-q5-offline",
|
| 801 |
lane="video_repair",
|
| 802 |
provider="local",
|
| 803 |
+
repo_id="local/VOID-Q5-video-repair",
|
| 804 |
license_gate="private_research",
|
| 805 |
+
params_b=1.3,
|
| 806 |
cost_hint="offline",
|
| 807 |
rpm_limit=20,
|
| 808 |
rpd_limit=200,
|
src/nexus_visual_weaver/planner.py
CHANGED
|
@@ -17,10 +17,20 @@ def build_command_center_run(
|
|
| 17 |
mode: str = "Strict",
|
| 18 |
video_preset: str = "Wan2.2 I2V",
|
| 19 |
adult_mode: bool = False,
|
|
|
|
|
|
|
| 20 |
) -> GenerationRun:
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
refined = refine_prompt(prompt, adult_mode=adult_mode)
|
| 23 |
-
outfit = build_outfit_graph(refined.refined, adult_mode=adult_mode)
|
| 24 |
inspection = inspect_outfit(outfit)
|
| 25 |
lore = build_lore_beats(refined.refined)
|
| 26 |
video = build_video_plan(video_preset)
|
|
@@ -52,4 +62,3 @@ def build_command_center_run(
|
|
| 52 |
video=video,
|
| 53 |
checkpoint=checkpoint,
|
| 54 |
)
|
| 55 |
-
|
|
|
|
| 17 |
mode: str = "Strict",
|
| 18 |
video_preset: str = "Wan2.2 I2V",
|
| 19 |
adult_mode: bool = False,
|
| 20 |
+
creator_controls: dict | None = None,
|
| 21 |
+
reference_metadata: list[dict] | None = None,
|
| 22 |
) -> GenerationRun:
|
| 23 |
+
controls = creator_controls or {}
|
| 24 |
+
references = reference_metadata or []
|
| 25 |
+
request = CreativeRequest(
|
| 26 |
+
prompt=prompt,
|
| 27 |
+
adult_mode=adult_mode,
|
| 28 |
+
references=[str(item.get("id") or item.get("basename") or item.get("url_hash")) for item in references],
|
| 29 |
+
creator_controls=controls,
|
| 30 |
+
reference_metadata=references,
|
| 31 |
+
)
|
| 32 |
refined = refine_prompt(prompt, adult_mode=adult_mode)
|
| 33 |
+
outfit = build_outfit_graph(refined.refined, adult_mode=adult_mode, controls=controls.get("wardrobe") if isinstance(controls, dict) else None)
|
| 34 |
inspection = inspect_outfit(outfit)
|
| 35 |
lore = build_lore_beats(refined.refined)
|
| 36 |
video = build_video_plan(video_preset)
|
|
|
|
| 62 |
video=video,
|
| 63 |
checkpoint=checkpoint,
|
| 64 |
)
|
|
|
src/nexus_visual_weaver/render.py
CHANGED
|
@@ -113,13 +113,13 @@ def render_command_header() -> str:
|
|
| 113 |
<div>
|
| 114 |
<small>COMMAND INPUT</small>
|
| 115 |
<strong>Raven Chronicle Active Weave</strong>
|
| 116 |
-
<span>
|
| 117 |
</div>
|
| 118 |
<div class="nw-command-pills">
|
| 119 |
-
{badge("
|
| 120 |
{badge("ST3GG ALWAYS ON", "cyan")}
|
| 121 |
{badge("FLUX.2 9B PINNED", "accent")}
|
| 122 |
-
{badge("4B
|
| 123 |
{badge("HUMAN CHECKPOINT", "warn")}
|
| 124 |
</div>
|
| 125 |
</section>
|
|
@@ -154,56 +154,6 @@ def render_trust_strip(scan: dict | None = None, operator_state: dict | None = N
|
|
| 154 |
"""
|
| 155 |
|
| 156 |
|
| 157 |
-
def _submission_link_ready() -> bool:
|
| 158 |
-
return bool(os.environ.get("NEXUS_DEMO_VIDEO_URL") and os.environ.get("NEXUS_SOCIAL_POST_URL"))
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
def _submission_readiness(scan: dict | None = None, operator_state: dict | None = None) -> tuple[int, int, list[tuple[str, bool, str]]]:
|
| 162 |
-
scan = scan or {"status": "idle", "export_gate": "pending"}
|
| 163 |
-
operator_state = operator_state or {}
|
| 164 |
-
generation = operator_state.get("generation") or {}
|
| 165 |
-
minicpm = operator_state.get("minicpm_judge") or {}
|
| 166 |
-
nemotron = operator_state.get("nemotron_evidence") or {}
|
| 167 |
-
gates = [
|
| 168 |
-
("Space/API", True, "Space is serving the command center and MCP/Gradio API."),
|
| 169 |
-
("Raven Stack", True, "28.50B quality stack is configured under the 32B rule."),
|
| 170 |
-
("ST3GG Visible", True, "Trust strip and export gate are above the fold."),
|
| 171 |
-
("FLUX Artifact", generation.get("status") == "success", "Run Active Weave must generate a real artifact."),
|
| 172 |
-
("Checkpoint", operator_state.get("checkpoint") == "approved", "Human checkpoint must approve the generated artifact."),
|
| 173 |
-
("Export Packet", bool(operator_state.get("export_packet")), "Prepare Export Packet must write evidence JSON."),
|
| 174 |
-
(
|
| 175 |
-
"Sponsor Evidence",
|
| 176 |
-
minicpm.get("status") == "success" and nemotron.get("status") == "success",
|
| 177 |
-
"MiniCPM and Nemotron both need configured secrets and successful calls.",
|
| 178 |
-
),
|
| 179 |
-
("Demo/Social", _submission_link_ready(), "Final demo video and social post URLs are still required."),
|
| 180 |
-
]
|
| 181 |
-
complete = sum(1 for _, ok, _ in gates if ok)
|
| 182 |
-
return complete, len(gates), gates
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
def render_submission_readiness(scan: dict | None = None, operator_state: dict | None = None) -> str:
|
| 186 |
-
complete, total, gates = _submission_readiness(scan, operator_state)
|
| 187 |
-
pct = int((complete / total) * 100)
|
| 188 |
-
chips = "".join(
|
| 189 |
-
f'<span class="nw-ready-chip {"is-done" if ok else "is-waiting"}">{escape(label)}</span>'
|
| 190 |
-
for label, ok, _ in gates
|
| 191 |
-
)
|
| 192 |
-
blockers = [help_text for _, ok, help_text in gates if not ok][:3]
|
| 193 |
-
blockers_html = " ".join(f"<span>{escape(text)}</span>" for text in blockers)
|
| 194 |
-
return f"""
|
| 195 |
-
<section class="nw-readiness">
|
| 196 |
-
<div class="nw-ready-head">
|
| 197 |
-
<strong>Hackathon Readiness</strong>
|
| 198 |
-
<small>{complete}/{total} gates complete</small>
|
| 199 |
-
</div>
|
| 200 |
-
<div class="nw-ready-meter"><i style="width:{pct}%"></i></div>
|
| 201 |
-
<div class="nw-ready-chips">{chips}</div>
|
| 202 |
-
<div class="nw-ready-blockers">{blockers_html}</div>
|
| 203 |
-
</section>
|
| 204 |
-
"""
|
| 205 |
-
|
| 206 |
-
|
| 207 |
def render_topbar(
|
| 208 |
adult_mode: bool = False,
|
| 209 |
relay_status: dict | None = None,
|
|
@@ -232,7 +182,7 @@ def render_topbar(
|
|
| 232 |
<div class="nw-topbar">
|
| 233 |
<div class="nw-brand"><span>NEXUS</span><strong>Visual Weaver</strong></div>
|
| 234 |
<div class="nw-topitem"><small>Project</small><strong>Raven Chronicle</strong><i></i></div>
|
| 235 |
-
<div class="nw-topitem"><small>Active Preset</small><strong>
|
| 236 |
<div class="nw-budget">
|
| 237 |
<div><strong>32B Parameter Budget</strong><small>{active:.2f}B / 32B ({pct}%)</small></div>
|
| 238 |
<div class="nw-meter"><i style="width:{pct}%"></i></div>
|
|
@@ -247,7 +197,6 @@ def render_topbar(
|
|
| 247 |
<div class="nw-locked"><b>18+</b><span>Locked. Enable in Security with explicit justification.</span></div>
|
| 248 |
</div>
|
| 249 |
{render_trust_strip(scan, operator_state)}
|
| 250 |
-
{render_submission_readiness(scan, operator_state)}
|
| 251 |
"""
|
| 252 |
|
| 253 |
|
|
@@ -308,7 +257,7 @@ def render_workflow(run: GenerationRun | None = None, operator_state: dict | Non
|
|
| 308 |
"refine": (275, 52, 185, 160, "Refine", ["Prompt Refiner", "Style Harmonizer", "Negative Purge"], "Qwen2.5-7B", "complete", "violet"),
|
| 309 |
"judge": (540, 52, 185, 160, "Judge", ["Aesthetic Scorer", "ST3GG Policy Filter", f"Score {score:.2f}"], "MiniCPM / Nemotron", "complete", "blue"),
|
| 310 |
"locate": (785, 52, 185, 160, "Locate", ["Reference Locator", "Pose & Composition", "IP-Adapter"], "Refs 3/5", "complete", "cyan"),
|
| 311 |
-
"generate": (275, 280, 235, 210, "Generate", ["Image / Video Generation", "FLUX.2 9B
|
| 312 |
"video": (590, 280, 235, 210, "Video Path", ["Image to Video", "Frame interpolation", run.video.preset if run else "Wan2.2 / LTX swap"], "Duration 5.6s 24fps", "ready", "blue"),
|
| 313 |
"checkpoint": (880, 285, 185, 185, "Human Checkpoint", ["Human review required", "Verify intent, vibe,", "and output before final."], "Review Now", "paused", "amber"),
|
| 314 |
}
|
|
@@ -621,7 +570,7 @@ def _render_relay_panel(relay_status: dict | None = None) -> str:
|
|
| 621 |
<h3>GMR ModelRelay</h3>
|
| 622 |
<ul class="nw-relay">{rows}</ul>
|
| 623 |
<div class="nw-relay-foot">
|
| 624 |
-
{badge("FLUX.2 9B pinned", "pass")} {badge("4B sidecar", "
|
| 625 |
</div>
|
| 626 |
"""
|
| 627 |
|
|
@@ -642,7 +591,6 @@ def render_provider_cards(relay_status: dict | None = None, adult_mode: bool = F
|
|
| 642 |
optional_statuses = {
|
| 643 |
"openbmb": "configured" if _provider_configured("MINICPM_BASE_URL", "MINICPM_API_KEY", "OPENBMB_API_KEY") else "missing secret",
|
| 644 |
"nvidia": "configured" if _provider_configured("NEMOTRON_BASE_URL", "NEMOTRON_API_KEY", "NVIDIA_API_KEY") else "missing secret",
|
| 645 |
-
"modal": "configured" if _env_configured("MODAL_TOKEN_ID", "MODAL_TOKEN_SECRET") else "deferred",
|
| 646 |
"fal": "configured" if _env_configured("FAL_KEY") else "blocked",
|
| 647 |
"netlify": "configured" if _env_configured("NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID", "OPENAI_BASE_URL") else "blocked",
|
| 648 |
"cloudflare": "configured" if _env_configured("CLOUDFLARE_API_TOKEN", "CF_ACCOUNT_ID") else "blocked",
|
|
@@ -679,9 +627,9 @@ def render_provider_cards(relay_status: dict | None = None, adult_mode: bool = F
|
|
| 679 |
<div class="nw-provider-card nw-provider-optional">
|
| 680 |
<small>optional gateway</small>
|
| 681 |
<strong>{escape(provider.title())}</strong>
|
| 682 |
-
<span>
|
| 683 |
-
<i class="nw-provider-meter" style="--health:{'74' if state == 'configured' else '
|
| 684 |
-
<div>{badge(state.upper(), "pass" if state == "configured" else "
|
| 685 |
</div>
|
| 686 |
"""
|
| 687 |
)
|
|
@@ -726,7 +674,7 @@ def render_inspector(
|
|
| 726 |
scan_status = (scan or {}).get("status", "pass")
|
| 727 |
else:
|
| 728 |
checks = [(label, True) for label in ["Patent Leather", "Faux Fur", "Lace / Mesh", "Crimson Hardware", "Platform Boots", "Layered Garments"]]
|
| 729 |
-
model_rows = "<li><span>active stack</span><strong>FLUX.2 9B /
|
| 730 |
score = 86
|
| 731 |
scan_status = (scan or {}).get("status", "pass")
|
| 732 |
checks_html = "".join(f'<li><span>{"✓" if ok else "!"}</span>{escape(label)}</li>' for label, ok in checks)
|
|
@@ -735,19 +683,11 @@ def render_inspector(
|
|
| 735 |
operator_state = operator_state or {}
|
| 736 |
minicpm = operator_state.get("minicpm_judge") or {}
|
| 737 |
nemotron = operator_state.get("nemotron_evidence") or {}
|
| 738 |
-
offellia = operator_state.get("offellia_judge") or {}
|
| 739 |
-
modal = operator_state.get("modal_video_repair") or {}
|
| 740 |
-
tts = operator_state.get("audio_lore_tts") or {}
|
| 741 |
-
locate = operator_state.get("locateanything_grounding") or {}
|
| 742 |
sponsor_rows = "".join(
|
| 743 |
f"<li><span>{escape(label)}</span><strong>{escape(str(result.get('status', 'pending')).upper())}</strong><em>{escape(str(result.get('repo_id', repo)))}</em></li>"
|
| 744 |
for label, repo, result in [
|
| 745 |
-
("OFFELLIA Quality Judge", "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf", offellia),
|
| 746 |
("OpenBMB MiniCPM", "openbmb/MiniCPM-V-4.6", minicpm),
|
| 747 |
("NVIDIA Nemotron", "nvidia/NVIDIA-Nemotron-Parse-v1.2", nemotron),
|
| 748 |
-
("LocateAnything Grounding", "nvidia/LocateAnything-3B", locate),
|
| 749 |
-
("Modal VOID Repair", "netflix/void-model", modal),
|
| 750 |
-
("Audio Lore TTS", "hexgrad/Kokoro-82M", tts),
|
| 751 |
]
|
| 752 |
)
|
| 753 |
findings = [_redact_scan_text(item) for item in (scan.get("findings") or [])]
|
|
|
|
| 113 |
<div>
|
| 114 |
<small>COMMAND INPUT</small>
|
| 115 |
<strong>Raven Chronicle Active Weave</strong>
|
| 116 |
+
<span>Prompt, reference scan, model route, and checkpoint controls stay in one sticky operator strip.</span>
|
| 117 |
</div>
|
| 118 |
<div class="nw-command-pills">
|
| 119 |
+
{badge("SFW DEFAULT", "pass")}
|
| 120 |
{badge("ST3GG ALWAYS ON", "cyan")}
|
| 121 |
{badge("FLUX.2 9B PINNED", "accent")}
|
| 122 |
+
{badge("4B SIDECAR", "cyan")}
|
| 123 |
{badge("HUMAN CHECKPOINT", "warn")}
|
| 124 |
</div>
|
| 125 |
</section>
|
|
|
|
| 154 |
"""
|
| 155 |
|
| 156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
def render_topbar(
|
| 158 |
adult_mode: bool = False,
|
| 159 |
relay_status: dict | None = None,
|
|
|
|
| 182 |
<div class="nw-topbar">
|
| 183 |
<div class="nw-brand"><span>NEXUS</span><strong>Visual Weaver</strong></div>
|
| 184 |
<div class="nw-topitem"><small>Project</small><strong>Raven Chronicle</strong><i></i></div>
|
| 185 |
+
<div class="nw-topitem"><small>Active Preset</small><strong>Dark Couture v2.4</strong><i></i></div>
|
| 186 |
<div class="nw-budget">
|
| 187 |
<div><strong>32B Parameter Budget</strong><small>{active:.2f}B / 32B ({pct}%)</small></div>
|
| 188 |
<div class="nw-meter"><i style="width:{pct}%"></i></div>
|
|
|
|
| 197 |
<div class="nw-locked"><b>18+</b><span>Locked. Enable in Security with explicit justification.</span></div>
|
| 198 |
</div>
|
| 199 |
{render_trust_strip(scan, operator_state)}
|
|
|
|
| 200 |
"""
|
| 201 |
|
| 202 |
|
|
|
|
| 257 |
"refine": (275, 52, 185, 160, "Refine", ["Prompt Refiner", "Style Harmonizer", "Negative Purge"], "Qwen2.5-7B", "complete", "violet"),
|
| 258 |
"judge": (540, 52, 185, 160, "Judge", ["Aesthetic Scorer", "ST3GG Policy Filter", f"Score {score:.2f}"], "MiniCPM / Nemotron", "complete", "blue"),
|
| 259 |
"locate": (785, 52, 185, 160, "Locate", ["Reference Locator", "Pose & Composition", "IP-Adapter"], "Refs 3/5", "complete", "cyan"),
|
| 260 |
+
"generate": (275, 280, 235, 210, "Generate", ["Image / Video Generation", "FLUX.2 9B + adapter stack", "4B sidecar fallback"], "Steps 4 CFG 1.0", "ready", "green"),
|
| 261 |
"video": (590, 280, 235, 210, "Video Path", ["Image to Video", "Frame interpolation", run.video.preset if run else "Wan2.2 / LTX swap"], "Duration 5.6s 24fps", "ready", "blue"),
|
| 262 |
"checkpoint": (880, 285, 185, 185, "Human Checkpoint", ["Human review required", "Verify intent, vibe,", "and output before final."], "Review Now", "paused", "amber"),
|
| 263 |
}
|
|
|
|
| 570 |
<h3>GMR ModelRelay</h3>
|
| 571 |
<ul class="nw-relay">{rows}</ul>
|
| 572 |
<div class="nw-relay-foot">
|
| 573 |
+
{badge("FLUX.2 9B pinned", "pass")} {badge("4B sidecar", "cyan")} {badge("LocateAnything pinned", "pass")} {badge(f"dedup hits {dedup_hits}", "muted")}
|
| 574 |
</div>
|
| 575 |
"""
|
| 576 |
|
|
|
|
| 591 |
optional_statuses = {
|
| 592 |
"openbmb": "configured" if _provider_configured("MINICPM_BASE_URL", "MINICPM_API_KEY", "OPENBMB_API_KEY") else "missing secret",
|
| 593 |
"nvidia": "configured" if _provider_configured("NEMOTRON_BASE_URL", "NEMOTRON_API_KEY", "NVIDIA_API_KEY") else "missing secret",
|
|
|
|
| 594 |
"fal": "configured" if _env_configured("FAL_KEY") else "blocked",
|
| 595 |
"netlify": "configured" if _env_configured("NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID", "OPENAI_BASE_URL") else "blocked",
|
| 596 |
"cloudflare": "configured" if _env_configured("CLOUDFLARE_API_TOKEN", "CF_ACCOUNT_ID") else "blocked",
|
|
|
|
| 627 |
<div class="nw-provider-card nw-provider-optional">
|
| 628 |
<small>optional gateway</small>
|
| 629 |
<strong>{escape(provider.title())}</strong>
|
| 630 |
+
<span>off by default / secrets required</span>
|
| 631 |
+
<i class="nw-provider-meter" style="--health:{'74' if state == 'configured' else '18'}"></i>
|
| 632 |
+
<div>{badge(state.upper(), "pass" if state == "configured" else "warn")}{badge("SPONSOR LANE" if provider in {"openbmb", "nvidia", "hf_nvidia"} else "NOT MVP DEFAULT", "muted")}</div>
|
| 633 |
</div>
|
| 634 |
"""
|
| 635 |
)
|
|
|
|
| 674 |
scan_status = (scan or {}).get("status", "pass")
|
| 675 |
else:
|
| 676 |
checks = [(label, True) for label in ["Patent Leather", "Faux Fur", "Lace / Mesh", "Crimson Hardware", "Platform Boots", "Layered Garments"]]
|
| 677 |
+
model_rows = "<li><span>active stack</span><strong>FLUX.2 9B / MiniCPM / LocateAnything</strong></li>"
|
| 678 |
score = 86
|
| 679 |
scan_status = (scan or {}).get("status", "pass")
|
| 680 |
checks_html = "".join(f'<li><span>{"✓" if ok else "!"}</span>{escape(label)}</li>' for label, ok in checks)
|
|
|
|
| 683 |
operator_state = operator_state or {}
|
| 684 |
minicpm = operator_state.get("minicpm_judge") or {}
|
| 685 |
nemotron = operator_state.get("nemotron_evidence") or {}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 686 |
sponsor_rows = "".join(
|
| 687 |
f"<li><span>{escape(label)}</span><strong>{escape(str(result.get('status', 'pending')).upper())}</strong><em>{escape(str(result.get('repo_id', repo)))}</em></li>"
|
| 688 |
for label, repo, result in [
|
|
|
|
| 689 |
("OpenBMB MiniCPM", "openbmb/MiniCPM-V-4.6", minicpm),
|
| 690 |
("NVIDIA Nemotron", "nvidia/NVIDIA-Nemotron-Parse-v1.2", nemotron),
|
|
|
|
|
|
|
|
|
|
| 691 |
]
|
| 692 |
)
|
| 693 |
findings = [_redact_scan_text(item) for item in (scan.get("findings") or [])]
|
src/nexus_visual_weaver/schema.py
CHANGED
|
@@ -17,6 +17,8 @@ class CreativeRequest:
|
|
| 17 |
output_goal: str = "image_to_video"
|
| 18 |
adult_mode: bool = False
|
| 19 |
references: list[str] = field(default_factory=list)
|
|
|
|
|
|
|
| 20 |
created_at: str = field(default_factory=utc_now)
|
| 21 |
|
| 22 |
|
|
@@ -84,6 +86,11 @@ class AdapterRecipe:
|
|
| 84 |
license: str = "unknown"
|
| 85 |
adult_only: bool = False
|
| 86 |
compatibility: str = "compatible"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
|
| 89 |
@dataclass(frozen=True)
|
|
|
|
| 17 |
output_goal: str = "image_to_video"
|
| 18 |
adult_mode: bool = False
|
| 19 |
references: list[str] = field(default_factory=list)
|
| 20 |
+
creator_controls: dict[str, Any] = field(default_factory=dict)
|
| 21 |
+
reference_metadata: list[dict[str, Any]] = field(default_factory=list)
|
| 22 |
created_at: str = field(default_factory=utc_now)
|
| 23 |
|
| 24 |
|
|
|
|
| 86 |
license: str = "unknown"
|
| 87 |
adult_only: bool = False
|
| 88 |
compatibility: str = "compatible"
|
| 89 |
+
weight_name: str | None = None
|
| 90 |
+
trigger_words: list[str] = field(default_factory=list)
|
| 91 |
+
compatible_repo_ids: list[str] = field(default_factory=list)
|
| 92 |
+
runtime_enabled: bool = True
|
| 93 |
+
requires_image: bool = False
|
| 94 |
|
| 95 |
|
| 96 |
@dataclass(frozen=True)
|
src/nexus_visual_weaver/styles.py
CHANGED
|
@@ -165,77 +165,6 @@ footer { display: none !important; }
|
|
| 165 |
.nw-trust-card .nw-badge {
|
| 166 |
margin-bottom: 1px;
|
| 167 |
}
|
| 168 |
-
.nw-readiness {
|
| 169 |
-
display: grid;
|
| 170 |
-
grid-template-columns: 190px minmax(180px, 260px) minmax(420px, 1fr);
|
| 171 |
-
gap: 10px;
|
| 172 |
-
align-items: center;
|
| 173 |
-
padding: 8px;
|
| 174 |
-
border-bottom: 1px solid #171c22;
|
| 175 |
-
background:
|
| 176 |
-
linear-gradient(90deg, rgba(255,54,95,.08), transparent 42%),
|
| 177 |
-
rgba(5, 7, 10, .98);
|
| 178 |
-
}
|
| 179 |
-
.nw-ready-head {
|
| 180 |
-
min-width: 0;
|
| 181 |
-
}
|
| 182 |
-
.nw-ready-head strong {
|
| 183 |
-
display: block;
|
| 184 |
-
font-size: 13px;
|
| 185 |
-
line-height: 1.2;
|
| 186 |
-
}
|
| 187 |
-
.nw-ready-head small {
|
| 188 |
-
color: var(--nw-muted);
|
| 189 |
-
font-size: 11px;
|
| 190 |
-
}
|
| 191 |
-
.nw-ready-meter {
|
| 192 |
-
height: 10px;
|
| 193 |
-
border-radius: 999px;
|
| 194 |
-
overflow: hidden;
|
| 195 |
-
background: #1d242c;
|
| 196 |
-
box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
|
| 197 |
-
}
|
| 198 |
-
.nw-ready-meter i {
|
| 199 |
-
display: block;
|
| 200 |
-
height: 100%;
|
| 201 |
-
background: linear-gradient(90deg, var(--nw-green), var(--nw-cyan));
|
| 202 |
-
box-shadow: 0 0 16px rgba(32,217,232,.32);
|
| 203 |
-
}
|
| 204 |
-
.nw-ready-chips {
|
| 205 |
-
display: flex;
|
| 206 |
-
flex-wrap: wrap;
|
| 207 |
-
gap: 5px;
|
| 208 |
-
}
|
| 209 |
-
.nw-ready-chip {
|
| 210 |
-
border: 1px solid var(--nw-line);
|
| 211 |
-
border-radius: 999px;
|
| 212 |
-
padding: 4px 8px;
|
| 213 |
-
color: var(--nw-muted);
|
| 214 |
-
font-size: 10px;
|
| 215 |
-
font-weight: 750;
|
| 216 |
-
white-space: nowrap;
|
| 217 |
-
}
|
| 218 |
-
.nw-ready-chip.is-done {
|
| 219 |
-
color: #9ff4c6;
|
| 220 |
-
border-color: rgba(38,215,130,.42);
|
| 221 |
-
background: rgba(38,215,130,.08);
|
| 222 |
-
}
|
| 223 |
-
.nw-ready-chip.is-waiting {
|
| 224 |
-
color: #ffb7c4;
|
| 225 |
-
border-color: rgba(255,54,95,.34);
|
| 226 |
-
background: rgba(255,54,95,.06);
|
| 227 |
-
}
|
| 228 |
-
.nw-ready-blockers {
|
| 229 |
-
grid-column: 1 / -1;
|
| 230 |
-
display: flex;
|
| 231 |
-
flex-wrap: wrap;
|
| 232 |
-
gap: 6px;
|
| 233 |
-
}
|
| 234 |
-
.nw-ready-blockers span {
|
| 235 |
-
color: var(--nw-muted);
|
| 236 |
-
font-size: 11px;
|
| 237 |
-
line-height: 1.35;
|
| 238 |
-
}
|
| 239 |
.nw-icon { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
| 240 |
.nw-shell {
|
| 241 |
display: grid;
|
|
@@ -1009,8 +938,6 @@ footer { display: none !important; }
|
|
| 1009 |
@media (max-width: 1100px) {
|
| 1010 |
.nw-topbar { grid-template-columns: 1fr; }
|
| 1011 |
.nw-trust-strip { grid-template-columns: 1fr; }
|
| 1012 |
-
.nw-readiness { grid-template-columns: 1fr; }
|
| 1013 |
-
.nw-ready-blockers { grid-column: 1; }
|
| 1014 |
.nw-shell { grid-template-columns: 1fr; grid-template-rows: auto; }
|
| 1015 |
.nw-rail, .nw-inspector, .nw-bottom { grid-column: 1; grid-row: auto; }
|
| 1016 |
.nw-rail { flex-direction: row; overflow-x: auto; }
|
|
|
|
| 165 |
.nw-trust-card .nw-badge {
|
| 166 |
margin-bottom: 1px;
|
| 167 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
.nw-icon { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
| 169 |
.nw-shell {
|
| 170 |
display: grid;
|
|
|
|
| 938 |
@media (max-width: 1100px) {
|
| 939 |
.nw-topbar { grid-template-columns: 1fr; }
|
| 940 |
.nw-trust-strip { grid-template-columns: 1fr; }
|
|
|
|
|
|
|
| 941 |
.nw-shell { grid-template-columns: 1fr; grid-template-rows: auto; }
|
| 942 |
.nw-rail, .nw-inspector, .nw-bottom { grid-column: 1; grid-row: auto; }
|
| 943 |
.nw-rail { flex-direction: row; overflow-x: auto; }
|
src/nexus_visual_weaver/wardrobe.py
CHANGED
|
@@ -17,10 +17,23 @@ SLOT_BLUEPRINTS: list[tuple[str, str, str, str, str]] = [
|
|
| 17 |
]
|
| 18 |
|
| 19 |
|
| 20 |
-
def build_outfit_graph(prompt: str, adult_mode: bool = False) -> OutfitGraph:
|
| 21 |
lowered = prompt.lower()
|
|
|
|
|
|
|
|
|
|
| 22 |
slots: list[WardrobeSlot] = []
|
| 23 |
for index, (name, description, material, palette, lora_hint) in enumerate(SLOT_BLUEPRINTS):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
locked = any(token in lowered for token in name.split("_")) or material.replace("_", " ") in lowered
|
| 25 |
if name == "outerwear" and "coat" in lowered:
|
| 26 |
locked = True
|
|
@@ -28,6 +41,8 @@ def build_outfit_graph(prompt: str, adult_mode: bool = False) -> OutfitGraph:
|
|
| 28 |
locked = True
|
| 29 |
if name == "jewelry" and ("crimson" in lowered or "hardware" in lowered):
|
| 30 |
locked = True
|
|
|
|
|
|
|
| 31 |
slots.append(
|
| 32 |
WardrobeSlot(
|
| 33 |
name=name,
|
|
@@ -37,11 +52,10 @@ def build_outfit_graph(prompt: str, adult_mode: bool = False) -> OutfitGraph:
|
|
| 37 |
lora_hint=lora_hint,
|
| 38 |
locked=locked,
|
| 39 |
adult_only=False if not adult_mode else name in {"upper_body", "lower_body"},
|
| 40 |
-
locate_region="auto-map",
|
| 41 |
edit_priority=max(1, 5 - index // 2),
|
| 42 |
)
|
| 43 |
)
|
| 44 |
locked_count = sum(1 for slot in slots if slot.locked)
|
| 45 |
score = round(0.68 + min(0.24, locked_count * 0.035), 2)
|
| 46 |
return OutfitGraph(slots=slots, score=score)
|
| 47 |
-
|
|
|
|
| 17 |
]
|
| 18 |
|
| 19 |
|
| 20 |
+
def build_outfit_graph(prompt: str, adult_mode: bool = False, controls: dict | None = None) -> OutfitGraph:
|
| 21 |
lowered = prompt.lower()
|
| 22 |
+
controls = controls or {}
|
| 23 |
+
locked_slots = set(controls.get("locked_slots") or [])
|
| 24 |
+
locate_focus = set(controls.get("locate_focus") or [])
|
| 25 |
slots: list[WardrobeSlot] = []
|
| 26 |
for index, (name, description, material, palette, lora_hint) in enumerate(SLOT_BLUEPRINTS):
|
| 27 |
+
if name == "outerwear" and controls.get("outerwear"):
|
| 28 |
+
description = str(controls["outerwear"])
|
| 29 |
+
if name == "upper_body" and controls.get("upper_body"):
|
| 30 |
+
material = str(controls["upper_body"])
|
| 31 |
+
if name == "footwear" and controls.get("footwear"):
|
| 32 |
+
description = str(controls["footwear"])
|
| 33 |
+
if name == "jewelry" and controls.get("hardware"):
|
| 34 |
+
material = str(controls["hardware"])
|
| 35 |
+
if controls.get("palette"):
|
| 36 |
+
palette = str(controls["palette"])
|
| 37 |
locked = any(token in lowered for token in name.split("_")) or material.replace("_", " ") in lowered
|
| 38 |
if name == "outerwear" and "coat" in lowered:
|
| 39 |
locked = True
|
|
|
|
| 41 |
locked = True
|
| 42 |
if name == "jewelry" and ("crimson" in lowered or "hardware" in lowered):
|
| 43 |
locked = True
|
| 44 |
+
if name in locked_slots:
|
| 45 |
+
locked = True
|
| 46 |
slots.append(
|
| 47 |
WardrobeSlot(
|
| 48 |
name=name,
|
|
|
|
| 52 |
lora_hint=lora_hint,
|
| 53 |
locked=locked,
|
| 54 |
adult_only=False if not adult_mode else name in {"upper_body", "lower_body"},
|
| 55 |
+
locate_region="manual-focus" if name in locate_focus else "auto-map",
|
| 56 |
edit_priority=max(1, 5 - index // 2),
|
| 57 |
)
|
| 58 |
)
|
| 59 |
locked_count = sum(1 for slot in slots if slot.locked)
|
| 60 |
score = round(0.68 + min(0.24, locked_count * 0.035), 2)
|
| 61 |
return OutfitGraph(slots=slots, score=score)
|
|
|
tests/test_app_callbacks.py
CHANGED
|
@@ -97,6 +97,36 @@ def test_run_weave_returns_stateful_dashboard_packet() -> None:
|
|
| 97 |
assert result[13].checkpoint.checkpoint_id.startswith("nw-")
|
| 98 |
assert result[15]["provider_state"] == "checkpointed"
|
| 99 |
assert result[16]["interactive"] is True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
|
| 101 |
|
| 102 |
def test_operator_actions_transition_checkpoint_export_and_stop() -> None:
|
|
@@ -146,40 +176,6 @@ def test_export_blocks_without_checkpoint() -> None:
|
|
| 146 |
assert "checkpoint" in blocked[13]["message"].lower()
|
| 147 |
|
| 148 |
|
| 149 |
-
def test_export_allows_st3gg_review_with_explicit_override() -> None:
|
| 150 |
-
from pathlib import Path
|
| 151 |
-
|
| 152 |
-
result = app.run_weave(
|
| 153 |
-
"gothic patent leather platform boots, crimson hardware",
|
| 154 |
-
"Strict",
|
| 155 |
-
"Wan2.2 I2V",
|
| 156 |
-
False,
|
| 157 |
-
None,
|
| 158 |
-
"Forge",
|
| 159 |
-
)
|
| 160 |
-
run = result[13]
|
| 161 |
-
artifact_path = Path("outputs/test-override-artifact.png")
|
| 162 |
-
artifact_path.parent.mkdir(parents=True, exist_ok=True)
|
| 163 |
-
artifact_path.write_bytes(b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIEND\xaeB`\x82NEXUS_REVIEW")
|
| 164 |
-
state = {
|
| 165 |
-
**result[15],
|
| 166 |
-
"generation": {**result[15]["generation"], "status": "success", "output_path": str(artifact_path)},
|
| 167 |
-
"checkpoint": "approved",
|
| 168 |
-
"provider_state": "checkpointed",
|
| 169 |
-
}
|
| 170 |
-
review_scan = {"status": "review", "export_gate": "blocked", "findings": ["high entropy sample"], "purification_actions": ["manual review"]}
|
| 171 |
-
|
| 172 |
-
blocked = app.export_packet(run, False, review_scan, "Forge", state, "")
|
| 173 |
-
assert blocked[13]["provider_state"] == "blocked"
|
| 174 |
-
assert "override reason" in blocked[13]["message"].lower()
|
| 175 |
-
|
| 176 |
-
exported = app.export_packet(run, False, review_scan, "Forge", state, "Judge-reviewed generated PNG; evidence packet only.")
|
| 177 |
-
assert exported[13]["provider_state"] == "exported"
|
| 178 |
-
assert exported[13]["export"] == "override"
|
| 179 |
-
assert exported[13]["st3gg_override_reason"] == "Judge-reviewed generated PNG; evidence packet only."
|
| 180 |
-
assert "export_packet" in exported[13]
|
| 181 |
-
|
| 182 |
-
|
| 183 |
def test_reference_scan_cannot_clear_blocked_generated_artifact() -> None:
|
| 184 |
base = app.ROOT / "outputs" / "test-app-callbacks"
|
| 185 |
base.mkdir(parents=True, exist_ok=True)
|
|
|
|
| 97 |
assert result[13].checkpoint.checkpoint_id.startswith("nw-")
|
| 98 |
assert result[15]["provider_state"] == "checkpointed"
|
| 99 |
assert result[16]["interactive"] is True
|
| 100 |
+
assert result[15]["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
|
| 101 |
+
assert result[15]["generation"]["lora_status"] == "disabled"
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def test_run_weave_persists_additive_creator_controls_and_reference_url_metadata() -> None:
|
| 105 |
+
result = app.run_weave(
|
| 106 |
+
"gothic patent leather platform boots, crimson hardware",
|
| 107 |
+
"Frontier",
|
| 108 |
+
"LTX-2.3",
|
| 109 |
+
False,
|
| 110 |
+
None,
|
| 111 |
+
"Wardrobe",
|
| 112 |
+
"layered tactical silhouette",
|
| 113 |
+
"faux fur collar coat",
|
| 114 |
+
"black mesh layer",
|
| 115 |
+
"patent leather heels",
|
| 116 |
+
"obsidian, pearl, crimson",
|
| 117 |
+
"silver occult buckles",
|
| 118 |
+
"https://shop.example.test/item/123",
|
| 119 |
+
)
|
| 120 |
+
|
| 121 |
+
state = result[15]
|
| 122 |
+
run = result[13]
|
| 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]
|
| 129 |
+
assert run.request.creator_controls["wardrobe"]["outerwear"] == "faux fur collar coat"
|
| 130 |
|
| 131 |
|
| 132 |
def test_operator_actions_transition_checkpoint_export_and_stop() -> None:
|
|
|
|
| 176 |
assert "checkpoint" in blocked[13]["message"].lower()
|
| 177 |
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
def test_reference_scan_cannot_clear_blocked_generated_artifact() -> None:
|
| 180 |
base = app.ROOT / "outputs" / "test-app-callbacks"
|
| 181 |
base.mkdir(parents=True, exist_ok=True)
|
tests/test_command_center.py
CHANGED
|
@@ -3,13 +3,10 @@ from pathlib import Path
|
|
| 3 |
from nexus_visual_weaver.catalog import (
|
| 4 |
DEFAULT_ACTIVE_STACK,
|
| 5 |
PRIVATE_RESEARCH_STACK,
|
| 6 |
-
RAVEN_QUALITY_STACK,
|
| 7 |
-
TINY_TITAN_STACK,
|
| 8 |
active_stack,
|
| 9 |
catalog_summary,
|
| 10 |
filter_catalog,
|
| 11 |
parameter_budget,
|
| 12 |
-
tiny_titan_stack,
|
| 13 |
)
|
| 14 |
from nexus_visual_weaver.grounding import inspect_outfit
|
| 15 |
from nexus_visual_weaver.model_relay import WeaverModelRelay
|
|
@@ -20,7 +17,6 @@ from nexus_visual_weaver.render import (
|
|
| 20 |
render_inspector,
|
| 21 |
render_operations_panel,
|
| 22 |
render_provider_cards,
|
| 23 |
-
render_submission_readiness,
|
| 24 |
render_topbar,
|
| 25 |
render_trust_strip,
|
| 26 |
)
|
|
@@ -67,25 +63,16 @@ def test_active_parameter_budget_passes_default_stack() -> None:
|
|
| 67 |
assert budget["active_b"] <= 32.0
|
| 68 |
|
| 69 |
|
| 70 |
-
def
|
| 71 |
stack = active_stack(False)
|
| 72 |
repo_ids = {model.repo_id for model in stack}
|
| 73 |
|
| 74 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
| 75 |
-
assert "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf" in repo_ids
|
| 76 |
assert "black-forest-labs/FLUX.2-klein-4B" not in repo_ids
|
|
|
|
| 77 |
assert all(model.params_b < 32.0 for model in stack)
|
| 78 |
|
| 79 |
|
| 80 |
-
def test_tiny_titan_stack_is_sidecar_only_and_all_models_are_under_4b() -> None:
|
| 81 |
-
stack = tiny_titan_stack()
|
| 82 |
-
repo_ids = {model.repo_id for model in stack}
|
| 83 |
-
|
| 84 |
-
assert "black-forest-labs/FLUX.2-klein-4B" in repo_ids
|
| 85 |
-
assert "black-forest-labs/FLUX.2-klein-9B" not in repo_ids
|
| 86 |
-
assert all(model.params_b <= 4.0 for model in stack)
|
| 87 |
-
|
| 88 |
-
|
| 89 |
def test_private_catalog_keeps_stronger_research_models_available() -> None:
|
| 90 |
private_models, _ = filter_catalog(True)
|
| 91 |
repo_ids = {model.repo_id for model in private_models}
|
|
@@ -227,7 +214,7 @@ def test_command_header_exposes_governed_run_controls() -> None:
|
|
| 227 |
assert "Raven Chronicle Active Weave" in header
|
| 228 |
assert "ST3GG ALWAYS ON" in header
|
| 229 |
assert "FLUX.2 9B PINNED" in header
|
| 230 |
-
assert "4B
|
| 231 |
assert "HUMAN CHECKPOINT" in header
|
| 232 |
|
| 233 |
|
|
@@ -316,8 +303,6 @@ def test_render_topbar_includes_trust_strip() -> None:
|
|
| 316 |
|
| 317 |
assert "TRUST MODEL" in html
|
| 318 |
assert "nw-trust-strip" in html
|
| 319 |
-
assert "Hackathon Readiness" in html
|
| 320 |
-
assert "3/8 gates complete" in html
|
| 321 |
|
| 322 |
|
| 323 |
def test_render_topbar_with_scan_passes_to_trust_strip() -> None:
|
|
@@ -342,24 +327,6 @@ def test_render_topbar_default_scan_shows_fixture_evidence() -> None:
|
|
| 342 |
assert "PNG trailing bytes -> blocked." in html
|
| 343 |
|
| 344 |
|
| 345 |
-
def test_submission_readiness_tracks_run_and_submission_blockers() -> None:
|
| 346 |
-
html = render_submission_readiness(
|
| 347 |
-
scan={"status": "review", "export_gate": "blocked"},
|
| 348 |
-
operator_state={
|
| 349 |
-
"generation": {"status": "success"},
|
| 350 |
-
"checkpoint": "approved",
|
| 351 |
-
"export_packet": {"path": "outputs/exports/nw.json"},
|
| 352 |
-
"minicpm_judge": {"status": "missing_secret"},
|
| 353 |
-
"nemotron_evidence": {"status": "missing_secret"},
|
| 354 |
-
},
|
| 355 |
-
)
|
| 356 |
-
|
| 357 |
-
assert "Hackathon Readiness" in html
|
| 358 |
-
assert "6/8 gates complete" in html
|
| 359 |
-
assert "MiniCPM and Nemotron" in html
|
| 360 |
-
assert "Final demo video and social post URLs" in html
|
| 361 |
-
|
| 362 |
-
|
| 363 |
# --- render_inspector sponsor evidence tests ---
|
| 364 |
|
| 365 |
def test_render_inspector_shows_sponsor_evidence_section() -> None:
|
|
@@ -393,7 +360,7 @@ def test_render_inspector_with_success_judge_shows_success_status() -> None:
|
|
| 393 |
def test_render_inspector_shows_default_stack_label_without_run() -> None:
|
| 394 |
html = render_inspector()
|
| 395 |
|
| 396 |
-
assert "FLUX.2 9B /
|
| 397 |
|
| 398 |
|
| 399 |
# --- render_provider_cards sponsor lane tests ---
|
|
@@ -480,11 +447,11 @@ def test_filter_catalog_includes_flux_9b_in_adult_mode() -> None:
|
|
| 480 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
| 481 |
|
| 482 |
|
| 483 |
-
def
|
| 484 |
models, _ = filter_catalog(False)
|
| 485 |
repo_ids = {model.repo_id for model in models}
|
| 486 |
|
| 487 |
-
assert "
|
| 488 |
|
| 489 |
|
| 490 |
def test_active_stack_uses_private_research_stack_in_adult_mode() -> None:
|
|
@@ -492,7 +459,6 @@ def test_active_stack_uses_private_research_stack_in_adult_mode() -> None:
|
|
| 492 |
repo_ids = {model.repo_id for model in stack}
|
| 493 |
|
| 494 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
| 495 |
-
assert "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf" in repo_ids
|
| 496 |
assert "black-forest-labs/FLUX.2-klein-4B" not in repo_ids
|
| 497 |
|
| 498 |
|
|
@@ -502,13 +468,10 @@ def test_private_research_stack_constant_contains_9b_and_offellia() -> None:
|
|
| 502 |
|
| 503 |
|
| 504 |
def test_default_active_stack_constant_uses_9b_and_sponsor_models() -> None:
|
| 505 |
-
assert DEFAULT_ACTIVE_STACK == RAVEN_QUALITY_STACK
|
| 506 |
assert "black-forest-labs/FLUX.2-klein-9B" in DEFAULT_ACTIVE_STACK
|
| 507 |
-
assert "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf" in DEFAULT_ACTIVE_STACK
|
| 508 |
assert "openbmb/MiniCPM-V-4.6" in DEFAULT_ACTIVE_STACK
|
| 509 |
assert "nvidia/NVIDIA-Nemotron-Parse-v1.2" in DEFAULT_ACTIVE_STACK
|
| 510 |
assert "black-forest-labs/FLUX.2-klein-4B" not in DEFAULT_ACTIVE_STACK
|
| 511 |
-
assert "black-forest-labs/FLUX.2-klein-4B" in TINY_TITAN_STACK
|
| 512 |
|
| 513 |
|
| 514 |
# --- schema ModelCandidate public_demo tests ---
|
|
@@ -548,8 +511,5 @@ def test_public_demo_false_models_are_excluded_from_public_filter() -> None:
|
|
| 548 |
license="other",
|
| 549 |
public_demo=False,
|
| 550 |
)
|
| 551 |
-
# public_demo=False should mean filter_catalog(False) excludes hidden support lanes.
|
| 552 |
-
# The catalog-level test: verify Modal VOID is absent from public catalog scope.
|
| 553 |
models_public, _ = filter_catalog(False)
|
| 554 |
assert all(m.public_demo for m in models_public)
|
| 555 |
-
assert "netflix/void-model" not in {model.repo_id for model in models_public}
|
|
|
|
| 3 |
from nexus_visual_weaver.catalog import (
|
| 4 |
DEFAULT_ACTIVE_STACK,
|
| 5 |
PRIVATE_RESEARCH_STACK,
|
|
|
|
|
|
|
| 6 |
active_stack,
|
| 7 |
catalog_summary,
|
| 8 |
filter_catalog,
|
| 9 |
parameter_budget,
|
|
|
|
| 10 |
)
|
| 11 |
from nexus_visual_weaver.grounding import inspect_outfit
|
| 12 |
from nexus_visual_weaver.model_relay import WeaverModelRelay
|
|
|
|
| 17 |
render_inspector,
|
| 18 |
render_operations_panel,
|
| 19 |
render_provider_cards,
|
|
|
|
| 20 |
render_topbar,
|
| 21 |
render_trust_strip,
|
| 22 |
)
|
|
|
|
| 63 |
assert budget["active_b"] <= 32.0
|
| 64 |
|
| 65 |
|
| 66 |
+
def test_public_stack_uses_flux_9b_and_excludes_offellia() -> None:
|
| 67 |
stack = active_stack(False)
|
| 68 |
repo_ids = {model.repo_id for model in stack}
|
| 69 |
|
| 70 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
|
|
|
| 71 |
assert "black-forest-labs/FLUX.2-klein-4B" not in repo_ids
|
| 72 |
+
assert not any("OFFELLIA" in repo_id for repo_id in repo_ids)
|
| 73 |
assert all(model.params_b < 32.0 for model in stack)
|
| 74 |
|
| 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
def test_private_catalog_keeps_stronger_research_models_available() -> None:
|
| 77 |
private_models, _ = filter_catalog(True)
|
| 78 |
repo_ids = {model.repo_id for model in private_models}
|
|
|
|
| 214 |
assert "Raven Chronicle Active Weave" in header
|
| 215 |
assert "ST3GG ALWAYS ON" in header
|
| 216 |
assert "FLUX.2 9B PINNED" in header
|
| 217 |
+
assert "4B SIDECAR" in header
|
| 218 |
assert "HUMAN CHECKPOINT" in header
|
| 219 |
|
| 220 |
|
|
|
|
| 303 |
|
| 304 |
assert "TRUST MODEL" in html
|
| 305 |
assert "nw-trust-strip" in html
|
|
|
|
|
|
|
| 306 |
|
| 307 |
|
| 308 |
def test_render_topbar_with_scan_passes_to_trust_strip() -> None:
|
|
|
|
| 327 |
assert "PNG trailing bytes -> blocked." in html
|
| 328 |
|
| 329 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 330 |
# --- render_inspector sponsor evidence tests ---
|
| 331 |
|
| 332 |
def test_render_inspector_shows_sponsor_evidence_section() -> None:
|
|
|
|
| 360 |
def test_render_inspector_shows_default_stack_label_without_run() -> None:
|
| 361 |
html = render_inspector()
|
| 362 |
|
| 363 |
+
assert "FLUX.2 9B / MiniCPM / LocateAnything" in html
|
| 364 |
|
| 365 |
|
| 366 |
# --- render_provider_cards sponsor lane tests ---
|
|
|
|
| 447 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
| 448 |
|
| 449 |
|
| 450 |
+
def test_filter_catalog_excludes_offellia_in_public_mode() -> None:
|
| 451 |
models, _ = filter_catalog(False)
|
| 452 |
repo_ids = {model.repo_id for model in models}
|
| 453 |
|
| 454 |
+
assert not any("OFFELLIA" in repo_id for repo_id in repo_ids)
|
| 455 |
|
| 456 |
|
| 457 |
def test_active_stack_uses_private_research_stack_in_adult_mode() -> None:
|
|
|
|
| 459 |
repo_ids = {model.repo_id for model in stack}
|
| 460 |
|
| 461 |
assert "black-forest-labs/FLUX.2-klein-9B" in repo_ids
|
|
|
|
| 462 |
assert "black-forest-labs/FLUX.2-klein-4B" not in repo_ids
|
| 463 |
|
| 464 |
|
|
|
|
| 468 |
|
| 469 |
|
| 470 |
def test_default_active_stack_constant_uses_9b_and_sponsor_models() -> None:
|
|
|
|
| 471 |
assert "black-forest-labs/FLUX.2-klein-9B" in DEFAULT_ACTIVE_STACK
|
|
|
|
| 472 |
assert "openbmb/MiniCPM-V-4.6" in DEFAULT_ACTIVE_STACK
|
| 473 |
assert "nvidia/NVIDIA-Nemotron-Parse-v1.2" in DEFAULT_ACTIVE_STACK
|
| 474 |
assert "black-forest-labs/FLUX.2-klein-4B" not in DEFAULT_ACTIVE_STACK
|
|
|
|
| 475 |
|
| 476 |
|
| 477 |
# --- schema ModelCandidate public_demo tests ---
|
|
|
|
| 511 |
license="other",
|
| 512 |
public_demo=False,
|
| 513 |
)
|
|
|
|
|
|
|
| 514 |
models_public, _ = filter_catalog(False)
|
| 515 |
assert all(m.public_demo for m in models_public)
|
|
|
tests/test_exporter.py
CHANGED
|
@@ -10,14 +10,31 @@ def _make_base_state(**overrides):
|
|
| 10 |
"provider_state": "export_ready",
|
| 11 |
"checkpoint": "approved",
|
| 12 |
"message": "approved",
|
| 13 |
-
"generation": {
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
"minicpm_judge": {"status": "success", "repo_id": "openbmb/MiniCPM-V-4.6"},
|
| 17 |
"nemotron_evidence": {"status": "missing_secret", "repo_id": "nvidia/NVIDIA-Nemotron-Parse-v1.2"},
|
| 18 |
-
"modal_video_repair": {"status": "deferred", "repo_id": "netflix/void-model", "provider": "modal"},
|
| 19 |
-
"audio_lore_tts": {"status": "optional", "repo_id": "hexgrad/Kokoro-82M"},
|
| 20 |
-
"tiny_titan_sidecar": {"status": "available", "repo_id": "black-forest-labs/FLUX.2-klein-4B"},
|
| 21 |
}
|
| 22 |
state.update(overrides)
|
| 23 |
return state
|
|
@@ -37,17 +54,13 @@ def test_write_export_packet_records_evidence_without_secrets(monkeypatch) -> No
|
|
| 37 |
assert payload["hackathon_claims"]["openbmb_lane"] is True
|
| 38 |
assert payload["hackathon_claims"]["nvidia_nemotron_lane"] is False
|
| 39 |
assert payload["parameter_budget"]["status"] == "pass"
|
| 40 |
-
assert payload["active_preset"] == "Raven Quality Stack"
|
| 41 |
-
assert payload["modal_video_repair"]["repo_id"] == "netflix/void-model"
|
| 42 |
-
assert payload["offellia_judge"]["repo_id"] == "Brunobkr/OFFELLIA_Q4_0_gemma-4-12B-it.gguf"
|
| 43 |
-
assert payload["audio_lore_tts"]["repo_id"] == "hexgrad/Kokoro-82M"
|
| 44 |
-
assert payload["tiny_titan_sidecar"]["repo_id"] == "black-forest-labs/FLUX.2-klein-4B"
|
| 45 |
-
assert payload["hackathon_claims"]["raven_quality_stack"] is True
|
| 46 |
-
assert payload["hackathon_claims"]["locateanything_grounding"] is True
|
| 47 |
-
assert payload["hackathon_claims"]["offellia_quality_lane"] is False
|
| 48 |
assert "token" not in json.dumps(payload).lower()
|
| 49 |
assert payload["artifact"] == "artifact.png"
|
|
|
|
| 50 |
assert payload["generation"]["output_path"] == "artifact.png"
|
|
|
|
|
|
|
|
|
|
| 51 |
assert "/data/" not in json.dumps(payload)
|
| 52 |
|
| 53 |
|
|
@@ -131,20 +144,6 @@ def test_export_packet_hackathon_claims_st3gg_export_gate(monkeypatch) -> None:
|
|
| 131 |
assert payload_blocked["hackathon_claims"]["st3gg_export_gate"] == "blocked"
|
| 132 |
|
| 133 |
|
| 134 |
-
def test_export_packet_records_st3gg_override_reason(monkeypatch) -> None:
|
| 135 |
-
monkeypatch.setenv("NEXUS_EXPORT_DIR", "outputs/test-exports")
|
| 136 |
-
run = build_command_center_run("review override brief")
|
| 137 |
-
scan = {"status": "review", "export_gate": "blocked"}
|
| 138 |
-
state = _make_base_state(st3gg_override_reason="Human reviewed generated artifact for evidence-only export.")
|
| 139 |
-
|
| 140 |
-
result = write_export_packet(run=run, scan=scan, operator_state=state, adult_mode=False)
|
| 141 |
-
payload = json.loads(Path(result["path"]).read_text(encoding="utf-8"))
|
| 142 |
-
|
| 143 |
-
assert payload["st3gg_override_reason"] == "Human reviewed generated artifact for evidence-only export."
|
| 144 |
-
assert payload["hackathon_claims"]["st3gg_override_recorded"] is True
|
| 145 |
-
assert payload["hackathon_claims"]["st3gg_export_gate"] == "blocked"
|
| 146 |
-
|
| 147 |
-
|
| 148 |
def test_export_packet_includes_model_stack_and_prompts(monkeypatch) -> None:
|
| 149 |
monkeypatch.setenv("NEXUS_EXPORT_DIR", "outputs/test-exports")
|
| 150 |
run = build_command_center_run("raven archivist couture brief")
|
|
@@ -211,3 +210,62 @@ def test_export_packet_returns_both_path_and_packet(monkeypatch) -> None:
|
|
| 211 |
assert "packet" in result
|
| 212 |
assert isinstance(result["packet"], dict)
|
| 213 |
assert result["packet"]["schema"] == "nexus_visual_weaver.export_packet.v1"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
"provider_state": "export_ready",
|
| 11 |
"checkpoint": "approved",
|
| 12 |
"message": "approved",
|
| 13 |
+
"generation": {
|
| 14 |
+
"status": "success",
|
| 15 |
+
"provider_state": "generated",
|
| 16 |
+
"output_path": "/data/artifact.png",
|
| 17 |
+
"hf_token_present": True,
|
| 18 |
+
"lora_status": "loaded",
|
| 19 |
+
"lora_repo_id": "DeverStyle/Flux.2-Klein-Loras",
|
| 20 |
+
"lora_message": "Adapter loaded and applied for this generation.",
|
| 21 |
+
},
|
| 22 |
+
"creator_controls": {
|
| 23 |
+
"reasoning_mode": "Strict",
|
| 24 |
+
"wardrobe": {"outerwear": "black patent leather long coat", "footwear": "platform boots"},
|
| 25 |
+
},
|
| 26 |
+
"reference_metadata": [
|
| 27 |
+
{
|
| 28 |
+
"source": "upload",
|
| 29 |
+
"basename": "C:/Users/speci.000/Downloads/reference.png",
|
| 30 |
+
"sha256": "a" * 64,
|
| 31 |
+
"size_bytes": 128,
|
| 32 |
+
"st3gg_status": "pass",
|
| 33 |
+
"export_gate": "clear",
|
| 34 |
+
}
|
| 35 |
+
],
|
| 36 |
"minicpm_judge": {"status": "success", "repo_id": "openbmb/MiniCPM-V-4.6"},
|
| 37 |
"nemotron_evidence": {"status": "missing_secret", "repo_id": "nvidia/NVIDIA-Nemotron-Parse-v1.2"},
|
|
|
|
|
|
|
|
|
|
| 38 |
}
|
| 39 |
state.update(overrides)
|
| 40 |
return state
|
|
|
|
| 54 |
assert payload["hackathon_claims"]["openbmb_lane"] is True
|
| 55 |
assert payload["hackathon_claims"]["nvidia_nemotron_lane"] is False
|
| 56 |
assert payload["parameter_budget"]["status"] == "pass"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
assert "token" not in json.dumps(payload).lower()
|
| 58 |
assert payload["artifact"] == "artifact.png"
|
| 59 |
+
assert payload["image_basename"] == "artifact.png"
|
| 60 |
assert payload["generation"]["output_path"] == "artifact.png"
|
| 61 |
+
assert payload["lora_status"]["status"] == "loaded"
|
| 62 |
+
assert payload["creator_controls"]["wardrobe"]["footwear"] == "platform boots"
|
| 63 |
+
assert payload["reference_metadata"][0]["basename"] == "reference.png"
|
| 64 |
assert "/data/" not in json.dumps(payload)
|
| 65 |
|
| 66 |
|
|
|
|
| 144 |
assert payload_blocked["hackathon_claims"]["st3gg_export_gate"] == "blocked"
|
| 145 |
|
| 146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
def test_export_packet_includes_model_stack_and_prompts(monkeypatch) -> None:
|
| 148 |
monkeypatch.setenv("NEXUS_EXPORT_DIR", "outputs/test-exports")
|
| 149 |
run = build_command_center_run("raven archivist couture brief")
|
|
|
|
| 210 |
assert "packet" in result
|
| 211 |
assert isinstance(result["packet"], dict)
|
| 212 |
assert result["packet"]["schema"] == "nexus_visual_weaver.export_packet.v1"
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
def test_export_packet_redacts_raw_payload_paths_and_secret_like_values(monkeypatch) -> None:
|
| 216 |
+
monkeypatch.setenv("NEXUS_EXPORT_DIR", "outputs/test-exports")
|
| 217 |
+
run = build_command_center_run(
|
| 218 |
+
"redaction brief",
|
| 219 |
+
creator_controls={"wardrobe": {"footwear": "platform boots"}},
|
| 220 |
+
reference_metadata=[{"source": "url", "domain": "shop.example.test", "url_hash": "b" * 64}],
|
| 221 |
+
)
|
| 222 |
+
scan = {
|
| 223 |
+
"status": "review",
|
| 224 |
+
"export_gate": "blocked",
|
| 225 |
+
"payload_excerpt": "hf_" + "abcdefghijklmnopqrstuvwxyz123456",
|
| 226 |
+
"findings": ["raw hidden bytes at C:/Users/speci.000/Downloads/thing.png"],
|
| 227 |
+
"purification_actions": ["base64 payload removed from /data/nexus_visual_weaver/artifact.png"],
|
| 228 |
+
}
|
| 229 |
+
state = _make_base_state(
|
| 230 |
+
generation={
|
| 231 |
+
"status": "success",
|
| 232 |
+
"provider_state": "generated",
|
| 233 |
+
"output_path": "/data/nexus_visual_weaver/artifact.png",
|
| 234 |
+
"hf_token_present": True,
|
| 235 |
+
"lora_status": "failed",
|
| 236 |
+
"lora_repo_id": "example/lora",
|
| 237 |
+
"lora_message": "RuntimeError: failed without token value",
|
| 238 |
+
},
|
| 239 |
+
minicpm_judge={
|
| 240 |
+
"status": "failed",
|
| 241 |
+
"provider_state": "failed",
|
| 242 |
+
"provider": "OpenBMB",
|
| 243 |
+
"repo_id": "openbmb/MiniCPM-V-4.6",
|
| 244 |
+
"model": "MiniCPM-V-4.6",
|
| 245 |
+
"message": "Set MINICPM_API_KEY in Space secrets.",
|
| 246 |
+
"evidence": {"raw_summary": "Bearer " + "secret-value", "configured": True},
|
| 247 |
+
},
|
| 248 |
+
reference_metadata=[
|
| 249 |
+
{
|
| 250 |
+
"source": "upload",
|
| 251 |
+
"basename": "C:/Users/speci.000/Downloads/reference.png",
|
| 252 |
+
"sha256": "c" * 64,
|
| 253 |
+
"size_bytes": 2048,
|
| 254 |
+
"st3gg_status": "review",
|
| 255 |
+
"export_gate": "blocked",
|
| 256 |
+
}
|
| 257 |
+
],
|
| 258 |
+
)
|
| 259 |
+
|
| 260 |
+
result = write_export_packet(run=run, scan=scan, operator_state=state, adult_mode=False)
|
| 261 |
+
payload = json.loads(Path(result["path"]).read_text(encoding="utf-8"))
|
| 262 |
+
serialized = json.dumps(payload)
|
| 263 |
+
|
| 264 |
+
assert "payload_excerpt" not in serialized
|
| 265 |
+
assert "raw_summary" not in serialized
|
| 266 |
+
assert "Bearer " + "secret-value" not in serialized
|
| 267 |
+
assert "MINICPM_API_KEY" not in serialized
|
| 268 |
+
assert "/data/" not in serialized
|
| 269 |
+
assert "C:/Users/speci.000/Downloads" not in serialized
|
| 270 |
+
assert payload["st3gg_verdict"] == {"status": "review", "export_gate": "blocked"}
|
| 271 |
+
assert payload["provider_states"]["minicpm"] == "failed"
|
tests/test_hf_runtime.py
CHANGED
|
@@ -4,7 +4,7 @@ from nexus_visual_weaver.hf_runtime import (
|
|
| 4 |
FLUX_REPO_ID,
|
| 5 |
PRIVATE_RESEARCH_FLUX_REPO_ID,
|
| 6 |
TINY_TITAN_FLUX_REPO_ID,
|
| 7 |
-
|
| 8 |
generate_flux_image,
|
| 9 |
hf_runtime_enabled,
|
| 10 |
)
|
|
@@ -22,19 +22,18 @@ def test_hf_runtime_is_disabled_locally_by_default(monkeypatch) -> None:
|
|
| 22 |
assert result.status == "disabled"
|
| 23 |
assert result.provider_state == "dry-run"
|
| 24 |
assert result.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
|
|
|
|
|
|
| 25 |
|
| 26 |
|
| 27 |
-
def
|
| 28 |
-
monkeypatch.delenv("NEXUS_FLUX_REPO_ID", raising=False)
|
| 29 |
-
monkeypatch.delenv("NEXUS_TINY_TITAN_MODE", raising=False)
|
| 30 |
-
|
| 31 |
assert FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-9B"
|
| 32 |
assert PRIVATE_RESEARCH_FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-9B"
|
| 33 |
assert TINY_TITAN_FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-4B"
|
| 34 |
-
assert active_flux_repo_id() == FLUX_REPO_ID
|
| 35 |
|
| 36 |
-
|
| 37 |
-
|
|
|
|
| 38 |
|
| 39 |
|
| 40 |
def test_artifact_lane_embeds_generated_image() -> None:
|
|
|
|
| 4 |
FLUX_REPO_ID,
|
| 5 |
PRIVATE_RESEARCH_FLUX_REPO_ID,
|
| 6 |
TINY_TITAN_FLUX_REPO_ID,
|
| 7 |
+
default_lora_repo_id,
|
| 8 |
generate_flux_image,
|
| 9 |
hf_runtime_enabled,
|
| 10 |
)
|
|
|
|
| 22 |
assert result.status == "disabled"
|
| 23 |
assert result.provider_state == "dry-run"
|
| 24 |
assert result.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
| 25 |
+
assert result.lora_status == "disabled"
|
| 26 |
+
assert result.lora_repo_id == "DeverStyle/Flux.2-Klein-Loras"
|
| 27 |
|
| 28 |
|
| 29 |
+
def test_flux_repo_ids_use_9b_with_4b_sidecar() -> None:
|
|
|
|
|
|
|
|
|
|
| 30 |
assert FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-9B"
|
| 31 |
assert PRIVATE_RESEARCH_FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-9B"
|
| 32 |
assert TINY_TITAN_FLUX_REPO_ID == "black-forest-labs/FLUX.2-klein-4B"
|
|
|
|
| 33 |
|
| 34 |
+
|
| 35 |
+
def test_default_lora_repo_id_prefers_runtime_enabled_compatible_adapter() -> None:
|
| 36 |
+
assert default_lora_repo_id("black-forest-labs/FLUX.2-klein-9B") == "DeverStyle/Flux.2-Klein-Loras"
|
| 37 |
|
| 38 |
|
| 39 |
def test_artifact_lane_embeds_generated_image() -> None:
|
tests/test_lora_adapter.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from nexus_visual_weaver.lora_adapter import load_and_apply, unload_all
|
| 2 |
+
from nexus_visual_weaver.schema import AdapterRecipe
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class FakeLoraPipe:
|
| 6 |
+
def __init__(self) -> None:
|
| 7 |
+
self.loaded: list[tuple[str, dict]] = []
|
| 8 |
+
self.adapters: tuple[list[str], list[float]] | None = None
|
| 9 |
+
self.unloaded = False
|
| 10 |
+
|
| 11 |
+
def load_lora_weights(self, repo_id: str, **kwargs) -> None:
|
| 12 |
+
self.loaded.append((repo_id, kwargs))
|
| 13 |
+
|
| 14 |
+
def set_adapters(self, adapter_names: list[str], adapter_weights: list[float]) -> None:
|
| 15 |
+
self.adapters = (adapter_names, adapter_weights)
|
| 16 |
+
|
| 17 |
+
def unload_lora_weights(self) -> None:
|
| 18 |
+
self.unloaded = True
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class FailingLoraPipe(FakeLoraPipe):
|
| 22 |
+
def load_lora_weights(self, repo_id: str, **kwargs) -> None:
|
| 23 |
+
raise RuntimeError("adapter load failed")
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class UnsupportedPipe:
|
| 27 |
+
pass
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def test_load_and_apply_reports_loaded_for_compatible_pipe() -> None:
|
| 31 |
+
recipe = AdapterRecipe(
|
| 32 |
+
repo_id="example/style-lora",
|
| 33 |
+
adapter_for="black-forest-labs/FLUX.2-klein-9B",
|
| 34 |
+
task="style",
|
| 35 |
+
weight=0.6,
|
| 36 |
+
)
|
| 37 |
+
pipe = FakeLoraPipe()
|
| 38 |
+
|
| 39 |
+
result = load_and_apply(pipe, recipe, "black-forest-labs/FLUX.2-klein-9B")
|
| 40 |
+
|
| 41 |
+
assert result["status"] == "loaded"
|
| 42 |
+
assert result["repo_id"] == "example/style-lora"
|
| 43 |
+
assert pipe.loaded == [("example/style-lora", {"adapter_name": "nexus_style"})]
|
| 44 |
+
assert pipe.adapters == (["nexus_style"], [0.6])
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_load_and_apply_reports_skipped_for_incompatible_adapter() -> None:
|
| 48 |
+
recipe = AdapterRecipe(
|
| 49 |
+
repo_id="example/style-lora",
|
| 50 |
+
adapter_for="black-forest-labs/FLUX.2-klein-4B",
|
| 51 |
+
task="style",
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
result = load_and_apply(FakeLoraPipe(), recipe, "black-forest-labs/FLUX.2-klein-9B")
|
| 55 |
+
|
| 56 |
+
assert result["status"] == "skipped_incompatible"
|
| 57 |
+
assert "not declared compatible" in result["message"]
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def test_load_and_apply_reports_unsupported_pipeline() -> None:
|
| 61 |
+
recipe = AdapterRecipe(
|
| 62 |
+
repo_id="example/style-lora",
|
| 63 |
+
adapter_for="black-forest-labs/FLUX.2-klein-9B",
|
| 64 |
+
task="style",
|
| 65 |
+
)
|
| 66 |
+
|
| 67 |
+
result = load_and_apply(UnsupportedPipe(), recipe, "black-forest-labs/FLUX.2-klein-9B")
|
| 68 |
+
|
| 69 |
+
assert result["status"] == "unsupported_pipeline"
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
def test_load_and_apply_reports_failed_without_raising() -> None:
|
| 73 |
+
recipe = AdapterRecipe(
|
| 74 |
+
repo_id="example/style-lora",
|
| 75 |
+
adapter_for="black-forest-labs/FLUX.2-klein-9B",
|
| 76 |
+
task="style",
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
result = load_and_apply(FailingLoraPipe(), recipe, "black-forest-labs/FLUX.2-klein-9B")
|
| 80 |
+
|
| 81 |
+
assert result["status"] == "failed"
|
| 82 |
+
assert "RuntimeError" in result["message"]
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def test_unload_all_uses_pipeline_unload_hook() -> None:
|
| 86 |
+
pipe = FakeLoraPipe()
|
| 87 |
+
|
| 88 |
+
unload_all(pipe)
|
| 89 |
+
|
| 90 |
+
assert pipe.unloaded is True
|
tests/test_model_relay.py
CHANGED
|
@@ -13,18 +13,17 @@ def test_pinned_lanes_do_not_rotate() -> None:
|
|
| 13 |
assert decision.primary is not None
|
| 14 |
assert decision.primary.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
| 15 |
assert decision.primary.params_b == 9.0
|
| 16 |
-
assert decision.fallbacks == []
|
| 17 |
assert "rotation disabled" in decision.reason
|
| 18 |
|
| 19 |
|
| 20 |
-
def
|
| 21 |
relay = WeaverModelRelay()
|
| 22 |
-
decision = relay.select_lane("
|
| 23 |
|
| 24 |
assert decision.primary is not None
|
| 25 |
-
assert decision.primary.repo_id == "black-forest-labs/FLUX.2-klein-
|
| 26 |
assert decision.primary.pinned is False
|
| 27 |
-
assert decision.primary.params_b == 4.0
|
| 28 |
|
| 29 |
|
| 30 |
def test_public_private_taste_judge_respects_license_and_budget() -> None:
|
|
@@ -137,8 +136,6 @@ def test_optional_external_gateways_are_registered_but_excluded_by_default() ->
|
|
| 137 |
assert relay.records["netlify-ai-gateway-helper"].provider == "netlify"
|
| 138 |
assert relay.records["cloudflare-agent-helper"].provider == "cloudflare"
|
| 139 |
assert relay.records["fal-media-adapter"].provider == "fal"
|
| 140 |
-
assert relay.records["netflix-void-modal"].repo_id == "netflix/void-model"
|
| 141 |
-
assert relay.records["netflix-void-modal"].params_b == 5.0
|
| 142 |
assert relay.records["netflix-void-modal"].health == "healthy"
|
| 143 |
assert relay.records["netlify-ai-gateway-helper"].health == "excluded"
|
| 144 |
assert relay.records["fal-media-adapter"].health == "excluded"
|
|
@@ -188,27 +185,31 @@ def test_private_image_research_lane_is_rotatable() -> None:
|
|
| 188 |
assert "private_image_research" in ROTATABLE_LANES
|
| 189 |
|
| 190 |
|
| 191 |
-
def
|
| 192 |
relay = WeaverModelRelay()
|
| 193 |
|
| 194 |
record = relay.records["flux2-klein-9b-quality"]
|
|
|
|
| 195 |
|
| 196 |
assert record.lane == "image_generation"
|
| 197 |
assert record.pinned is True
|
| 198 |
assert record.params_b == 9.0
|
| 199 |
assert record.license_gate == "review_required"
|
| 200 |
assert record.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
|
|
|
|
|
|
|
|
|
| 201 |
|
| 202 |
|
| 203 |
-
def
|
| 204 |
relay = WeaverModelRelay()
|
| 205 |
|
| 206 |
-
record = relay.records["flux2-klein-
|
| 207 |
|
| 208 |
-
assert record.lane == "
|
| 209 |
assert record.pinned is False
|
| 210 |
-
assert record.params_b ==
|
| 211 |
-
assert record.license_gate == "
|
| 212 |
|
| 213 |
|
| 214 |
def test_minicpm_has_fallback_chain_configured() -> None:
|
|
|
|
| 13 |
assert decision.primary is not None
|
| 14 |
assert decision.primary.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
| 15 |
assert decision.primary.params_b == 9.0
|
| 16 |
+
assert [fallback.repo_id for fallback in decision.fallbacks] == ["black-forest-labs/FLUX.2-klein-4B"]
|
| 17 |
assert "rotation disabled" in decision.reason
|
| 18 |
|
| 19 |
|
| 20 |
+
def test_private_image_research_keeps_flux_9b_available() -> None:
|
| 21 |
relay = WeaverModelRelay()
|
| 22 |
+
decision = relay.select_lane("private_image_research", budget=9.0, public_demo=False, strategy="private_research")
|
| 23 |
|
| 24 |
assert decision.primary is not None
|
| 25 |
+
assert decision.primary.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
| 26 |
assert decision.primary.pinned is False
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
def test_public_private_taste_judge_respects_license_and_budget() -> None:
|
|
|
|
| 136 |
assert relay.records["netlify-ai-gateway-helper"].provider == "netlify"
|
| 137 |
assert relay.records["cloudflare-agent-helper"].provider == "cloudflare"
|
| 138 |
assert relay.records["fal-media-adapter"].provider == "fal"
|
|
|
|
|
|
|
| 139 |
assert relay.records["netflix-void-modal"].health == "healthy"
|
| 140 |
assert relay.records["netlify-ai-gateway-helper"].health == "excluded"
|
| 141 |
assert relay.records["fal-media-adapter"].health == "excluded"
|
|
|
|
| 185 |
assert "private_image_research" in ROTATABLE_LANES
|
| 186 |
|
| 187 |
|
| 188 |
+
def test_flux2_klein_9b_is_pinned_with_4b_sidecar_fallback() -> None:
|
| 189 |
relay = WeaverModelRelay()
|
| 190 |
|
| 191 |
record = relay.records["flux2-klein-9b-quality"]
|
| 192 |
+
fallback = relay.records["flux2-klein-4b-sidecar"]
|
| 193 |
|
| 194 |
assert record.lane == "image_generation"
|
| 195 |
assert record.pinned is True
|
| 196 |
assert record.params_b == 9.0
|
| 197 |
assert record.license_gate == "review_required"
|
| 198 |
assert record.repo_id == "black-forest-labs/FLUX.2-klein-9B"
|
| 199 |
+
assert "flux2-klein-4b-sidecar" in record.fallback_chain
|
| 200 |
+
assert fallback.repo_id == "black-forest-labs/FLUX.2-klein-4B"
|
| 201 |
+
assert fallback.pinned is False
|
| 202 |
|
| 203 |
|
| 204 |
+
def test_flux2_klein_9b_is_not_pinned_and_in_private_research() -> None:
|
| 205 |
relay = WeaverModelRelay()
|
| 206 |
|
| 207 |
+
record = relay.records["flux2-klein-9b-private"]
|
| 208 |
|
| 209 |
+
assert record.lane == "private_image_research"
|
| 210 |
assert record.pinned is False
|
| 211 |
+
assert record.params_b == 9.0
|
| 212 |
+
assert record.license_gate == "review_required"
|
| 213 |
|
| 214 |
|
| 215 |
def test_minicpm_has_fallback_chain_configured() -> None:
|