from __future__ import annotations from app_state import app_state def train_cue_model_from_feedback(): """Train lightweight cue and transition-candidate scorers from feedback.""" from cue_learning import ( load_training_examples, examples_from_rating_rows, fit_logistic_model, save_model, examples_from_candidate_rating_rows, fit_candidate_ranker, save_candidate_model, ) from listening_benchmarks import load_ratings manual = load_training_examples("data/manual-cue-edits.jsonl") rows = load_ratings() rating_examples = examples_from_rating_rows(rows) candidate_examples = examples_from_candidate_rating_rows(rows) examples = manual + rating_examples if not examples and not candidate_examples: return "⚠️ No manual cue edits or decisive listening ratings available for training yet." path = None candidate_path = None if examples: model = fit_logistic_model(examples) path = save_model(model) if candidate_examples: candidate_model = fit_candidate_ranker(candidate_examples) candidate_path = save_candidate_model(candidate_model) return ( "✅ Feedback models trained\n\n" f"- Cue examples: {len(examples)}\n" f"- Manual cue edits: {len(manual)}\n" f"- Rating-derived examples: {len(rating_examples)}\n" f"- Candidate examples: {len(candidate_examples)}\n" f"- Cue model output: `{path or 'not enough examples'}`\n" f"- Candidate ranker output: `{candidate_path or 'not enough examples'}`\n\n" "New analyses blend cue probability into cue confidence and candidate acceptance probability into transition ranking." ) def save_transition_rating(transition_idx, candidate_rank, rating, accepted, notes): """Persist a human listening rating for a transition candidate.""" if not app_state.transitions: return "⚠️ Generate a set plan first" idx = int(transition_idx) - 1 if idx < 0 or idx >= len(app_state.transitions): return f"⚠️ Invalid transition index. Choose 1-{len(app_state.transitions)}" trans = app_state.transitions[idx] track_a = app_state.analyses[trans.track_a_idx] track_b = app_state.analyses[trans.track_b_idx] from listening_benchmarks import record_transition_rating, summarize_ratings, format_rating_summary record_transition_rating( transition=trans, track_a=track_a, track_b=track_b, rating=float(rating), notes=str(notes or ""), candidate_rank=int(candidate_rank or 0), accepted=bool(accepted), ) return "✅ Rating saved.\n\n" + format_rating_summary(summarize_ratings()) def show_listening_benchmarks(): from listening_benchmarks import summarize_ratings, format_rating_summary return format_rating_summary(summarize_ratings())