specimba commited on
Commit
b41f3a7
·
verified ·
1 Parent(s): 3aae80c

Wire command center operator actions

Browse files
app.py CHANGED
@@ -44,6 +44,15 @@ DEFAULT_PROMPT = (
44
  MODEL_RELAY = WeaverModelRelay()
45
 
46
 
 
 
 
 
 
 
 
 
 
47
  def _zero_gpu_entrypoint(fn: Any) -> Any:
48
  """Expose one callback to ZeroGPU without making local development depend on Spaces."""
49
  gpu_decorator = getattr(spaces, "GPU", None) if spaces is not None else None
@@ -73,6 +82,7 @@ def _dashboard_regions(
73
  adult_mode: bool = False,
74
  scan: dict[str, Any] | None = None,
75
  active_section: str = "Forge",
 
76
  ) -> dict[str, str]:
77
  return render_dashboard_regions(
78
  run=run,
@@ -80,6 +90,7 @@ def _dashboard_regions(
80
  scan=scan,
81
  relay_status=_relay_snapshot(adult_mode),
82
  active_section=active_section,
 
83
  )
84
 
85
 
@@ -91,7 +102,25 @@ def run_weave(
91
  adult_mode: bool,
92
  upload: Any,
93
  active_section: str,
94
- ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any]]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  prompt = prompt.strip() or DEFAULT_PROMPT
96
  run = build_command_center_run(
97
  prompt=prompt,
@@ -100,7 +129,19 @@ def run_weave(
100
  adult_mode=adult_mode,
101
  )
102
  scan = scan_file(_file_path(upload))
103
- regions = _dashboard_regions(run=run, adult_mode=adult_mode, scan=scan, active_section=active_section)
 
 
 
 
 
 
 
 
 
 
 
 
104
  catalog = render_catalog_table(adult_mode=adult_mode)
105
  return (
106
  regions["topbar"],
@@ -116,6 +157,10 @@ def run_weave(
116
  run.to_dict(),
117
  catalog_summary(adult_mode),
118
  scan,
 
 
 
 
119
  )
120
 
121
 
@@ -123,9 +168,13 @@ def toggle_adult_visibility(
123
  adult_mode: bool,
124
  active_section: str,
125
  upload: Any,
126
- ) -> tuple[str, str, str, str, str, str, str, dict[str, Any], dict[str, Any]]:
127
  scan = scan_file(_file_path(upload))
128
- regions = _dashboard_regions(adult_mode=adult_mode, scan=scan, active_section=active_section)
 
 
 
 
129
  return (
130
  regions["topbar"],
131
  regions["command_rail"],
@@ -136,22 +185,172 @@ def toggle_adult_visibility(
136
  render_catalog_table(adult_mode=adult_mode),
137
  catalog_summary(adult_mode),
138
  scan,
 
139
  )
140
 
141
 
142
  def refresh_section(
143
  active_section: str,
144
  adult_mode: bool,
145
- upload: Any,
 
 
146
  ) -> tuple[str, str, str, str, str, dict[str, Any]]:
147
- scan = scan_file(_file_path(upload))
148
- regions = _dashboard_regions(adult_mode=adult_mode, scan=scan, active_section=active_section)
 
 
 
 
 
 
149
  return regions["command_rail"], regions["operations"], regions["inspector"], regions["artifacts"], regions["providers"], scan
150
 
151
 
152
- initial_regions = _dashboard_regions(scan=scan_file(None))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
  with gr.Blocks(title="NEXUS Visual Weaver") as demo:
 
 
 
155
  topbar_html = gr.HTML(initial_regions["topbar"], container=False)
156
 
157
  with gr.Group(elem_id="nw-inputs", elem_classes=["nw-control-panel"]):
@@ -190,6 +389,11 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
190
  )
191
  run_btn = gr.Button("Run Active Weave", variant="primary", scale=1)
192
  stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
 
 
 
 
 
193
 
194
  with gr.Row(elem_id="nw-workspace", elem_classes=["nw-workspace"]):
195
  with gr.Column(scale=1, min_width=150, elem_id="nw-native-rail"):
@@ -218,44 +422,36 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
218
  catalog_json = gr.JSON(label="Catalog Summary")
219
  scan_json = gr.JSON(label="ST3GG Scan")
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  run_btn.click(
222
  fn=run_weave,
223
  inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
224
- outputs=[
225
- topbar_html,
226
- command_rail_html,
227
- workflow_html,
228
- operations_html,
229
- inspector_html,
230
- drawer_html,
231
- status_html,
232
- artifact_html,
233
- provider_html,
234
- catalog_html,
235
- run_json,
236
- catalog_json,
237
- scan_json,
238
- ],
239
  api_name="run_active_weave",
240
  )
241
  prompt.submit(
242
  fn=run_weave,
243
  inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
244
- outputs=[
245
- topbar_html,
246
- command_rail_html,
247
- workflow_html,
248
- operations_html,
249
- inspector_html,
250
- drawer_html,
251
- status_html,
252
- artifact_html,
253
- provider_html,
254
- catalog_html,
255
- run_json,
256
- catalog_json,
257
- scan_json,
258
- ],
259
  api_name=False,
260
  )
261
  adult_mode.change(
@@ -271,18 +467,49 @@ with gr.Blocks(title="NEXUS Visual Weaver") as demo:
271
  catalog_html,
272
  catalog_json,
273
  scan_json,
 
274
  ],
275
  api_name="toggle_adult_catalog",
276
  )
277
  section_nav.change(
278
  fn=refresh_section,
279
- inputs=[section_nav, adult_mode, upload],
280
  outputs=[command_rail_html, operations_html, inspector_html, artifact_html, provider_html, scan_json],
281
  api_name=False,
282
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  demo.load(
284
- fn=lambda: (render_catalog_table(False), catalog_summary(False), scan_file(None)),
285
- outputs=[catalog_html, catalog_json, scan_json],
286
  api_name=False,
287
  )
288
 
 
44
  MODEL_RELAY = WeaverModelRelay()
45
 
46
 
47
+ def _default_operator_state() -> dict[str, Any]:
48
+ return {
49
+ "provider_state": "idle",
50
+ "checkpoint": "pending",
51
+ "export": "pending",
52
+ "message": "No operator action yet.",
53
+ }
54
+
55
+
56
  def _zero_gpu_entrypoint(fn: Any) -> Any:
57
  """Expose one callback to ZeroGPU without making local development depend on Spaces."""
58
  gpu_decorator = getattr(spaces, "GPU", None) if spaces is not None else None
 
82
  adult_mode: bool = False,
83
  scan: dict[str, Any] | None = None,
84
  active_section: str = "Forge",
85
+ operator_state: dict[str, Any] | None = None,
86
  ) -> dict[str, str]:
87
  return render_dashboard_regions(
88
  run=run,
 
90
  scan=scan,
91
  relay_status=_relay_snapshot(adult_mode),
92
  active_section=active_section,
93
+ operator_state=operator_state,
94
  )
95
 
96
 
 
102
  adult_mode: bool,
103
  upload: Any,
104
  active_section: str,
105
+ ) -> tuple[
106
+ str,
107
+ str,
108
+ str,
109
+ str,
110
+ str,
111
+ str,
112
+ str,
113
+ str,
114
+ str,
115
+ str,
116
+ dict[str, Any],
117
+ dict[str, Any],
118
+ dict[str, Any],
119
+ Any,
120
+ dict[str, Any],
121
+ dict[str, Any],
122
+ Any,
123
+ ]:
124
  prompt = prompt.strip() or DEFAULT_PROMPT
125
  run = build_command_center_run(
126
  prompt=prompt,
 
129
  adult_mode=adult_mode,
130
  )
131
  scan = scan_file(_file_path(upload))
132
+ operator_state = {
133
+ "provider_state": "checkpointed",
134
+ "checkpoint": "pending_review",
135
+ "export": scan.get("export_gate", "pending"),
136
+ "message": "Run packet generated. Human checkpoint required before provider promotion or export.",
137
+ }
138
+ regions = _dashboard_regions(
139
+ run=run,
140
+ adult_mode=adult_mode,
141
+ scan=scan,
142
+ active_section=active_section,
143
+ operator_state=operator_state,
144
+ )
145
  catalog = render_catalog_table(adult_mode=adult_mode)
146
  return (
147
  regions["topbar"],
 
157
  run.to_dict(),
158
  catalog_summary(adult_mode),
159
  scan,
160
+ run,
161
+ scan,
162
+ operator_state,
163
+ gr.update(interactive=True),
164
  )
165
 
166
 
 
168
  adult_mode: bool,
169
  active_section: str,
170
  upload: Any,
171
+ ) -> tuple[str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any]]:
172
  scan = scan_file(_file_path(upload))
173
+ operator_state = {
174
+ **_default_operator_state(),
175
+ "message": "Adult catalog visibility changed. ST3GG, consent, and export gates remain active.",
176
+ }
177
+ regions = _dashboard_regions(adult_mode=adult_mode, scan=scan, active_section=active_section, operator_state=operator_state)
178
  return (
179
  regions["topbar"],
180
  regions["command_rail"],
 
185
  render_catalog_table(adult_mode=adult_mode),
186
  catalog_summary(adult_mode),
187
  scan,
188
+ operator_state,
189
  )
190
 
191
 
192
  def refresh_section(
193
  active_section: str,
194
  adult_mode: bool,
195
+ run: Any | None,
196
+ scan: dict[str, Any] | None,
197
+ operator_state: dict[str, Any] | None,
198
  ) -> tuple[str, str, str, str, str, dict[str, Any]]:
199
+ scan = scan or scan_file(None)
200
+ regions = _dashboard_regions(
201
+ run=run,
202
+ adult_mode=adult_mode,
203
+ scan=scan,
204
+ active_section=active_section,
205
+ operator_state=operator_state or _default_operator_state(),
206
+ )
207
  return regions["command_rail"], regions["operations"], regions["inspector"], regions["artifacts"], regions["providers"], scan
208
 
209
 
210
+ def _render_stateful(
211
+ run: Any | None,
212
+ adult_mode: bool,
213
+ scan: dict[str, Any] | None,
214
+ active_section: str,
215
+ operator_state: dict[str, Any],
216
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], Any]:
217
+ scan = scan or scan_file(None)
218
+ regions = _dashboard_regions(
219
+ run=run,
220
+ adult_mode=adult_mode,
221
+ scan=scan,
222
+ active_section=active_section,
223
+ operator_state=operator_state,
224
+ )
225
+ return (
226
+ regions["topbar"],
227
+ regions["command_rail"],
228
+ regions["workflow"],
229
+ regions["operations"],
230
+ regions["inspector"],
231
+ regions["drawer"],
232
+ regions["status"],
233
+ regions["artifacts"],
234
+ regions["providers"],
235
+ render_catalog_table(adult_mode=adult_mode),
236
+ run.to_dict() if hasattr(run, "to_dict") else {},
237
+ catalog_summary(adult_mode),
238
+ scan,
239
+ operator_state,
240
+ gr.update(interactive=run is not None and operator_state.get("provider_state") not in {"idle", "stopped", "exported"}),
241
+ )
242
+
243
+
244
+ def scan_reference(
245
+ run: Any | None,
246
+ adult_mode: bool,
247
+ upload: Any,
248
+ active_section: str,
249
+ operator_state: dict[str, Any] | None,
250
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], Any, dict[str, Any]]:
251
+ scan = scan_file(_file_path(upload))
252
+ next_state = {
253
+ **(operator_state or _default_operator_state()),
254
+ "export": scan.get("export_gate", "pending"),
255
+ "message": "Reference scan complete. Export gate is clear." if scan.get("export_gate") == "clear" else "Reference scan requires review before export.",
256
+ }
257
+ rendered = _render_stateful(run, adult_mode, scan, active_section, next_state)
258
+ return (*rendered, scan)
259
+
260
+
261
+ def approve_checkpoint(
262
+ run: Any | None,
263
+ adult_mode: bool,
264
+ scan: dict[str, Any] | None,
265
+ active_section: str,
266
+ operator_state: dict[str, Any] | None,
267
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], Any]:
268
+ scan = scan or scan_file(None)
269
+ if run is None:
270
+ next_state = {**_default_operator_state(), "provider_state": "blocked", "message": "No run exists yet. Run Active Weave first."}
271
+ else:
272
+ export_state = scan.get("export_gate", "pending")
273
+ next_state = {
274
+ **(operator_state or _default_operator_state()),
275
+ "provider_state": "export_ready" if export_state == "clear" else "checkpointed",
276
+ "checkpoint": "approved",
277
+ "export": export_state,
278
+ "message": "Checkpoint approved. Export is ready after clear ST3GG scan." if export_state == "clear" else "Checkpoint approved, but export still waits on ST3GG review.",
279
+ }
280
+ return _render_stateful(run, adult_mode, scan, active_section, next_state)
281
+
282
+
283
+ def export_packet(
284
+ run: Any | None,
285
+ adult_mode: bool,
286
+ scan: dict[str, Any] | None,
287
+ active_section: str,
288
+ operator_state: dict[str, Any] | None,
289
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], Any]:
290
+ scan = scan or scan_file(None)
291
+ state = operator_state or _default_operator_state()
292
+ if run is None:
293
+ next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: no active run packet exists."}
294
+ elif state.get("checkpoint") != "approved":
295
+ next_state = {**state, "provider_state": "blocked", "export": "blocked", "message": "Export blocked: human checkpoint has not been approved."}
296
+ elif scan.get("export_gate") != "clear":
297
+ next_state = {**state, "provider_state": "blocked", "export": scan.get("export_gate", "blocked"), "message": "Export blocked: ST3GG gate is not clear."}
298
+ else:
299
+ next_state = {**state, "provider_state": "exported", "export": "clear", "message": "Governed export packet prepared with run, catalog, and ST3GG evidence."}
300
+ return _render_stateful(run, adult_mode, scan, active_section, next_state)
301
+
302
+
303
+ def stop_provider_job(
304
+ run: Any | None,
305
+ adult_mode: bool,
306
+ scan: dict[str, Any] | None,
307
+ active_section: str,
308
+ operator_state: dict[str, Any] | None,
309
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], dict[str, Any], Any]:
310
+ scan = scan or scan_file(None)
311
+ next_state = {
312
+ **(operator_state or _default_operator_state()),
313
+ "provider_state": "stopped",
314
+ "message": "Provider handoff stopped. Local dry-run packet and evidence remain available.",
315
+ }
316
+ return _render_stateful(run, adult_mode, scan, active_section, next_state)
317
+
318
+
319
+ def reset_demo(
320
+ adult_mode: bool,
321
+ active_section: str,
322
+ ) -> tuple[str, str, str, str, str, str, str, str, str, str, dict[str, Any], dict[str, Any], dict[str, Any], None, dict[str, Any], dict[str, Any], Any]:
323
+ scan = scan_file(None)
324
+ operator_state = _default_operator_state()
325
+ regions = _dashboard_regions(adult_mode=adult_mode, scan=scan, active_section=active_section, operator_state=operator_state)
326
+ return (
327
+ regions["topbar"],
328
+ regions["command_rail"],
329
+ regions["workflow"],
330
+ regions["operations"],
331
+ regions["inspector"],
332
+ regions["drawer"],
333
+ regions["status"],
334
+ regions["artifacts"],
335
+ regions["providers"],
336
+ render_catalog_table(adult_mode=adult_mode),
337
+ {},
338
+ catalog_summary(adult_mode),
339
+ scan,
340
+ None,
341
+ scan,
342
+ operator_state,
343
+ gr.update(interactive=False),
344
+ )
345
+
346
+
347
+ initial_operator_state = _default_operator_state()
348
+ initial_regions = _dashboard_regions(scan=scan_file(None), operator_state=initial_operator_state)
349
 
350
  with gr.Blocks(title="NEXUS Visual Weaver") as demo:
351
+ active_run_state = gr.State(None)
352
+ scan_state = gr.State(scan_file(None))
353
+ operator_state = gr.State(initial_operator_state)
354
  topbar_html = gr.HTML(initial_regions["topbar"], container=False)
355
 
356
  with gr.Group(elem_id="nw-inputs", elem_classes=["nw-control-panel"]):
 
389
  )
390
  run_btn = gr.Button("Run Active Weave", variant="primary", scale=1)
391
  stop_btn = gr.Button("Stop Provider Job", variant="stop", interactive=False, scale=1)
392
+ with gr.Row(elem_id="nw-operator-actions", elem_classes=["nw-operator-actions"]):
393
+ scan_btn = gr.Button("Scan Reference", scale=1)
394
+ checkpoint_btn = gr.Button("Approve Checkpoint", scale=1)
395
+ export_btn = gr.Button("Prepare Export Packet", scale=1)
396
+ reset_btn = gr.Button("Reset Demo State", scale=1)
397
 
398
  with gr.Row(elem_id="nw-workspace", elem_classes=["nw-workspace"]):
399
  with gr.Column(scale=1, min_width=150, elem_id="nw-native-rail"):
 
422
  catalog_json = gr.JSON(label="Catalog Summary")
423
  scan_json = gr.JSON(label="ST3GG Scan")
424
 
425
+ dashboard_outputs = [
426
+ topbar_html,
427
+ command_rail_html,
428
+ workflow_html,
429
+ operations_html,
430
+ inspector_html,
431
+ drawer_html,
432
+ status_html,
433
+ artifact_html,
434
+ provider_html,
435
+ catalog_html,
436
+ run_json,
437
+ catalog_json,
438
+ scan_json,
439
+ ]
440
+
441
+ stateful_outputs = dashboard_outputs + [active_run_state, scan_state, operator_state, stop_btn]
442
+
443
+ operator_outputs = dashboard_outputs + [operator_state, stop_btn]
444
+
445
  run_btn.click(
446
  fn=run_weave,
447
  inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
448
+ outputs=stateful_outputs,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  api_name="run_active_weave",
450
  )
451
  prompt.submit(
452
  fn=run_weave,
453
  inputs=[prompt, reasoning_mode, video_preset, adult_mode, upload, section_nav],
454
+ outputs=stateful_outputs,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  api_name=False,
456
  )
457
  adult_mode.change(
 
467
  catalog_html,
468
  catalog_json,
469
  scan_json,
470
+ operator_state,
471
  ],
472
  api_name="toggle_adult_catalog",
473
  )
474
  section_nav.change(
475
  fn=refresh_section,
476
+ inputs=[section_nav, adult_mode, active_run_state, scan_state, operator_state],
477
  outputs=[command_rail_html, operations_html, inspector_html, artifact_html, provider_html, scan_json],
478
  api_name=False,
479
  )
480
+ scan_btn.click(
481
+ fn=scan_reference,
482
+ inputs=[active_run_state, adult_mode, upload, section_nav, operator_state],
483
+ outputs=dashboard_outputs + [operator_state, stop_btn, scan_state],
484
+ api_name="scan_reference",
485
+ )
486
+ checkpoint_btn.click(
487
+ fn=approve_checkpoint,
488
+ inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
489
+ outputs=operator_outputs,
490
+ api_name="approve_checkpoint",
491
+ )
492
+ export_btn.click(
493
+ fn=export_packet,
494
+ inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
495
+ outputs=operator_outputs,
496
+ api_name="prepare_export_packet",
497
+ )
498
+ stop_btn.click(
499
+ fn=stop_provider_job,
500
+ inputs=[active_run_state, adult_mode, scan_state, section_nav, operator_state],
501
+ outputs=operator_outputs,
502
+ api_name="stop_provider_job",
503
+ )
504
+ reset_btn.click(
505
+ fn=reset_demo,
506
+ inputs=[adult_mode, section_nav],
507
+ outputs=stateful_outputs,
508
+ api_name="reset_demo_state",
509
+ )
510
  demo.load(
511
+ fn=lambda: (render_catalog_table(False), catalog_summary(False), scan_file(None), scan_file(None), _default_operator_state()),
512
+ outputs=[catalog_html, catalog_json, scan_json, scan_state, operator_state],
513
  api_name=False,
514
  )
515
 
src/nexus_visual_weaver/render.py CHANGED
@@ -137,13 +137,20 @@ def render_command_rail(active_section: str = "Forge") -> str:
137
  """
138
 
139
 
140
- def render_workflow(run: GenerationRun | None = None) -> str:
 
141
  workflow = WorkflowState.default()
142
  score = run.checkpoint.trust_score if run else 0.82
143
  checkpoint_id = run.checkpoint.checkpoint_id if run else "nw-dry-run"
144
- recommendation = run.checkpoint.recommendation.replace("_", " ").title() if run else "Awaiting Run"
 
 
145
  required_actions = run.checkpoint.required_actions if run else ["Review candidate thumbnails before promotion"]
146
  action_label = required_actions[0] if required_actions else "No action pending"
 
 
 
 
147
  model_label = _short_repo(run.model_stack[0].repo_id) if run and run.model_stack else "FLUX.2"
148
  locate_label = run.inspection.locate_model.split("/")[-1] if run else "LocateAnything-3B"
149
  nodes = {
@@ -210,13 +217,13 @@ def render_workflow(run: GenerationRun | None = None) -> str:
210
  {"".join(cards)}
211
  </svg>
212
  <div class="nw-legend">
213
- {badge("Text Flow", "accent")} {badge("Refine Loop", "violet")} {badge("Policy Gate", "blue")} {badge("Media Flow", "cyan")} {badge("Human Gate", "warn")}
214
  </div>
215
  <div class="nw-weave-console">
216
  <div class="nw-console-card nw-console-primary">
217
  <small>Selected Node</small>
218
  <strong>Human Checkpoint</strong>
219
- <span>{escape(recommendation)} / {escape(checkpoint_id)}</span>
220
  </div>
221
  <div class="nw-console-card">
222
  <small>Next Operator Action</small>
@@ -238,20 +245,31 @@ def render_workflow(run: GenerationRun | None = None) -> str:
238
  """
239
 
240
 
241
- def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = None) -> str:
242
  scan = scan or {"status": "idle", "export_gate": "pending"}
 
243
  prompt_label = "Prompt proof"
244
  outfit_label = "Outfit map"
245
  locate_label = "Grounding overlay"
246
  video_label = run.video.preset if run else "Video path"
247
  active_prompt = run.refined_prompt.refined[:150] if run else "Awaiting first weave. The preview stage shows dry-run handoff packets until provider output exists."
248
- checkpoint = getattr(run.checkpoint, "recommendation", "pending") if run else "pending"
 
 
 
 
 
 
 
 
 
 
249
  demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
250
  artifacts = [
251
  (prompt_label, "Taste-refined brief", "dry-run", "material-0", "01"),
252
  (outfit_label, "Wardrobe slots and locks", "checkpointed", "material-1", "02"),
253
  (locate_label, "LocateAnything region plan", "configured", "material-4", "03"),
254
- (video_label, "Checkpointed storyboard", "blocked" if scan.get("export_gate") == "blocked" else "ready", "story-2", "04"),
255
  ]
256
  cards = "".join(
257
  f"""
@@ -285,13 +303,13 @@ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = N
285
  <div class="nw-preview-meta">
286
  <div><small>checkpoint</small><strong>{escape(str(checkpoint).replace("_", " ").title())}</strong></div>
287
  <div><small>export gate</small><strong>{escape(export_gate)}</strong></div>
288
- <div><small>preview mode</small><strong>Dry Run</strong></div>
289
  </div>
290
  </div>
291
  <div class="nw-preview-ribbon">
292
  <span>{icon("security")} ST3GG before export</span>
293
  <span>{icon("wardrobe")} continuity: {escape(continuity)}</span>
294
- <span>{icon("models")} provider call remains checkpointed; state: dry-run / configured / blocked / failed</span>
295
  </div>
296
  <div class="nw-artifact-grid">{cards}</div>
297
  </section>
@@ -305,9 +323,11 @@ def render_operations_panel(
305
  relay_status: dict | None = None,
306
  *,
307
  adult_mode: bool = False,
 
308
  ) -> str:
309
  scan = scan or {"status": "idle", "export_gate": "pending", "findings": []}
310
  relay_status = relay_status or {}
 
311
  section = active_section if active_section in {"Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"} else "Forge"
312
  checkpoint = getattr(run, "checkpoint", None) if run else None
313
  outfit = getattr(run, "outfit", None) if run else None
@@ -317,6 +337,8 @@ def render_operations_panel(
317
  lore_count = len(getattr(lore, "beats", []) or [])
318
  scan_status = str(scan.get("status", "idle")).upper()
319
  export_gate = str(scan.get("export_gate", "pending")).upper()
 
 
320
  decisions = relay_status.get("decisions", [])
321
  first_decision = decisions[0] if decisions else {}
322
  first_primary = (first_decision.get("primary") or {}) if first_decision else {}
@@ -325,7 +347,7 @@ def render_operations_panel(
325
  "Forge": [
326
  ("Prompt contract", "Taste-refined prompt, material locks, negative purge, and checkpoint requirements."),
327
  ("Active run", f"{run_id} / checkpoint remains human-reviewed before video promotion."),
328
- ("Provider posture", "Dry-run packets are visible before paid or gated calls."),
329
  ],
330
  "Wardrobe": [
331
  ("Slot coverage", f"{outfit_count or 9} garment/accessory regions tracked with locks and edit priority."),
@@ -353,7 +375,7 @@ def render_operations_panel(
353
  ],
354
  "Runs": [
355
  ("Current checkpoint", run_id),
356
- ("Ledger mode", "Run JSON, catalog summary, and ST3GG evidence remain in the evidence accordion."),
357
  ("Rollback path", "Feature branches and draft PRs carry implementation checkpoints."),
358
  ],
359
  }
@@ -593,8 +615,11 @@ def render_drawer(run: GenerationRun | None = None) -> str:
593
  """
594
 
595
 
596
- def render_status_bar() -> str:
597
  space = _space_runtime_status()
 
 
 
598
  return f"""
599
  <footer class="nw-statusbar">
600
  {_metric("Runs", "112")}
@@ -604,7 +629,7 @@ def render_status_bar() -> str:
604
  {_metric("Temp", "62 C")}
605
  {_metric("HF Space", space["hardware"])}
606
  <div class="nw-autosave"><span class="nw-live-dot"></span><strong>Auto-save</strong><small>On</small></div>
607
- <div class="nw-stop nw-stop-idle">No live provider job</div>
608
  </footer>
609
  """
610
 
@@ -637,8 +662,9 @@ def render_dashboard(
637
  scan: dict | None = None,
638
  relay_status: dict | None = None,
639
  active_section: str = "Forge",
 
640
  ) -> str:
641
- regions = render_dashboard_regions(run, adult_mode, scan, relay_status, active_section)
642
  return f"""
643
  <div class="nw-app">
644
  {regions["topbar"]}
@@ -666,16 +692,17 @@ def render_dashboard_regions(
666
  scan: dict | None = None,
667
  relay_status: dict | None = None,
668
  active_section: str = "Forge",
 
669
  ) -> dict[str, str]:
670
  return {
671
  "topbar": render_topbar(adult_mode, relay_status),
672
  "rail": render_left_rail(active_section),
673
  "command_rail": render_command_rail(active_section),
674
- "workflow": render_workflow(run),
675
- "operations": render_operations_panel(active_section, run, scan, relay_status, adult_mode=adult_mode),
676
  "inspector": render_inspector(run, scan, relay_status),
677
  "drawer": render_drawer(run),
678
- "status": render_status_bar(),
679
- "artifacts": render_artifact_lane(run, scan),
680
  "providers": render_provider_cards(relay_status, adult_mode),
681
  }
 
137
  """
138
 
139
 
140
+ def render_workflow(run: GenerationRun | None = None, operator_state: dict | None = None) -> str:
141
+ operator_state = operator_state or {}
142
  workflow = WorkflowState.default()
143
  score = run.checkpoint.trust_score if run else 0.82
144
  checkpoint_id = run.checkpoint.checkpoint_id if run else "nw-dry-run"
145
+ checkpoint_status = str(operator_state.get("checkpoint", "pending_review" if run else "pending"))
146
+ provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
147
+ recommendation = operator_state.get("message") or (run.checkpoint.recommendation.replace("_", " ").title() if run else "Awaiting Run")
148
  required_actions = run.checkpoint.required_actions if run else ["Review candidate thumbnails before promotion"]
149
  action_label = required_actions[0] if required_actions else "No action pending"
150
+ if checkpoint_status == "approved":
151
+ action_label = "Checkpoint approved; export packet may be prepared after ST3GG gate."
152
+ elif provider_state == "stopped":
153
+ action_label = "Provider handoff stopped; dry-run evidence remains available."
154
  model_label = _short_repo(run.model_stack[0].repo_id) if run and run.model_stack else "FLUX.2"
155
  locate_label = run.inspection.locate_model.split("/")[-1] if run else "LocateAnything-3B"
156
  nodes = {
 
217
  {"".join(cards)}
218
  </svg>
219
  <div class="nw-legend">
220
+ {badge("Text Flow", "accent")} {badge("Refine Loop", "violet")} {badge("Policy Gate", "blue")} {badge("Media Flow", "cyan")} {badge("Human Gate", "warn")} {badge(provider_state.replace("_", " ").upper(), "pass" if provider_state == "exported" else "warn" if provider_state in {"blocked", "stopped"} else "muted")}
221
  </div>
222
  <div class="nw-weave-console">
223
  <div class="nw-console-card nw-console-primary">
224
  <small>Selected Node</small>
225
  <strong>Human Checkpoint</strong>
226
+ <span>{escape(str(recommendation))} / {escape(checkpoint_id)}</span>
227
  </div>
228
  <div class="nw-console-card">
229
  <small>Next Operator Action</small>
 
245
  """
246
 
247
 
248
+ def render_artifact_lane(run: GenerationRun | None = None, scan: dict | None = None, operator_state: dict | None = None) -> str:
249
  scan = scan or {"status": "idle", "export_gate": "pending"}
250
+ operator_state = operator_state or {}
251
  prompt_label = "Prompt proof"
252
  outfit_label = "Outfit map"
253
  locate_label = "Grounding overlay"
254
  video_label = run.video.preset if run else "Video path"
255
  active_prompt = run.refined_prompt.refined[:150] if run else "Awaiting first weave. The preview stage shows dry-run handoff packets until provider output exists."
256
+ checkpoint = operator_state.get("checkpoint", getattr(run.checkpoint, "recommendation", "pending") if run else "pending")
257
+ provider_state = str(operator_state.get("provider_state", "dry-run" if run else "idle"))
258
+ preview_mode = {
259
+ "idle": "Idle",
260
+ "dry-run": "Dry Run",
261
+ "checkpointed": "Checkpointed",
262
+ "export_ready": "Export Ready",
263
+ "exported": "Exported",
264
+ "blocked": "Blocked",
265
+ "stopped": "Stopped",
266
+ }.get(provider_state, provider_state.replace("_", " ").title())
267
  demo_seed = (run.checkpoint.checkpoint_id[-4:] if run else "0000").upper()
268
  artifacts = [
269
  (prompt_label, "Taste-refined brief", "dry-run", "material-0", "01"),
270
  (outfit_label, "Wardrobe slots and locks", "checkpointed", "material-1", "02"),
271
  (locate_label, "LocateAnything region plan", "configured", "material-4", "03"),
272
+ (video_label, "Checkpointed storyboard", "blocked" if scan.get("export_gate") == "blocked" or provider_state == "blocked" else "ready", "story-2", "04"),
273
  ]
274
  cards = "".join(
275
  f"""
 
303
  <div class="nw-preview-meta">
304
  <div><small>checkpoint</small><strong>{escape(str(checkpoint).replace("_", " ").title())}</strong></div>
305
  <div><small>export gate</small><strong>{escape(export_gate)}</strong></div>
306
+ <div><small>preview mode</small><strong>{escape(preview_mode)}</strong></div>
307
  </div>
308
  </div>
309
  <div class="nw-preview-ribbon">
310
  <span>{icon("security")} ST3GG before export</span>
311
  <span>{icon("wardrobe")} continuity: {escape(continuity)}</span>
312
+ <span>{icon("models")} provider call remains checkpointed; state: dry-run / configured / blocked / failed / exported; current: {escape(provider_state)}</span>
313
  </div>
314
  <div class="nw-artifact-grid">{cards}</div>
315
  </section>
 
323
  relay_status: dict | None = None,
324
  *,
325
  adult_mode: bool = False,
326
+ operator_state: dict | None = None,
327
  ) -> str:
328
  scan = scan or {"status": "idle", "export_gate": "pending", "findings": []}
329
  relay_status = relay_status or {}
330
+ operator_state = operator_state or {}
331
  section = active_section if active_section in {"Forge", "Wardrobe", "Lore", "Models", "Security", "Runs"} else "Forge"
332
  checkpoint = getattr(run, "checkpoint", None) if run else None
333
  outfit = getattr(run, "outfit", None) if run else None
 
337
  lore_count = len(getattr(lore, "beats", []) or [])
338
  scan_status = str(scan.get("status", "idle")).upper()
339
  export_gate = str(scan.get("export_gate", "pending")).upper()
340
+ provider_state = str(operator_state.get("provider_state", "idle")).replace("_", " ").upper()
341
+ operator_message = str(operator_state.get("message", "No operator action yet."))
342
  decisions = relay_status.get("decisions", [])
343
  first_decision = decisions[0] if decisions else {}
344
  first_primary = (first_decision.get("primary") or {}) if first_decision else {}
 
347
  "Forge": [
348
  ("Prompt contract", "Taste-refined prompt, material locks, negative purge, and checkpoint requirements."),
349
  ("Active run", f"{run_id} / checkpoint remains human-reviewed before video promotion."),
350
+ ("Provider posture", f"{provider_state}: {operator_message}"),
351
  ],
352
  "Wardrobe": [
353
  ("Slot coverage", f"{outfit_count or 9} garment/accessory regions tracked with locks and edit priority."),
 
375
  ],
376
  "Runs": [
377
  ("Current checkpoint", run_id),
378
+ ("Ledger mode", f"Operator state: {provider_state}. Run JSON, catalog summary, and ST3GG evidence remain in the evidence accordion."),
379
  ("Rollback path", "Feature branches and draft PRs carry implementation checkpoints."),
380
  ],
381
  }
 
615
  """
616
 
617
 
618
+ def render_status_bar(operator_state: dict | None = None) -> str:
619
  space = _space_runtime_status()
620
+ operator_state = operator_state or {}
621
+ provider_state = str(operator_state.get("provider_state", "idle")).replace("_", " ").title()
622
+ stop_class = "nw-stop-idle" if provider_state == "Idle" else "nw-stop-active"
623
  return f"""
624
  <footer class="nw-statusbar">
625
  {_metric("Runs", "112")}
 
629
  {_metric("Temp", "62 C")}
630
  {_metric("HF Space", space["hardware"])}
631
  <div class="nw-autosave"><span class="nw-live-dot"></span><strong>Auto-save</strong><small>On</small></div>
632
+ <div class="nw-stop {stop_class}">{escape(provider_state)}</div>
633
  </footer>
634
  """
635
 
 
662
  scan: dict | None = None,
663
  relay_status: dict | None = None,
664
  active_section: str = "Forge",
665
+ operator_state: dict | None = None,
666
  ) -> str:
667
+ regions = render_dashboard_regions(run, adult_mode, scan, relay_status, active_section, operator_state)
668
  return f"""
669
  <div class="nw-app">
670
  {regions["topbar"]}
 
692
  scan: dict | None = None,
693
  relay_status: dict | None = None,
694
  active_section: str = "Forge",
695
+ operator_state: dict | None = None,
696
  ) -> dict[str, str]:
697
  return {
698
  "topbar": render_topbar(adult_mode, relay_status),
699
  "rail": render_left_rail(active_section),
700
  "command_rail": render_command_rail(active_section),
701
+ "workflow": render_workflow(run, operator_state),
702
+ "operations": render_operations_panel(active_section, run, scan, relay_status, adult_mode=adult_mode, operator_state=operator_state),
703
  "inspector": render_inspector(run, scan, relay_status),
704
  "drawer": render_drawer(run),
705
+ "status": render_status_bar(operator_state),
706
+ "artifacts": render_artifact_lane(run, scan, operator_state),
707
  "providers": render_provider_cards(relay_status, adult_mode),
708
  }
src/nexus_visual_weaver/styles.py CHANGED
@@ -482,6 +482,28 @@ footer { display: none !important; }
482
  background: linear-gradient(180deg, #ff3b62, #c51a3b) !important;
483
  border-color: rgba(255,54,95,.58) !important;
484
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  .nw-control-panel {
486
  margin: 8px 8px 10px 8px;
487
  padding: 12px;
@@ -852,6 +874,10 @@ footer { display: none !important; }
852
  background: rgba(255,255,255,.025);
853
  color: var(--nw-muted);
854
  }
 
 
 
 
855
  @media (max-width: 1100px) {
856
  .nw-topbar { grid-template-columns: 1fr; }
857
  .nw-shell { grid-template-columns: 1fr; grid-template-rows: auto; }
 
482
  background: linear-gradient(180deg, #ff3b62, #c51a3b) !important;
483
  border-color: rgba(255,54,95,.58) !important;
484
  }
485
+ #nw-operator-actions {
486
+ margin-top: 10px;
487
+ padding-top: 10px;
488
+ border-top: 1px solid rgba(255,255,255,.06);
489
+ gap: 8px !important;
490
+ }
491
+ #nw-operator-actions button {
492
+ min-height: 34px !important;
493
+ text-transform: uppercase;
494
+ letter-spacing: 0 !important;
495
+ font-size: 11px !important;
496
+ font-weight: 750 !important;
497
+ }
498
+ #nw-operator-actions button:nth-child(2) {
499
+ border-color: rgba(16,185,129,.42) !important;
500
+ }
501
+ #nw-operator-actions button:nth-child(3) {
502
+ border-color: rgba(245,158,11,.46) !important;
503
+ }
504
+ #nw-operator-actions button:nth-child(4) {
505
+ border-color: rgba(148,163,184,.34) !important;
506
+ }
507
  .nw-control-panel {
508
  margin: 8px 8px 10px 8px;
509
  padding: 12px;
 
874
  background: rgba(255,255,255,.025);
875
  color: var(--nw-muted);
876
  }
877
+ .nw-stop-active {
878
+ display: grid;
879
+ place-items: center;
880
+ }
881
  @media (max-width: 1100px) {
882
  .nw-topbar { grid-template-columns: 1fr; }
883
  .nw-shell { grid-template-columns: 1fr; grid-template-rows: auto; }
tests/test_app_callbacks.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import app
2
+
3
+
4
+ def test_run_weave_returns_stateful_dashboard_packet() -> None:
5
+ result = app.run_weave(
6
+ "gothic patent leather platform boots, crimson hardware",
7
+ "Strict",
8
+ "Wan2.2 I2V",
9
+ False,
10
+ None,
11
+ "Forge",
12
+ )
13
+
14
+ assert len(result) == 17
15
+ assert result[13].checkpoint.checkpoint_id.startswith("nw-")
16
+ assert result[15]["provider_state"] == "checkpointed"
17
+ assert result[16]["interactive"] is True
18
+
19
+
20
+ def test_operator_actions_transition_checkpoint_export_and_stop() -> None:
21
+ result = app.run_weave(
22
+ "gothic patent leather platform boots, crimson hardware",
23
+ "Strict",
24
+ "Wan2.2 I2V",
25
+ False,
26
+ None,
27
+ "Forge",
28
+ )
29
+ run = result[13]
30
+ operator_state = result[15]
31
+ clean_scan = {"status": "pass", "export_gate": "clear", "findings": [], "purification_actions": []}
32
+
33
+ approved = app.approve_checkpoint(run, False, clean_scan, "Forge", operator_state)
34
+ assert approved[13]["checkpoint"] == "approved"
35
+ assert approved[13]["provider_state"] == "export_ready"
36
+
37
+ exported = app.export_packet(run, False, clean_scan, "Forge", approved[13])
38
+ assert exported[13]["provider_state"] == "exported"
39
+ assert exported[13]["export"] == "clear"
40
+
41
+ stopped = app.stop_provider_job(run, False, clean_scan, "Forge", operator_state)
42
+ assert stopped[13]["provider_state"] == "stopped"
43
+
44
+
45
+ def test_export_blocks_without_checkpoint() -> None:
46
+ result = app.run_weave(
47
+ "gothic patent leather platform boots, crimson hardware",
48
+ "Strict",
49
+ "Wan2.2 I2V",
50
+ False,
51
+ None,
52
+ "Forge",
53
+ )
54
+ clean_scan = {"status": "pass", "export_gate": "clear", "findings": [], "purification_actions": []}
55
+
56
+ blocked = app.export_packet(result[13], False, clean_scan, "Forge", result[15])
57
+
58
+ assert blocked[13]["provider_state"] == "blocked"
59
+ assert "checkpoint" in blocked[13]["message"].lower()