forked from MakazhanAlpamys/Soup
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrecipes.py
More file actions
150 lines (119 loc) · 4.6 KB
/
Copy pathrecipes.py
File metadata and controls
150 lines (119 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""soup recipes — browse and use ready-made configs for popular models."""
from pathlib import Path
from typing import Optional
import typer
from rich.console import Console
from rich.panel import Panel
from rich.syntax import Syntax
from rich.table import Table
console = Console()
app = typer.Typer(no_args_is_help=True)
@app.command(name="list")
def list_cmd():
"""List all available recipes."""
from soup_cli.recipes.catalog import RECIPES
table = Table(title="Soup Recipes")
table.add_column("Name", style="bold cyan")
table.add_column("Model", style="green")
table.add_column("Task", style="yellow")
table.add_column("Size", style="magenta")
table.add_column("Description")
for name, recipe in RECIPES.items():
table.add_row(name, recipe.model, recipe.task, recipe.size, recipe.description)
console.print(table)
@app.command()
def show(
name: str = typer.Argument(..., help="Recipe name"),
):
"""Show a recipe config (print YAML to stdout)."""
from soup_cli.recipes.catalog import get_recipe
recipe = get_recipe(name)
if recipe is None:
console.print(f"[red]Recipe not found: {name}[/]")
# v0.40.1 Part E / M3 — fuzzy-match suggestion (mirrors Typer's
# built-in "Did you mean" for unknown CLI flags).
suggestions = _suggest_recipes(name)
if suggestions:
console.print(
f"[dim]Did you mean: [bold]{', '.join(suggestions)}[/]?[/]"
)
console.print("[dim]Run 'soup recipes list' to see all recipes.[/]")
raise typer.Exit(1)
console.print(Panel(
Syntax(recipe.yaml_str, "yaml", theme="monokai"),
title=f"[bold green]{name}[/] -- {recipe.description}",
))
@app.command()
def use(
name: str = typer.Argument(..., help="Recipe name"),
output: str = typer.Option(
"soup.yaml",
"--output",
"-o",
help="Output path for config file",
),
yes: bool = typer.Option(
False,
"--yes",
"-y",
help="Skip confirmation prompts",
),
):
"""Copy a recipe to soup.yaml (or custom path)."""
from soup_cli.recipes.catalog import get_recipe
recipe = get_recipe(name)
if recipe is None:
console.print(f"[red]Recipe not found: {name}[/]")
raise typer.Exit(1)
from soup_cli.migrate.common import validate_output_path
try:
output_path = validate_output_path(Path(output))
except ValueError as exc:
console.print(f"[red]{exc}[/]")
raise typer.Exit(1)
if output_path.exists() and not yes:
confirm = typer.confirm(f"File '{output}' already exists. Overwrite?")
if not confirm:
console.print("[yellow]Aborted.[/]")
raise typer.Exit(0)
output_path.write_text(recipe.yaml_str, encoding="utf-8")
console.print(f"[green]\u2713[/] Recipe [bold]{name}[/] written to [bold]{output}[/]")
console.print(f"[dim]Next: soup train --config {output}[/]")
@app.command()
def search(
query: Optional[str] = typer.Argument(None, help="Search keyword"),
task: Optional[str] = typer.Option(None, "--task", help="Filter by task"),
size: Optional[str] = typer.Option(None, "--size", help="Filter by model size"),
):
"""Search recipes by keyword, task, or model size."""
from soup_cli.recipes.catalog import RECIPES, search_recipes
results = search_recipes(query=query, task=task, size=size)
if not results:
console.print("[yellow]No recipes found matching your query.[/]")
console.print(f"[dim]Available recipes: {len(RECIPES)}. Run 'soup recipes list'.[/]")
return
table = Table(title="Search Results")
table.add_column("Name", style="bold cyan")
table.add_column("Model", style="green")
table.add_column("Task", style="yellow")
table.add_column("Size", style="magenta")
table.add_column("Description")
# Find name for each result
for recipe in results:
name = next(
(n for n, r in RECIPES.items() if r is recipe),
"?",
)
table.add_row(name, recipe.model, recipe.task, recipe.size, recipe.description)
console.print(table)
def _suggest_recipes(query: str, n: int = 3) -> list[str]:
"""v0.40.1 Part E / M3 — return up to ``n`` close-matching recipe ids."""
from difflib import get_close_matches
from soup_cli.recipes.catalog import RECIPES
try:
names = list(RECIPES.keys()) if hasattr(RECIPES, "keys") else [
r.name for r in RECIPES
]
except Exception: # noqa: BLE001
return []
return get_close_matches(query, names, n=n, cutoff=0.6)