From aa077f60e64dcef84349cb3674578dee7c3f89d0 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Mon, 11 May 2026 22:36:14 +0200 Subject: [PATCH] fix(diagnostic+brain): Sprachmodell-Einstellung auf runtime.json umgestellt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit War kaputt nach OpenClaw-Abriss: handleGetModel/handleSetModel haben gegen aria-core (dockerExec + node-script in den Container) gearbeitet, der gibt's nicht mehr. diagnostic/server.js - handleGetModel/handleSetModel lesen/schreiben jetzt brainModel in /shared/config/runtime.json - RUNTIME_CONFIG_FIELDS um "brainModel" erweitert - Tote Variante (findSettingsFile + base64-node-script) komplett raus aria-brain/proxy_client.py - Liest brainModel aus runtime.json beim Container-Start - Fallback: BRAIN_MODEL env → "claude-sonnet-4" Default - Bei Aenderung in Diagnostic: aria-brain restarten damit's greift (Hinweis steht in der UI) diagnostic/index.html - Section "Model" → "Sprachmodell (Brain)" - Hinweis-Block mit Default-Erklaerung und Restart-Hinweis - Modelle: claude-sonnet-4 (default), claude-opus-4, claude-haiku-4-5 Co-Authored-By: Claude Opus 4.7 (1M context) --- aria-brain/proxy_client.py | 21 ++++++++++++++++++- diagnostic/index.html | 14 ++++++++++--- diagnostic/server.js | 43 +++++++++++++++++++------------------- 3 files changed, 53 insertions(+), 25 deletions(-) diff --git a/aria-brain/proxy_client.py b/aria-brain/proxy_client.py index 8bf7a8e..d747a07 100644 --- a/aria-brain/proxy_client.py +++ b/aria-brain/proxy_client.py @@ -9,8 +9,10 @@ neuen CLI-Prozess (Cold-Start), das dauert. from __future__ import annotations +import json import logging import os +from pathlib import Path from typing import List, Optional import httpx @@ -18,11 +20,28 @@ from pydantic import BaseModel logger = logging.getLogger(__name__) -DEFAULT_MODEL = os.environ.get("BRAIN_MODEL", "claude-sonnet-4") +RUNTIME_CONFIG_FILE = Path("/shared/config/runtime.json") +ENV_MODEL = os.environ.get("BRAIN_MODEL", "claude-sonnet-4") PROXY_URL = os.environ.get("PROXY_URL", "http://proxy:3456") PROXY_TIMEOUT_SEC = float(os.environ.get("PROXY_TIMEOUT_SEC", "300")) +def _read_model_from_runtime() -> str: + """Liest brainModel aus runtime.json. Fallback: ENV BRAIN_MODEL.""" + try: + if RUNTIME_CONFIG_FILE.exists(): + data = json.loads(RUNTIME_CONFIG_FILE.read_text(encoding="utf-8")) + m = (data.get("brainModel") or "").strip() + if m: + return m + except Exception as exc: + logger.warning("runtime.json lesen fehlgeschlagen: %s", exc) + return ENV_MODEL + + +DEFAULT_MODEL = _read_model_from_runtime() + + class Message(BaseModel): role: str # "system" | "user" | "assistant" | "tool" content: Optional[str] = None diff --git a/diagnostic/index.html b/diagnostic/index.html index 8d514eb..7272334 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -659,13 +659,21 @@ selbst (Skills + skill_create Meta-Tool). Es gibt keine granulare Permission-Maske, Brain weiss zur Laufzeit welche Tools es hat. --> - +
-

Model

+

Sprachmodell (Brain)

+
+ Welches Claude-Model nutzt das Brain pro Anfrage. Wert wird in + /shared/config/runtime.json als brainModel persistiert. + Bei Aenderung: aria-brain restarten (Reparatur-Section oben), damit's greift. +

+ Verfuegbar via Proxy: claude-sonnet-4 (Default — schnell, gut), + claude-opus-4 (langsam, smarter), claude-haiku-4-5 (sehr schnell, kleiner Kontext). +
Aktives Model: - +
diff --git a/diagnostic/server.js b/diagnostic/server.js index cca1022..6ede9aa 100644 --- a/diagnostic/server.js +++ b/diagnostic/server.js @@ -65,6 +65,7 @@ const RUNTIME_CONFIG_FILE = "/shared/config/runtime.json"; const RUNTIME_CONFIG_FIELDS = [ "RVS_HOST", "RVS_PORT", "RVS_TLS", "RVS_TOKEN", "ARIA_AUTH_TOKEN", "WHISPER_MODEL", "WHISPER_LANGUAGE", + "brainModel", ]; function readRuntimeConfig() { const envDefaults = { @@ -2164,42 +2165,42 @@ async function handleRestartSession(clientWs) { // Claude Code laeuft mit --dangerously-skip-permissions (Alles oder Nichts). // Root-Check wird via CLAUDE_CODE_BUBBLEWRAP=1 in docker-compose.yml umgangen. -// ── Einstellungen: Model ──────────────────────────────── +// ── Einstellungen: Model (Brain) ──────────────────────── +// Liest/schreibt brainModel in /shared/config/runtime.json — Brain liest +// das beim Container-Start. Bei Aenderung: aria-brain restarten +// (Einstellungen → Reparatur → 🚨 aria-brain neu). -async function handleGetModel(clientWs) { +function handleGetModel(clientWs) { try { - const raw = await dockerExec("aria-core", `echo $DEFAULT_MODEL`); - clientWs.send(JSON.stringify({ type: "model_info", model: raw.trim(), info: "Aktuelles Model (ENV)" })); + const cfg = readRuntimeConfig(); + const model = (cfg.brainModel || "").trim() || "claude-sonnet-4"; + clientWs.send(JSON.stringify({ + type: "model_info", + model, + info: "Brain-Model (runtime.json) — bei Aenderung: aria-brain restarten", + })); } catch (err) { clientWs.send(JSON.stringify({ type: "model_info", error: err.message })); } } -async function handleSetModel(clientWs, model) { +function handleSetModel(clientWs, model) { if (!model || typeof model !== "string") { clientWs.send(JSON.stringify({ type: "model_info", error: "Kein Model angegeben" })); return; } try { - // Model in Settings speichern (OpenClaw liest das) - const settingsPath = await findSettingsFile(); - const script = [ - 'const fs=require("fs");', - `const f="${settingsPath}";`, - 'let s={};try{s=JSON.parse(fs.readFileSync(f,"utf8"));}catch(e){}', - `s.model=${JSON.stringify(model)};`, - `const dir=f.substring(0,f.lastIndexOf("/"));`, - 'try{fs.mkdirSync(dir,{recursive:true});}catch(e){}', - 'fs.writeFileSync(f,JSON.stringify(s,null,2));', - ].join(""); - const b64 = Buffer.from(script).toString("base64"); - await dockerExec("aria-core", `echo ${b64} | base64 -d | node`); - - clientWs.send(JSON.stringify({ type: "model_info", model, info: `Model auf "${model}" gesetzt (Neustart noetig)` })); - log("info", "server", `Model gesetzt: ${model}`); + writeRuntimeConfig({ brainModel: model.trim() }); + log("info", "server", `Brain-Model gesetzt: ${model.trim()}`); + clientWs.send(JSON.stringify({ + type: "model_info", + model: model.trim(), + info: `Model auf "${model.trim()}" gesetzt — aria-brain neu starten damit's greift`, + })); } catch (err) { clientWs.send(JSON.stringify({ type: "model_info", error: err.message })); } + return; } // OpenClaw-Config-Handler entfernt — aria-core ist raus.