Bug: la dashboard mostrava \$0.0000 per Cost (USD) durante i run in corso
perché leggeva runs.total_cost_usd, che viene aggiornato solo dentro
Repository.complete_run a fine run. I record per-call esistevano già in
cost_records (124 record / \$0.019 sul run phase2-qwen3-001 attivo).
Fix: in _snapshot() se il run è status=running uso Repository.total_cost(run_id)
che fa SUM(cost_usd) live su cost_records. Per i run completed/failed continuo
a leggere total_cost_usd dal record runs (storico autoritativo).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Soluzione robusta al bug "chiavi JSON invisibili": invece di tentare
override CSS su Prism.js/highlight.js (che nelle build NiceGUI possono
non essere attivi o variare), il JSON viene serializzato server-side con
span colorati espliciti e renderizzato via ui.html.
Implementato helper _json_to_html(obj) che produce HTML con classi:
- .cb-key (chiavi) → cyan #00D9FF
- .cb-string → green #00E676
- .cb-number → pink #FF2D87
- .cb-bool / .cb-null → amber #FFB800
- .cb-punct (graffe, virgole, due punti) → muted
Stessa logica per system_prompt e raw LLM output in /genomes: sostituito
ui.code(language=text) con ui.html('<pre class="raw-block">') e
html.escape() per safety XSS. Background dedicato #1A1A24 e font
JetBrains Mono 13.5px, line-height 1.7, ottimo contrasto su qualsiasi
browser senza dipendere da syntax highlighter esterno.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Due bug visivi distinti:
1) Icone Material rotte ("arrow_drop_down" come testo nel selector):
Il selettore CSS '*' applicava font Inter a tutti gli elementi inclusi
gli .material-icons che richiedono il loro proprio font ligature.
Sostituito '*' con whitelist esplicita di elementi UI; aggiunto override
esplicito per .material-icons / .q-icon che forza font 'Material Icons'.
2) JSON keys invisibili nel code block config:
NiceGUI ui.code usa Prism.js (non highlight.js) per il syntax highlighting.
Aggiunti selettori .token.* coordinati con la palette neon:
- .token.property / .token.attr-name → cyan (chiavi JSON)
- .token.string → green (valori string)
- .token.number / .token.boolean / .token.null → pink
- .token.punctuation / .token.operator → muted
- .token.keyword / .token.builtin → amber
Più reset text-shadow per pre[class*=language-].
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Aggiunta route /genomes:
- Run selector + Top K (10/25/50)
- Tabella sortable con fitness, DSR, Sharpe, max DD, trades, style, T, lookback
- Selezione riga → pannello ispezione con 6 metric card e blocchi code per
system_prompt + raw_text + parse_error eventuale
- Auto-refresh ogni 3s (mantiene selezione corrente se ancora valida)
- Header nav aggiornato con link Genomes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prima fase migrazione da Streamlit a NiceGUI. Pagina indice riproduce
l'Overview con:
- run selector reattivo
- 2 progress bar live (generations, evaluations) con WebSocket push
- 4 metric card (top fitness, median, parse success %, cost)
- timer auto-refresh ogni 3s (no click manuale)
- status badge colorato (running/completed/failed)
- config JSON code block
Avvio: uv run python -m multi_swarm.dashboard.nicegui_app (porta 8080)
Streamlit resta attivo su 8501 durante la migrazione. Backend invariato:
riusa dashboard/data.py senza modifiche.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>