"""Head-only voice-pack preset (unused by the CLI).""" import argparse import json import urllib.error from pathlib import Path from vlib import ctx from vlib.fetch import _fetch_pack, _resolve_output_name, _source_arch from vlib.sources import (_family, _hf_config, _public_source, _slugify_voice_name, open_source) from vlib.tensors import write_safetensors from vlib.ui import _fail, _note, _now_iso, _say, _step def _resolve_pack_tensors(source, repo, config, names): """Head-only voice-pack preset. Embed/norm/blocks stay manual (voice get ). Config is the source config with _hf_config fallback. Miss fails loud.""" if config is None and getattr(source, "repo", None): config = _hf_config(source.repo) head = _resolve_output_name(source, config, names) if head is None: _fail(f" ✗ pack: no output head found in '{repo}'.") return [head] def cmd_pack(args): repo = args.repo.strip().rstrip("/") if not repo: _fail(" ✗ Enter a model name — for example: voice pack google/gemma-3-1b") _step(f"Finding the voice pack in {repo}…") try: source = open_source(repo) names = source.names() if not names: _fail(f" ✗ No tensors found in '{repo}'.") arch, config = _source_arch(source) except urllib.error.HTTPError as e: _fail(f" ✗ Model '{repo}' was not found or is not accessible ({e.code}).") except Exception as e: if ctx.VERBOSE: import traceback _say(traceback.format_exc()) _fail(f" ✗ Could not reach the model. Check your connection ({type(e).__name__}).") _step("Resolving voice-pack tensors…") resolved = _resolve_pack_tensors(source, repo, config, names) for tname in resolved: _note(f" {tname}") # Fetch via the same multi path as get --multi, then save flat in the # registry through the existing add machinery (no new storage format). pack = _fetch_pack(source, repo, resolved) slug = _slugify_voice_name(repo.split("/")[-1].split("@")[0].split(":")[0].replace(".gguf", "").replace(".safetensors", "")) name = f"pack-{slug}" import tempfile, shutil stage = Path(tempfile.mkdtemp(prefix="voicepack-stage-")) try: st_path = stage / "voice.safetensors" write_safetensors(pack, str(st_path)) js_path = stage / "voice.json" js_path.write_text(json.dumps({ "name": name, "source": _public_source(repo), "source_format": source.kind, "tensors": [{"name": n, "shape": [int(x) for x in pack[n][2]], "dtype": pack[n][1]} for n in resolved if n in pack], "architecture": arch, "family": _family(arch), "downloaded_at": _now_iso(), }, indent=2) + "\n") from vlib.cmds_voices import cmd_add cmd_add(argparse.Namespace(safetensors=str(st_path), json=str(js_path), name=name, yes=getattr(args, "yes", False), non_interactive=getattr(args, "non_interactive", False))) finally: shutil.rmtree(stage, ignore_errors=True)