feat: enable full model file deletion on disk including split parts and vision adapters, update prompt text
This commit is contained in:
@@ -223,11 +223,58 @@ def set_ctx(model_id: str, ctx: int) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def delete_model(model_id: str) -> bool:
|
def delete_model(model_id: str) -> bool:
|
||||||
"""Entfernt einen Modell-Eintrag aus der config.yaml (und aus allen Gruppen)."""
|
"""Entfernt einen Modell-Eintrag aus der config.yaml, löscht die zugehörigen
|
||||||
|
GGUF-Dateien (auch Splits) vom Datenträger und bereinigt leere Ordner.
|
||||||
|
"""
|
||||||
cfg = read_config()
|
cfg = read_config()
|
||||||
models = cfg.get("models") or {}
|
models = cfg.get("models") or {}
|
||||||
if model_id not in models:
|
if model_id not in models:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
model_spec = models[model_id] or {}
|
||||||
|
cmd = str(model_spec.get("cmd", "")).strip()
|
||||||
|
if (m := _PATH_RE.search(cmd)):
|
||||||
|
path = m.group(1).replace("'", "").replace('"', "")
|
||||||
|
if path:
|
||||||
|
# 1. Haupt-GGUF-Datei löschen
|
||||||
|
if os.path.exists(path):
|
||||||
|
try:
|
||||||
|
os.remove(path)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 2. Split-GGUF-Teile löschen (z.B. dateiname-00001-of-00005.gguf etc.)
|
||||||
|
dirname = os.path.dirname(path)
|
||||||
|
basename = os.path.basename(path)
|
||||||
|
if os.path.isdir(dirname):
|
||||||
|
split_idx = basename.find("-00001-of-")
|
||||||
|
if split_idx != -1:
|
||||||
|
prefix = basename[:split_idx]
|
||||||
|
for f in os.listdir(dirname):
|
||||||
|
if f.startswith(prefix) and f.endswith(".gguf"):
|
||||||
|
try:
|
||||||
|
os.remove(os.path.join(dirname, f))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# mmproj-Datei (Vision adapter) aus dem Befehl parsen & löschen
|
||||||
|
if "mmproj" in cmd:
|
||||||
|
mmproj_match = re.search(r'--mmproj\s+[\'"]?([^\s\'"]+)[\'"]?', cmd)
|
||||||
|
if mmproj_match:
|
||||||
|
m_path = mmproj_match.group(1)
|
||||||
|
if os.path.exists(m_path):
|
||||||
|
try:
|
||||||
|
os.remove(m_path)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 3. Eltern-Ordner löschen, falls er leer ist und nicht der Modelle-Wurzelordner selbst ist
|
||||||
|
try:
|
||||||
|
if not os.listdir(dirname) and os.path.basename(dirname) != "models":
|
||||||
|
os.rmdir(dirname)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
del models[model_id]
|
del models[model_id]
|
||||||
for g in (cfg.get("groups") or {}).values():
|
for g in (cfg.get("groups") or {}).values():
|
||||||
if isinstance(g, dict) and model_id in (g.get("members") or []):
|
if isinstance(g, dict) and model_id in (g.get("members") or []):
|
||||||
|
|||||||
+12
-12
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
<meta name="theme-color" content="#0d1117" />
|
<meta name="theme-color" content="#0d1117" />
|
||||||
<link rel="manifest" href="/manifest.webmanifest" />
|
<link rel="manifest" href="/manifest.webmanifest" />
|
||||||
<title>Mission Control 2.0</title>
|
<title>Mission Control 2.0</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DphlB-Xi.js"></script>
|
<script type="module" crossorigin src="/assets/index-DMajYfAZ.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CAfaSDN8.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CAfaSDN8.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ function Cockpit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleDelete(name: string) {
|
async function handleDelete(name: string) {
|
||||||
if (!confirm(`Modell '${name}' aus der Config entfernen? (GGUF-Datei bleibt)`)) return
|
if (!confirm(`Modell '${name}' und alle zugehörigen GGUF-Dateien unwiderruflich von der Box löschen?`)) return
|
||||||
try {
|
try {
|
||||||
await api(`/api/models/${encodeURIComponent(name)}`, { method: "DELETE" })
|
await api(`/api/models/${encodeURIComponent(name)}`, { method: "DELETE" })
|
||||||
load()
|
load()
|
||||||
@@ -604,7 +604,7 @@ function Cockpit() {
|
|||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(m.name)}
|
onClick={() => handleDelete(m.name)}
|
||||||
className="h-7 w-7 rounded-lg flex items-center justify-center border border-border/40 text-muted-foreground hover:text-red-400 hover:bg-red-500/5 transition-all opacity-0 group-hover:opacity-100 shrink-0 cursor-pointer"
|
className="h-7 w-7 rounded-lg flex items-center justify-center border border-border/40 text-muted-foreground hover:text-red-400 hover:bg-red-500/5 transition-all opacity-0 group-hover:opacity-100 shrink-0 cursor-pointer"
|
||||||
title="Modell aus Config entfernen"
|
title="Modell und GGUF-Dateien löschen"
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3.5 w-3.5" />
|
<Trash2 className="h-3.5 w-3.5" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user