mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 18:25:26 -04:00
Fix cached GGUF model metadata in Cookbook Serve
This commit is contained in:
@@ -37,7 +37,7 @@ from routes.cookbook_helpers import (
|
||||
_validate_local_dir, _validate_ssh_port, _validate_gpus, _shell_path,
|
||||
_ps_squote, _bash_squote, _validate_serve_cmd, _parse_serve_phase,
|
||||
_safe_env_prefix, _local_tooling_path_export, _append_serve_preflight_exit_lines,
|
||||
_append_serve_exit_code_lines,
|
||||
_append_serve_exit_code_lines, _cached_model_scan_script,
|
||||
ModelDownloadRequest, ServeRequest,
|
||||
)
|
||||
|
||||
@@ -647,84 +647,13 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
raise HTTPException(400, "Invalid ssh_port")
|
||||
TMUX_LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
paths_code = "import json, os\n"
|
||||
paths_code += "models = []\n"
|
||||
paths_code += "seen = set()\n"
|
||||
paths_code += "BLOCKED_ROOTS = ('/sys', '/proc', '/dev', '/run', '/var/run')\n"
|
||||
paths_code += "def safe_path(p):\n"
|
||||
paths_code += " try:\n"
|
||||
paths_code += " rp = os.path.realpath(os.path.expanduser(p))\n"
|
||||
paths_code += " return not any(rp == b or rp.startswith(b + os.sep) for b in BLOCKED_ROOTS)\n"
|
||||
paths_code += " except Exception:\n"
|
||||
paths_code += " return False\n"
|
||||
paths_code += "def safe_walk(top):\n"
|
||||
paths_code += " if not safe_path(top): return\n"
|
||||
paths_code += " for root, dirs, fns in os.walk(top, followlinks=False):\n"
|
||||
paths_code += " dirs[:] = [d for d in dirs if not os.path.islink(os.path.join(root, d)) and safe_path(os.path.join(root, d))]\n"
|
||||
paths_code += " yield root, dirs, fns\n"
|
||||
# Scan HF cache format (models-- directories with blobs/)
|
||||
paths_code += "def scan_hf(cache):\n"
|
||||
paths_code += " if not os.path.isdir(cache): return\n"
|
||||
paths_code += " for d in sorted(os.listdir(cache)):\n"
|
||||
paths_code += " if not d.startswith('models--'): continue\n"
|
||||
paths_code += " rid = d.replace('models--','').replace('--','/')\n"
|
||||
paths_code += " if rid in seen: continue\n"
|
||||
paths_code += " seen.add(rid)\n"
|
||||
paths_code += " blobs = os.path.join(cache, d, 'blobs')\n"
|
||||
paths_code += " sz, nf, ic = 0, 0, False\n"
|
||||
paths_code += " if os.path.isdir(blobs):\n"
|
||||
paths_code += " for f in os.scandir(blobs):\n"
|
||||
paths_code += " if f.is_file(): nf += 1; sz += f.stat().st_size\n"
|
||||
paths_code += " if f.name.endswith('.incomplete'): ic = True\n"
|
||||
paths_code += " # Check if it's an LLM (has config.json with model_type) vs diffusion (has model_index.json)\n"
|
||||
paths_code += " snap = os.path.join(cache, d, 'snapshots')\n"
|
||||
paths_code += " is_diffusion = False; is_gguf = False\n"
|
||||
paths_code += " if os.path.isdir(snap):\n"
|
||||
paths_code += " for sd in os.listdir(snap):\n"
|
||||
paths_code += " sf = os.path.join(snap, sd)\n"
|
||||
paths_code += " if not os.path.isdir(sf): continue\n"
|
||||
paths_code += " if os.path.exists(os.path.join(sf, 'model_index.json')): is_diffusion = True\n"
|
||||
paths_code += " try:\n"
|
||||
paths_code += " if any(x.endswith('.gguf') for x in os.listdir(sf)): is_gguf = True\n"
|
||||
paths_code += " except Exception: pass\n"
|
||||
paths_code += " models.append({'repo_id':rid,'size_bytes':sz,'nb_files':nf,'has_incomplete':ic,'path':cache,'is_diffusion':is_diffusion,'is_gguf':is_gguf})\n"
|
||||
# Scan plain directory (each subdirectory = a model if it has model files)
|
||||
paths_code += "def scan_dir(p):\n"
|
||||
paths_code += " if not os.path.isdir(p) or not safe_path(p): return\n"
|
||||
paths_code += " for d in sorted(os.listdir(p)):\n"
|
||||
paths_code += " if d.startswith('.'): continue\n"
|
||||
paths_code += " fp = os.path.join(p, d)\n"
|
||||
paths_code += " if not os.path.isdir(fp) or os.path.islink(fp) or not safe_path(fp): continue\n"
|
||||
paths_code += " if d in seen: continue\n"
|
||||
paths_code += " # Check if it looks like a model (has config.json, safetensors, bin, or gguf)\n"
|
||||
paths_code += " is_model = False; is_gguf = False\n"
|
||||
paths_code += " for root, dirs, fns in safe_walk(fp):\n"
|
||||
paths_code += " for fn in fns:\n"
|
||||
paths_code += " if fn.endswith('.gguf'): is_gguf = True; is_model = True\n"
|
||||
paths_code += " elif fn == 'config.json' or fn.endswith('.safetensors') or fn.endswith('.bin'): is_model = True\n"
|
||||
paths_code += " if is_model: break\n"
|
||||
paths_code += " if not is_model: continue\n"
|
||||
paths_code += " seen.add(d)\n"
|
||||
paths_code += " sz, nf = 0, 0\n"
|
||||
paths_code += " for dp, _, fns in safe_walk(fp):\n"
|
||||
paths_code += " for fn in fns:\n"
|
||||
paths_code += " try: nf += 1; sz += os.path.getsize(os.path.join(dp, fn))\n"
|
||||
paths_code += " except Exception: pass\n"
|
||||
paths_code += " is_diff = os.path.exists(os.path.join(fp, 'model_index.json'))\n"
|
||||
paths_code += " models.append({'repo_id':d,'size_bytes':sz,'nb_files':nf,'has_incomplete':False,'path':p,'is_local_dir':True,'is_diffusion':is_diff,'is_gguf':is_gguf})\n"
|
||||
# Always scan HF cache
|
||||
paths_code += "scan_hf(os.path.expanduser('~/.cache/huggingface/hub'))\n"
|
||||
# Also scan custom model dirs (comma-separated) if specified
|
||||
model_dirs = []
|
||||
if model_dir:
|
||||
for d in model_dir.split(','):
|
||||
d = d.strip()
|
||||
if d and d != '~/.cache/huggingface/hub':
|
||||
# repr() encodes the dir as a properly-escaped Python string
|
||||
# literal. The old f"...'{d}'..." broke out of the quotes on
|
||||
# any `'` in the value, injecting arbitrary Python that then
|
||||
# ran locally or over ssh.
|
||||
paths_code += f"scan_dir(os.path.expanduser({d!r}))\n"
|
||||
paths_code += "print(json.dumps(models))\n"
|
||||
if d:
|
||||
model_dirs.append(d)
|
||||
paths_code = _cached_model_scan_script(model_dirs)
|
||||
|
||||
scan_py = TMUX_LOG_DIR / "scan_cache.py"
|
||||
scan_py.write_text(paths_code, encoding="utf-8")
|
||||
@@ -779,6 +708,8 @@ def setup_cookbook_routes() -> APIRouter:
|
||||
}
|
||||
if m.get("is_local_dir"):
|
||||
entry["is_local_dir"] = True
|
||||
if m.get("is_gguf"):
|
||||
entry["is_gguf"] = True
|
||||
models.append(entry)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to parse cached models: {e}")
|
||||
|
||||
Reference in New Issue
Block a user