fix+feat: offene Punkte abgeschlossen

Kontext in Connect-Snippet:
- ConnectPanel: max_tokens nutzt jetzt den echten konfigurierten Kontext
  des Modells (m.meta.ctx) statt hartkodiertem 32768 -> Zed sieht 128k

Phase D - 'Immer aktiv halten' Toggle:
- models.py: UpdateReq bekommt optionales ttl-Feld
- update_model: setzt TTL wenn angegeben (ctx und ttl unabhaengig)
- ModelsPanel: Checkbox 'Immer aktiv halten' im Konfig-Modal
  (TTL=99999 = nie entladen, TTL=300 = Standard 5min)

MoE tps-Schaetzung:
- hw_math.py: extract_active_params_b() erkennt A3B-Suffix
- estimate_speed(): moe_active_ratio-Parameter, sqrt-Boost fuer MoE
- evaluate_fit(): name-Parameter (optional) fuer automatische MoE-Erkennung
- cookbook.py: alle evaluate_fit-Aufrufe mit name= versehen

Cleanup:
- static/js/panels/*.js + static/js/main.js geloescht (Dead Code)
- wird-Datei (versehentlich committet) geloescht
- CLAUDE.md: KISS-Statement auf Vite+Svelte-Stand aktualisiert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-22 22:21:15 +02:00
parent 5e9471a778
commit d8fe1f8097
17 changed files with 91 additions and 2192 deletions
+4 -4
View File
@@ -127,7 +127,7 @@ async def analyze_repo(req: AnalyzeRequest):
results = []
for f in gguf_files:
quant = extract_quant(f)
fit = evaluate_fit(params_b, quant, req.ctx, ram_gb)
fit = evaluate_fit(params_b, quant, req.ctx, ram_gb, name=req.repo_id)
# Priority-Score, um den besten Fit an oberste Stelle zu setzen.
# "Q4_K_M" ist oft der Sweetspot.
@@ -173,7 +173,7 @@ def recipes():
for r in all_recipes():
models, worst = [], "perfect"
for m in r["models"]:
fit = evaluate_fit(m["params_b"], m["quant"], 8192, ram_gb)
fit = evaluate_fit(m["params_b"], m["quant"], 8192, ram_gb, name=m.get("name", ""))
models.append({**m, "fit": fit, "optimal_ctx": max_ctx_for(m["params_b"], m["quant"], ram_gb)})
if _FIT_ORDER[fit["level"]] > _FIT_ORDER[worst]:
worst = fit["level"]
@@ -427,7 +427,7 @@ def refresh_discover(ram_gb: float) -> dict:
role = _categorize(rid)
params_b = extract_params_b(rid)
quant = "Q4_K_M" # Referenz-Quant fuer die Fit-Einschaetzung
fit = evaluate_fit(params_b, quant, 8192, ram_gb)
fit = evaluate_fit(params_b, quant, 8192, ram_gb, name=rid)
by_cat[role].append({
"name": rid.split("/")[-1], "author": rid.split("/")[0], "repo": rid,
"role": role, "params_b": params_b, "quant": quant,
@@ -518,7 +518,7 @@ def compute_upgrades(ram_gb):
out.append({
"name": up["name"], "repo": up["repo"], "params_b": up["params_b"], "quant": up["quant"],
"why": up["why"], "old": old, "role": old,
"fit": evaluate_fit(up["params_b"], up["quant"], 8192, ram_gb),
"fit": evaluate_fit(up["params_b"], up["quant"], 8192, ram_gb, name=up.get("name", "")),
"optimal_ctx": max_ctx_for(up["params_b"], up["quant"], ram_gb),
})
return out
+15 -11
View File
@@ -58,7 +58,8 @@ class ChatReq(BaseModel):
class UpdateReq(BaseModel):
alias: str
ctx: int
ctx: int | None = None
ttl: int | None = None
class DeleteReq(BaseModel):
@@ -251,17 +252,20 @@ def update_model(req: UpdateReq):
cfg = read_config()
if req.alias not in cfg.get("models", {}):
raise HTTPException(404, "Modell nicht gefunden")
spec = cfg["models"][req.alias]
cmd = str(spec.get("cmd", ""))
# Replace or add context size
if re.search(r'-(?:c|-ctx-size)\s+\d+', cmd):
cmd = re.sub(r'-(?:c|-ctx-size)\s+\d+', f'-c {req.ctx}', cmd)
else:
cmd = cmd.strip() + f" -c {req.ctx}\n"
cfg["models"][req.alias]["cmd"] = LiteralScalarString(cmd)
if req.ctx is not None:
cmd = str(spec.get("cmd", ""))
if re.search(r'-(?:c|-ctx-size)\s+\d+', cmd):
cmd = re.sub(r'-(?:c|-ctx-size)\s+\d+', f'-c {req.ctx}', cmd)
else:
cmd = cmd.strip() + f" -c {req.ctx}\n"
cfg["models"][req.alias]["cmd"] = LiteralScalarString(cmd)
if req.ttl is not None:
cfg["models"][req.alias]["ttl"] = req.ttl
write_config(cfg)
return {"ok": True}