"""Interactive setup wizard: files + LLM_RUNTIME + optional watchdog.""" from __future__ import annotations import shutil from collections.abc import Callable from pathlib import Path from gpu_rent.llm_runtime import ( append_vars_llm_runtime, ensure_ollama_manifest_from_example, llm_runtime_menu, normalize_runtime, ollama_preset_menu, write_ollama_models_preset, ) from gpu_rent.paths import ( app_root, assistent_personas_example_path, assistent_personas_manifest_path, env_path, extensions_manifest_path, models_manifest_path, ollama_models_example_path, ollama_models_manifest_path, vars_example_path, vars_path, ) from gpu_rent.prompts import prompt_menu Log = Callable[[str], None] def _copy_if_missing(src: Path, dst: Path, label: str, log: Log) -> None: if dst.is_file(): log(f"есть {label}") return if src.is_file(): shutil.copy2(src, dst) log(f"создал {label} из example") else: log(f"нет example для {label}: {src}") def run_setup( *, llm: str | None = None, ollama_preset: str | None = None, install_watchdog: bool | None = None, confirm: Callable[[str], bool] | None = None, ask: Callable[[str, str], str] | None = None, log: Log = print, ) -> None: root = app_root() log(f"setup в {root}") _copy_if_missing(root / "env.example", env_path(), ".env", log) _copy_if_missing(root / "models.example.yaml", models_manifest_path(), "models.yaml", log) _copy_if_missing( assistent_personas_example_path(), assistent_personas_manifest_path(), "assistent-personas.yaml", log, ) _copy_if_missing( root / "extensions.example.yaml", extensions_manifest_path(), "extensions.yaml", log ) _copy_if_missing(vars_example_path(), vars_path(), "gpu-rent.vars", log) _copy_if_missing( ollama_models_example_path(), ollama_models_manifest_path(), "ollama-models.yaml", log ) runtime = llm if runtime is None: if ask: runtime = prompt_menu( "LLM runtime", llm_runtime_menu(), default="none", ask=ask, show=log, ) else: runtime = "none" runtime = normalize_runtime(runtime) append_vars_llm_runtime(vars_path(), runtime) log(f"LLM_RUNTIME={runtime} → gpu-rent.vars") if runtime == "ollama": preset = ollama_preset if preset is None and ask: preset = prompt_menu( "Ollama preset", ollama_preset_menu(include_keep=False), default="recommended", ask=ask, show=log, ) if preset is None: preset = "recommended" if preset.strip().lower() in {"keep", "example", ""}: ensure_ollama_manifest_from_example() log("ollama-models.yaml из example") else: write_ollama_models_preset(ollama_models_manifest_path(), preset) log(f"ollama-models.yaml пресет={preset}") do_wd = install_watchdog if do_wd is None and confirm: do_wd = confirm("Установить local-watchdog (аварийный stop, если процесс умер)?") if do_wd: from gpu_rent.local_watchdog import install_watchdog as _install _install(log=log) elif do_wd is False: log("local-watchdog: skip") log("готово. Заполни .env (OS_*), потом: gpu-rent doctor && gpu-rent up")