dev-strender's picture
Replace v24-era demo with v34 pipeline demo (engine-vendored bundle)
9c84f9d verified
Raw History Blame Contribute Delete
3.3 kB
"""Project management commands — local YAML or remote API."""
import click
from solar_eval.cli.config import config
from solar_eval.cli.formatters import format_projects_table
def _resolve_project_id(client, name_or_id: str) -> str:
"""Resolve a project name to its API ID (remote mode only)."""
if len(name_or_id) == 24:
try:
int(name_or_id, 16)
return name_or_id
except ValueError:
pass
projects = client.get("/api/projects")
for p in projects:
if p["name"] == name_or_id:
return p["id"]
raise click.ClickException(f"Project not found: {name_or_id}")
@click.group("projects")
def projects_group() -> None:
"""Manage evaluation projects."""
@projects_group.command("list")
@click.pass_context
def list_projects(ctx: click.Context) -> None:
"""List projects (from YAML locally, or from API remotely)."""
cfg = ctx.obj["config"]
if cfg.is_remote:
from solar_eval.cli.client import EvalClient
client = EvalClient(cfg.remote_url, cfg.timeout)
projects = client.get("/api/projects")
if not projects:
click.secho("No projects found.", fg="yellow")
return
click.secho(format_projects_table(projects), fg="blue")
else:
from solar_eval.core.project_loader import load_all_project_configs
configs = load_all_project_configs(cfg.projects_dir, cfg.config_dirs)
if not configs:
click.secho(f"No project YAML files in {cfg.projects_dir}", fg="yellow")
return
rows = [{
"name": c["name"],
"display_name": c.get("display_name", c["name"]),
"description": c.get("description", ""),
"task_count": len(c.get("tasks", [])),
} for c in configs]
click.secho(format_projects_table(rows), fg="blue")
@projects_group.command("show")
@click.argument("name")
@click.pass_context
def show_project(ctx: click.Context, name: str) -> None:
"""Show project details by name."""
cfg = ctx.obj["config"]
if cfg.is_remote:
from solar_eval.cli.client import EvalClient
client = EvalClient(cfg.remote_url, cfg.timeout)
project_id = _resolve_project_id(client, name)
project = client.get(f"/api/projects/{project_id}")
else:
from solar_eval.core.project_loader import load_all_project_configs
configs = load_all_project_configs(cfg.projects_dir, cfg.config_dirs)
project = next((c for c in configs if c["name"] == name), None)
if not project:
raise click.ClickException(f"Project not found: {name}")
project["display_name"] = project.get("display_name", name)
project["config"] = project
click.secho(f"Project: {project.get('display_name', name)}", fg="blue", bold=True)
click.echo(f" Name: {project.get('name', name)}")
click.echo(f" Description: {project.get('description', '-')}")
tasks = project.get("config", {}).get("tasks", project.get("tasks", []))
if tasks:
click.echo(f" Tasks ({len(tasks)}):")
for t in tasks:
ev = t.get("evaluator", {})
click.echo(f" - {t['name']} (pipeline: {t.get('pipeline', '?')}, evaluator: {ev.get('type', '?')})")