mirror of https://github.com/razor-ai/soup.git
99 lines
3.1 KiB
Python
99 lines
3.1 KiB
Python
"""``soup compile`` — DSPy / GEPA prompt-program compiler CLI (v0.68.0 Part A).
|
|
|
|
Renders a ``CompilePlan`` panel and, when ``--plan-only`` is omitted,
|
|
invokes the deferred-live ``run_compile`` (raises NotImplementedError
|
|
with a v0.68.1 marker). Mirrors v0.61.0 / v0.62.0 stub-then-live CLI policy.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import typer
|
|
from rich.console import Console
|
|
from rich.markup import escape
|
|
from rich.panel import Panel
|
|
|
|
from soup_cli.utils.paths import atomic_write_text
|
|
from soup_cli.utils.prompt_compile import (
|
|
SUPPORTED_PROMPT_OPTIMIZERS,
|
|
build_compile_plan,
|
|
run_compile,
|
|
)
|
|
|
|
console = Console()
|
|
|
|
|
|
def compile_cmd(
|
|
program: str = typer.Argument(..., help="Path to DSPy / GEPA program (.py)"),
|
|
eval_suite: str = typer.Option(
|
|
..., "--eval", help="Path to eval-suite JSON / JSONL file"
|
|
),
|
|
optimizer: str = typer.Option(
|
|
"mipro",
|
|
"--optimizer",
|
|
help=(
|
|
"Optimizer name. Allowed: "
|
|
+ ", ".join(sorted(SUPPORTED_PROMPT_OPTIMIZERS))
|
|
),
|
|
),
|
|
max_iters: int = typer.Option(10, "--max-iters", help="Maximum optimizer iterations"),
|
|
output: str = typer.Option(
|
|
"compiled_program.py", "--output", "-o", help="Output program path"
|
|
),
|
|
plan_only: bool = typer.Option(
|
|
False,
|
|
"--plan-only",
|
|
help="Render the resolved plan + exit 0 (no live compile).",
|
|
),
|
|
) -> None:
|
|
"""Compile a DSPy / GEPA prompt program against an eval suite."""
|
|
try:
|
|
plan = build_compile_plan(
|
|
program_path=program,
|
|
eval_suite_path=eval_suite,
|
|
optimizer=optimizer,
|
|
max_iters=max_iters,
|
|
output_path=output,
|
|
)
|
|
except (TypeError, ValueError) as exc:
|
|
console.print(f"[red]{escape(str(exc))}[/]")
|
|
raise typer.Exit(2) from exc
|
|
|
|
console.print(
|
|
Panel(
|
|
f"Program: [bold]{escape(plan.program_path)}[/]\n"
|
|
f"Eval suite: [bold]{escape(plan.eval_suite_path)}[/]\n"
|
|
f"Optimizer: [bold]{escape(plan.optimizer)}[/]\n"
|
|
f"Max iters: [bold]{plan.max_iters}[/]\n"
|
|
f"Output: [bold]{escape(plan.output_path)}[/]",
|
|
title="soup compile — plan",
|
|
)
|
|
)
|
|
|
|
if plan_only:
|
|
return
|
|
|
|
try:
|
|
result = run_compile(plan)
|
|
except NotImplementedError as exc:
|
|
console.print(
|
|
Panel(
|
|
f"[yellow]{escape(str(exc))}[/]",
|
|
title="Live compile deferred",
|
|
)
|
|
)
|
|
raise typer.Exit(3) from exc
|
|
except (TypeError, ValueError) as exc:
|
|
console.print(f"[red]{escape(str(exc))}[/]")
|
|
raise typer.Exit(2) from exc
|
|
|
|
atomic_write_text(result.program_text, plan.output_path, field="output_path")
|
|
console.print(
|
|
Panel(
|
|
f"Output: [bold]{escape(plan.output_path)}[/]\n"
|
|
f"Score: [bold]{result.score:.3f}[/]\n"
|
|
f"Iterations: [bold]{result.iterations}[/]\n"
|
|
f"Converged: [bold]{result.converged}[/]",
|
|
title="soup compile — done",
|
|
)
|
|
)
|