Spaces:
Sleeping
Sleeping
| """Lore training CLI β curiosity training and model management.""" | |
| from __future__ import annotations | |
| import json | |
| import typer | |
| from rich import print as rprint | |
| from rich.console import Console | |
| from rich.table import Table | |
| app = typer.Typer(name="lore-train", help="Curiosity training management", add_completion=False) | |
| console = Console() | |
| def curiosity_cmd(): | |
| """Train the model on your questioning patterns (SFT/GRPO).""" | |
| from lore.evolve.trainer import run_curiosity_training | |
| stats = run_curiosity_training() | |
| rprint(f"[green]β[/green] Curiosity training complete: {stats}") | |
| def status_cmd(): | |
| """Show training status.""" | |
| from lore.evolve.trajectory import get_question_trace_stats | |
| from lore.config import LORA_CHECKPOINTS_DIR, CURIOSITY_BOOTSTRAP_N | |
| q_stats = get_question_trace_stats() | |
| checkpoints = sorted(LORA_CHECKPOINTS_DIR.glob("step-*")) if LORA_CHECKPOINTS_DIR.exists() else [] | |
| total_traces = q_stats.get("total", 0) | |
| table = Table(title="Curiosity Training Status") | |
| table.add_column("Metric", style="cyan") | |
| table.add_column("Value", style="green") | |
| table.add_row("Question traces", str(total_traces)) | |
| table.add_row("Untrained traces", str(q_stats.get("untrained", 0))) | |
| table.add_row("LoRA checkpoints", str(len(checkpoints))) | |
| table.add_row("Latest checkpoint", | |
| checkpoints[-1].name if checkpoints else "none (base model)") | |
| table.add_row("Training mode", | |
| "SFT (imitation)" if total_traces < CURIOSITY_BOOTSTRAP_N else "GRPO (RL)") | |
| console.print(table) | |
| from lore.evolve.trajectory import CURIOSITY_SUGGESTED_FLAG | |
| if CURIOSITY_SUGGESTED_FLAG.exists(): | |
| rprint( | |
| f"\n[bold yellow]Ready to train:[/bold yellow] " | |
| f"{q_stats.get('untrained', 0)} new question traces.\n" | |
| f" Run [bold]lore-train curiosity[/bold] to improve suggestions." | |
| ) | |
| def suggest_cmd( | |
| n: int = typer.Option(3, "--n", "-n", help="Number of suggestions"), | |
| json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON"), | |
| ): | |
| """Generate follow-up question suggestions based on your questioning style.""" | |
| from lore.evolve.curiosity import generate_suggestions_with_mode | |
| suggestions, mode = generate_suggestions_with_mode(n=n) | |
| payload = {"mode": mode, "suggestions": suggestions} | |
| if json_output: | |
| print(json.dumps(payload)) | |
| return | |
| if not suggestions: | |
| rprint("[yellow]No suggestions β wiki is empty or model not available.[/yellow]") | |
| return | |
| if mode == "heuristic": | |
| rprint("[yellow]Using heuristic fallback suggestions (no checkpoint yet).[/yellow]\n") | |
| elif mode == "daemon": | |
| rprint("[green]Using daemon-backed suggestions.[/green]\n") | |
| elif mode == "checkpoint": | |
| rprint("[green]Using local checkpoint suggestions.[/green]\n") | |
| rprint("\n[bold]Suggested follow-up questions:[/bold]\n") | |
| for i, s in enumerate(suggestions, 1): | |
| rprint(f" [cyan]{i}.[/cyan] {s['question']}") | |
| rprint(f" [dim]gap={s['gap_targeting']:.2f} style={s['style_match']:.2f} " | |
| f"novelty={s['novelty']:.2f} specificity={s['specificity']:.2f} " | |
| f"combined={s['combined']:.3f}[/dim]") | |
| rprint("") | |
| def rollback_cmd( | |
| steps: int = typer.Option(1, "--steps", "-n", help="Number of checkpoints to roll back"), | |
| ): | |
| """Roll back to a previous LoRA checkpoint.""" | |
| from lore.evolve.trainer import rollback_checkpoint | |
| rollback_checkpoint(steps) | |
| def serve_cmd( | |
| port: int = typer.Option(8765, "--port", "-p"), | |
| host: str = typer.Option("127.0.0.1", "--host"), | |
| ): | |
| """Start the daemon β keeps model in memory for instant suggestions.""" | |
| import uvicorn | |
| from lore.evolve.daemon import app as daemon_app | |
| rprint(f"[green]Starting lore daemon on {host}:{port}[/green]") | |
| rprint("[dim]Keep this running in a terminal. Suggestions will be instant.[/dim]") | |
| uvicorn.run(daemon_app, host=host, port=port) | |
| def main(): | |
| app() | |
| if __name__ == "__main__": | |
| main() | |