Commit Graph

6 Commits

Author SHA1 Message Date
Adriano c38311e5fa feat(phase-2.5): mutate_prompt_llm operator + weighted dispatcher + GA wiring
Implementazione completa Phase 2.5 (LLM prompt mutator) seguendo il piano in
docs/superpowers/plans/2026-05-11-mutate-prompt-llm-phase-2-5.md.

Nuovo modulo src/multi_swarm/genome/mutation_prompt_llm.py:
- 6 mutation instructions (tighten_threshold, swap_comparator, add_condition,
  remove_condition, change_timeframe, add_temporal_gate)
- mutate_prompt_llm(g, llm, rng, mutator_tier=ModelTier.B): clona genome con
  tier B per la call mutator, costruisce system+user prompt con istruzione
  scelta random, estrae prompt da tag <prompt>...</prompt>, valida
- is_valid_prompt(): 3 check (lunghezza >= 50, keyword tecnica, diff > 5%
  Levenshtein-like via difflib.SequenceMatcher)
- Fallback random_mutate su qualsiasi validation fail O LLM exception

Esteso src/multi_swarm/genome/mutation.py con weighted_random_mutate dispatcher:
con probabilità prompt_mutation_weight invoca mutate_prompt_llm, altrimenti
random_mutate. Backward compat: llm=None oppure weight=0 → solo scalare.

Integrazione GA loop + RunConfig:
- GAConfig.prompt_mutation_weight: float = 0.0 (default off)
- next_generation(llm=...) propagato all'invocazione mutator
- RunConfig.prompt_mutation_weight con stesso default
- run_phase1: passa llm a next_generation solo se weight > 0
- scripts/run_phase1.py: flag CLI --prompt-mutation-weight

Tests (+18, 175 totale):
- tests/unit/test_mutation_prompt_llm.py (12): extract_prompt, is_valid_prompt
  3 check, operator success + fallback su 3 modi (invalid/identical/exception),
  tier B per LLM call, istruzione scelta dal pool
- tests/unit/test_mutation_dispatcher.py (4): weight 0/1/None + distribuzione
  30/70 su 1000 estrazioni con tolleranza ±5%
- tests/integration/test_ga_loop_with_prompt_mutator.py (2): loop con
  weight=1.0 produce prompt evoluti; backward compat weight=0 invariato

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 23:49:46 +02:00
Adriano 44eb6436c1 refactor(protocol): swap S-expression grammar for strict JSON Schema
Sostituisce la grammatica S-expression con uno schema JSON stretto. La
grammatica S-expression falliva il parsing nel 64% delle generazioni del
modello Qwen3-235B sul run reale; JSON e' nativo per gli LLM moderni e
si parsa con json.loads.

Cambiamenti principali:
- grammar.py: costanti rinominate LOGICAL_OPS / COMPARATOR_OPS /
  CROSSOVER_OPS / ACTION_VALUES / KIND_VALUES.
- parser.py: nuovo AST a dataclass tipizzato (OpNode, IndicatorNode,
  FeatureNode, LiteralNode, Rule, Strategy); parse_strategy ora consuma
  JSON tramite json.loads.
- validator.py: walk dispatchato per tipo (isinstance) invece di
  pattern-matching su 'kind'; arity check su operatori e indicator.
- compiler.py: traversal del nuovo AST tipizzato, dispatch per
  isinstance; logica indicator/feature/literal invariata.
- hypothesis.py: prompt SYSTEM riscritto con esempi JSON e vincoli
  espliciti su no-nesting; estrazione via fence ```json``` + fallback
  brace-balanced.
- __init__.py: re-export pubblico delle entita' del protocollo.
- Tutti i test (parser, validator, compiler, hypothesis_agent,
  falsification, adversarial, e2e, smoke_run) migrati a JSON.
- Rimossa dipendenza sexpdata da pyproject.toml + uv.lock.

Test: 135 passed (era 122; aggiunti casi parser/validator).
ruff + mypy strict clean. Smoke run end-to-end OK.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:17:26 +02:00
Adriano 3688611a40 feat(dashboard): aquarium click handler with info panel + ancestor lineage
Rimuove sidebar acquario (slider max-pesci, toggle label): la dimensione
popolazione è già definita dal GA, le label sono ridondanti col pannello
di ispezione. Mostra tutti i pesci della generazione selezionata.

Aggiunge `build_lineage_index` (mappa ogni genome_id della run ai suoi
attributi) e `trace_ancestors` (BFS sui parent_ids fino a max_levels,
guardia su cicli). `build_fish_dataset` accetta ora il lineage_index e
allega il campo `ancestors` ad ogni pesce; conserva la firma legacy per
compat con i fixture di test esistenti.

`build_aquarium_html` perde `show_labels`. Embedda click handler con
hit-test in canvas pixel space (account per CSS scaling) + pannello
info top-right con stile, fitness/DSR/Sharpe/maxDD/trades, prompt e
albero discendenza colorato per cognitive_style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 09:47:10 +02:00
Adriano 70b8bc3d6c feat(dashboard): aquarium 2D visualization (fish per agent, size by fitness)
Nuova pagina Streamlit "Aquarium" che renderizza ogni genoma come pesce
animato su canvas HTML5: dimensione proporzionale alla fitness, colore
per cognitive_style, halo per i top-3. Helper puro-Python testabile per
costruire dataset e HTML self-contained (no CDN).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 09:26:53 +02:00
Adriano 889903fdae feat(dashboard): streamlit skeleton + Overview page + data layer
Aggiunge scheletro multipage Streamlit per Phase 1:
- modulo data.py con helper (list_runs_df, get_run_overview,
  generations_df, evaluations_df, genomes_df) sopra Repository.
- streamlit_app.py entry point con DB_PATH da env.
- pages/01_overview.py per elenco run + metriche + config JSON.
- smoke test import di multi_swarm.dashboard.data.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 20:33:08 +02:00
Adriano 91d160be6f feat(orchestrator): end-to-end Phase 1 runner with persistence
Loop GA completo: build_initial_population -> hypothesis.propose ->
falsification + adversarial -> compute_fitness -> persistenza ->
next_generation. Stato run/gen/genomes/evals/cost/findings su SQLite,
elite skip-eval, run marcato failed su eccezione.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 20:28:35 +02:00