diff --git a/diagnostic/index.html b/diagnostic/index.html index 428aaec..4e71bda 100644 --- a/diagnostic/index.html +++ b/diagnostic/index.html @@ -602,6 +602,24 @@ selbst (Skills + skill_create Meta-Tool). Es gibt keine granulare Permission-Maske, Brain weiss zur Laufzeit welche Tools es hat. --> + + +

Sprachmodell (Brain)

@@ -659,8 +677,13 @@
Drei Kanäle, über die Claude Code zusätzlich zur eigentlichen - Anfrage Daten verschickt. Gesetzt wird in ~/.claude/settings.json — - greift bei jeder neuen Anfrage, kein Neustart nötig. + Anfrage Daten verschickt. +

+ ✓ Kein Neustart nötig. + Gesetzt wird in ~/.claude/settings.json, und die Claude-CLI liest + die Datei bei jedem Aufruf neu. Speichern genügt — die nächste Anfrage + nutzt die neue Einstellung. Nur ein gerade laufender Turn arbeitet noch + mit der alten, weil sein Prozess schon gestartet ist.

Davon unabhängig ist, ob Anthropic mit deinen Unterhaltungen Modelle trainiert — das steht in deinem Konto unter @@ -2748,6 +2771,26 @@ return; } + if (msg.type === 'proxy_patch_state') { + const box = document.getElementById('proxy-patch-warning'); + const det = document.getElementById('proxy-patch-detail'); + if (box) { + const stale = msg.stale || []; + box.style.display = stale.length ? 'block' : 'none'; + if (stale.length && det) { + const fmt = (ms) => new Date(ms).toLocaleString('de-DE', + { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' }); + det.innerHTML = + 'Diese Dateien wurden nach dem letzten Proxy-Start geändert — der Proxy ' + + 'arbeitet noch mit der alten Fassung:
' + + stale.map(s => '• ' + escapeHtml(s.file) + ' — geändert ' + + fmt(s.srcAt) + ', eingespielt ' + fmt(s.activeAt)).join('
') + + '

Der Proxy kopiert die Patches nur beim Start. ' + + 'Ein --build reicht nicht:'; + } + } + return; + } if (msg.type === 'privacy_flags') { renderPrivacyFlags(msg); return; } if (msg.type === 'privacy_flags_saved') { const st = document.getElementById('privacy-flags-status'); @@ -4754,6 +4797,7 @@ refreshVoiceIdStatus(); send({ action: 'get_attachment_limit' }); send({ action: 'get_privacy_flags' }); + send({ action: 'check_proxy_patches' }); } else if (tab === 'brain') { loadBrainStatus(); loadBrainMemoryList(); diff --git a/diagnostic/server.js b/diagnostic/server.js index 221d900..1dc00fc 100644 --- a/diagnostic/server.js +++ b/diagnostic/server.js @@ -3217,6 +3217,8 @@ wss.on("connection", (ws) => { handleSetModel(ws, msg.model); } else if (msg.action === "test_model") { handleTestModel(ws, msg.model); + } else if (msg.action === "check_proxy_patches") { + handleCheckProxyPatches(ws); } else if (msg.action === "get_privacy_flags") { handleGetPrivacyFlags(ws); } else if (msg.action === "set_privacy_flags") { @@ -3647,6 +3649,50 @@ function handleSetModel(clientWs, model) { return; } +// ── Laufen im Proxy die aktuellen Patches? ────────────────────────── +// +// Der Proxy kopiert proxy-patches/*.js beim START ueber den npm-Code (siehe +// docker-compose.yml, command:). Wer nach einem git pull nur `restart` macht — +// oder neu startet, BEVOR der Pull durch ist — laeuft still mit der alten +// Fassung weiter. Das faellt sonst nirgends auf: der Container ist "Up", die +// Oberflaeche sieht normal aus, nur wirkt die Aenderung nicht. +// +// Darum: Zeitstempel der Quelldateien gegen die eingespielten vergleichen. +const PROXY_PATCH_MAP = [ + ["routes.js", "server/routes.js"], + ["manager.js", "subprocess/manager.js"], + ["openai-to-cli.js", "adapter/openai-to-cli.js"], + ["cli-to-openai.js", "adapter/cli-to-openai.js"], +]; + +async function handleCheckProxyPatches(clientWs) { + try { + const dist = "/usr/local/lib/node_modules/claude-max-api-proxy/dist"; + const pairs = PROXY_PATCH_MAP + .map(([src, dst]) => `/proxy-patches/${src} ${dist}/${dst}`).join(" "); + // %Y = mtime als Unix-Zeit, %n = Dateiname + const out = await dockerExec("aria-proxy", `stat -c '%Y %n' ${pairs} 2>/dev/null || true`); + const mtime = {}; + for (const line of String(out || "").split("\n")) { + const m = line.trim().match(/^(\d+)\s+(.+)$/); + if (m) mtime[m[2]] = parseInt(m[1], 10); + } + const stale = []; + for (const [src, dst] of PROXY_PATCH_MAP) { + const a = mtime[`/proxy-patches/${src}`]; + const b = mtime[`${dist}/${dst}`]; + if (a == null || b == null) continue; + // Toleranz 5s: Quelle und Kopie entstehen beim Start kurz nacheinander. + if (a > b + 5) stale.push({ file: src, srcAt: a * 1000, activeAt: b * 1000 }); + } + clientWs.send(JSON.stringify({ type: "proxy_patch_state", stale })); + } catch (err) { + // Kein Alarm bei einem Pruef-Fehler — sonst steht da eine Warnung, die + // gar nichts ueber die Patches aussagt. + clientWs.send(JSON.stringify({ type: "proxy_patch_state", stale: [], error: String((err && err.message) || err) })); + } +} + // ── Einstellungen: Datenschutz-Schalter von Claude Code ───────────── // // Drei Kanaele, ueber die Claude Code von sich aus Daten an Anthropic bzw. an