Refactor CLI and LLM runtime handling for improved user experience
- Removed deprecated console usage in favor of structured logging functions for error handling and user prompts. - Enhanced CLI prompts for LLM runtime and preset selection, utilizing menu helpers for better user interaction. - Updated GPU pool scanning output with improved formatting and error indication for clarity. - Refactored setup wizard to streamline LLM runtime and preset configuration, ensuring a more intuitive setup process. - Improved documentation and user feedback in CLI outputs to enhance overall usability.
This commit is contained in:
+23
-19
@@ -6,6 +6,8 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from rich.markup import escape
|
||||
|
||||
from gpu_rent.config import Config
|
||||
from gpu_rent.inventory import FlavorInfo, looks_like_gpu, rank_flavors, resolve_flavor
|
||||
|
||||
@@ -21,14 +23,19 @@ def list_ranked_flavors(flavors: list[Any], cfg: Config) -> list[FlavorInfo]:
|
||||
|
||||
def format_flavor_lines(ranked: list[FlavorInfo], picked: FlavorInfo | None = None) -> list[str]:
|
||||
if not ranked:
|
||||
return ["flavors: пусто (проверь регион / FLAVOR_PREFERENCE)"]
|
||||
lines = ["flavors (по FLAVOR_PREFERENCE):"]
|
||||
return ["[yellow]flavors: пусто (проверь регион / FLAVOR_PREFERENCE)[/yellow]"]
|
||||
lines = ["[bold cyan]flavors (по FLAVOR_PREFERENCE):[/bold cyan]"]
|
||||
for i, info in enumerate(ranked, 1):
|
||||
mark = " ← выберем" if picked and info.id == picked.id else ""
|
||||
mark = " [green]← выберем[/green]" if picked and info.id == picked.id else ""
|
||||
ram = f"{info.ram_mb // 1024}GB" if info.ram_mb else "?"
|
||||
vcpu = str(info.vcpus) if info.vcpus is not None else "?"
|
||||
label = info.label or "—"
|
||||
lines.append(f" {i}. [{label}] {info.name} vCPU={vcpu} RAM={ram} id={info.id}{mark}")
|
||||
label = escape(info.label or "—")
|
||||
name = escape(info.name)
|
||||
fid = escape(info.id)
|
||||
lines.append(
|
||||
f" [cyan]{i}.[/cyan] [bold]{label}[/bold] {name} "
|
||||
f"vCPU={vcpu} RAM={ram} id={fid}{mark}"
|
||||
)
|
||||
return lines
|
||||
|
||||
|
||||
@@ -114,21 +121,18 @@ def prompt_server_plan(
|
||||
if data_gb < 20:
|
||||
raise ValueError("Data disk GB: минимум 20")
|
||||
|
||||
spot_default = "Y" if spot else "n"
|
||||
raw_spot = (
|
||||
ask(
|
||||
"Preemptible GPU (дешевле, могут усыпить ~24ч)? [Y/n]",
|
||||
spot_default,
|
||||
)
|
||||
.strip()
|
||||
.lower()
|
||||
from gpu_rent.prompts import MenuItem, prompt_menu
|
||||
|
||||
spot_key = prompt_menu(
|
||||
"Тариф GPU",
|
||||
[
|
||||
MenuItem("yes", "preemptible (дешевле, могут усыпить ~24ч)"),
|
||||
MenuItem("no", "обычный on-demand"),
|
||||
],
|
||||
default="yes" if spot else "no",
|
||||
ask=ask,
|
||||
)
|
||||
if raw_spot in {"", "y", "yes", "1", "true", "on"}:
|
||||
use_spot = True
|
||||
elif raw_spot in {"n", "no", "0", "false", "off"}:
|
||||
use_spot = False
|
||||
else:
|
||||
raise ValueError(f"preemptible: жду Y/n, получили {raw_spot!r}")
|
||||
use_spot = spot_key == "yes"
|
||||
|
||||
changed = (
|
||||
chosen.id != picked.id
|
||||
|
||||
Reference in New Issue
Block a user