added check claude credentials in log server and changelog altered
This commit is contained in:
parent
f0b4e586c0
commit
c711899e4d
|
|
@ -11,7 +11,9 @@ Alle Änderungen am Projekt. Format: [Keep a Changelog](https://keepachangelog.c
|
||||||
**Diagnostic Container — Selbstcheck-UI**
|
**Diagnostic Container — Selbstcheck-UI**
|
||||||
- Neuer Container `aria-diagnostic` mit Web-UI auf Port 3001
|
- Neuer Container `aria-diagnostic` mit Web-UI auf Port 3001
|
||||||
- Status-Karten: OpenClaw Gateway, RVS, Claude Proxy — jeweils mit Dot-Indicator
|
- Status-Karten: OpenClaw Gateway, RVS, Claude Proxy — jeweils mit Dot-Indicator
|
||||||
- Claude Proxy Test: Prüft Erreichbarkeit (`/v1/models`) und sendet Test-Prompt an Claude
|
- Claude Proxy Test: Prüft Erreichbarkeit (`/v1/models`) und sendet Test-Prompt an Claude — zeigt verfügbare Modelle als Tags + `DEFAULT_MODEL` Hinweis für docker-compose.yml
|
||||||
|
- Auth-Check: "Auth prüfen" Button zeigt Inhalt von `/root/.config/claude/` im Proxy-Container (Dateien + `.credentials.json`) — per Docker Exec API
|
||||||
|
- Docker Exec API: Generische `dockerExec()` Funktion für Befehle in laufenden Containern (via Docker Socket)
|
||||||
- Chat-Test: Nachrichten direkt über Gateway oder via RVS senden
|
- Chat-Test: Nachrichten direkt über Gateway oder via RVS senden
|
||||||
- Tabbed Logs: Separate Tabs für Alle, Gateway, RVS, Proxy, Server — mit Zähler pro Tab
|
- Tabbed Logs: Separate Tabs für Alle, Gateway, RVS, Proxy, Server — mit Zähler pro Tab
|
||||||
- Autoscroll-Pause: Automatisch wenn hochgescrollt, "Nach unten" Button zum Fortsetzen
|
- Autoscroll-Pause: Automatisch wenn hochgescrollt, "Nach unten" Button zum Fortsetzen
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,9 @@
|
||||||
<div id="proxy-models-list" style="font-size:12px;line-height:1.6"></div>
|
<div id="proxy-models-list" style="font-size:12px;line-height:1.6"></div>
|
||||||
<div style="font-size:10px;color:#555570;margin-top:4px" id="proxy-models-hint"></div>
|
<div style="font-size:10px;color:#555570;margin-top:4px" id="proxy-models-hint"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="proxy-auth" style="margin-top:6px;display:none;background:#080810;border:1px solid #1E1E2E;border-radius:4px;padding:6px 8px;font-size:10px;line-height:1.5;max-height:120px;overflow-y:auto;white-space:pre-wrap;color:#8888AA"></div>
|
||||||
<button class="btn secondary" id="btn-proxy-test" onclick="testProxyBtn()" style="margin-top:6px">Proxy testen</button>
|
<button class="btn secondary" id="btn-proxy-test" onclick="testProxyBtn()" style="margin-top:6px">Proxy testen</button>
|
||||||
|
<button class="btn secondary" onclick="checkProxyAuth()" style="margin-top:6px">Auth pruefen</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -283,6 +285,12 @@
|
||||||
if (msg.models && msg.models.length) showProxyModels(msg.models);
|
if (msg.models && msg.models.length) showProxyModels(msg.models);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msg.type === 'proxy_auth') {
|
||||||
|
const el = document.getElementById('proxy-auth');
|
||||||
|
el.style.display = 'block';
|
||||||
|
el.textContent = msg.error ? `Fehler: ${msg.error}` : msg.info;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (msg.type === 'docker_logs') {
|
if (msg.type === 'docker_logs') {
|
||||||
showDockerLogs(msg);
|
showDockerLogs(msg);
|
||||||
return;
|
return;
|
||||||
|
|
@ -315,6 +323,10 @@
|
||||||
send({ action: 'test_proxy', text: 'Antworte mit genau einem Wort: Ping' });
|
send({ action: 'test_proxy', text: 'Antworte mit genau einem Wort: Ping' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkProxyAuth() {
|
||||||
|
send({ action: 'check_proxy_auth' });
|
||||||
|
}
|
||||||
|
|
||||||
function loadDockerLogs() {
|
function loadDockerLogs() {
|
||||||
if (!DOCKER_TABS.includes(activeTab)) return;
|
if (!DOCKER_TABS.includes(activeTab)) return;
|
||||||
send({ action: 'docker_logs', tab: activeTab, tail: 200 });
|
send({ action: 'docker_logs', tab: activeTab, tail: 200 });
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,15 @@ async function testProxy(prompt) {
|
||||||
log("info", "proxy", `Fuer docker-compose.yml (DEFAULT_MODEL): ${models.map(m => m.replace("openai/", "")).join(" | ")}`);
|
log("info", "proxy", `Fuer docker-compose.yml (DEFAULT_MODEL): ${models.map(m => m.replace("openai/", "")).join(" | ")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Schritt 1b: Auth-Dateien im Proxy-Container pruefen
|
||||||
|
try {
|
||||||
|
const authInfo = await dockerExec("aria-proxy", "ls -la /root/.config/claude/ 2>&1 && echo '---' && cat /root/.config/claude/.credentials.json 2>/dev/null | head -c 500 || echo '(keine .credentials.json)'");
|
||||||
|
log("info", "proxy", `Auth-Dateien im Container:\n${authInfo}`);
|
||||||
|
broadcast({ type: "proxy_auth", info: authInfo });
|
||||||
|
} catch (authErr) {
|
||||||
|
log("warn", "proxy", `Auth-Check fehlgeschlagen: ${authErr.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Schritt 2: Chat Completion testen (kurzer Prompt)
|
// Schritt 2: Chat Completion testen (kurzer Prompt)
|
||||||
const testPrompt = prompt || "Antworte mit genau einem Wort: Ping";
|
const testPrompt = prompt || "Antworte mit genau einem Wort: Ping";
|
||||||
log("info", "proxy", `Sende Test-Prompt: "${testPrompt}"`);
|
log("info", "proxy", `Sende Test-Prompt: "${testPrompt}"`);
|
||||||
|
|
@ -416,6 +425,18 @@ async function testProxy(prompt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkProxyAuth() {
|
||||||
|
try {
|
||||||
|
log("info", "proxy", "Pruefe Auth-Dateien im Proxy-Container...");
|
||||||
|
const authInfo = await dockerExec("aria-proxy", "echo '=== /root/.config/claude/ ===' && ls -la /root/.config/claude/ 2>&1 && echo '' && echo '=== .credentials.json ===' && cat /root/.config/claude/.credentials.json 2>/dev/null || echo '(nicht vorhanden)'");
|
||||||
|
log("info", "proxy", `Auth-Dateien:\n${authInfo}`);
|
||||||
|
broadcast({ type: "proxy_auth", info: authInfo });
|
||||||
|
} catch (err) {
|
||||||
|
log("error", "proxy", `Auth-Check fehlgeschlagen: ${err.message}`);
|
||||||
|
broadcast({ type: "proxy_auth", info: null, error: err.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Docker Container Logs ────────────────────────────────
|
// ── Docker Container Logs ────────────────────────────────
|
||||||
|
|
||||||
const CONTAINER_MAP = {
|
const CONTAINER_MAP = {
|
||||||
|
|
@ -476,6 +497,64 @@ async function handleDockerLogs(ws, tab, tail) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Docker Exec (Befehl in Container ausfuehren) ────────
|
||||||
|
|
||||||
|
function dockerExec(containerName, cmd) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const createBody = JSON.stringify({
|
||||||
|
AttachStdout: true, AttachStderr: true,
|
||||||
|
Cmd: Array.isArray(cmd) ? cmd : ["sh", "-c", cmd],
|
||||||
|
});
|
||||||
|
|
||||||
|
const createReq = http.request({
|
||||||
|
socketPath: "/var/run/docker.sock",
|
||||||
|
path: `/containers/${containerName}/exec`,
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(createBody) },
|
||||||
|
}, (res) => {
|
||||||
|
let data = "";
|
||||||
|
res.on("data", (c) => data += c);
|
||||||
|
res.on("end", () => {
|
||||||
|
if (res.statusCode !== 201) return reject(new Error(`Exec create: HTTP ${res.statusCode} — ${data.slice(0, 200)}`));
|
||||||
|
const execId = JSON.parse(data).Id;
|
||||||
|
|
||||||
|
// Exec starten
|
||||||
|
const startBody = JSON.stringify({ Detach: false });
|
||||||
|
const startReq = http.request({
|
||||||
|
socketPath: "/var/run/docker.sock",
|
||||||
|
path: `/exec/${execId}/start`,
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(startBody) },
|
||||||
|
}, (sRes) => {
|
||||||
|
const chunks = [];
|
||||||
|
sRes.on("data", (c) => chunks.push(c));
|
||||||
|
sRes.on("end", () => {
|
||||||
|
// Docker multiplexed stream: 8-byte header pro Frame
|
||||||
|
const raw = Buffer.concat(chunks);
|
||||||
|
const lines = [];
|
||||||
|
let offset = 0;
|
||||||
|
while (offset < raw.length) {
|
||||||
|
if (offset + 8 > raw.length) { lines.push(raw.slice(offset).toString("utf-8").trim()); break; }
|
||||||
|
const size = raw.readUInt32BE(offset + 4);
|
||||||
|
if (size === 0 || offset + 8 + size > raw.length) { lines.push(raw.slice(offset).toString("utf-8").trim()); break; }
|
||||||
|
const line = raw.slice(offset + 8, offset + 8 + size).toString("utf-8").trimEnd();
|
||||||
|
if (line) lines.push(line);
|
||||||
|
offset += 8 + size;
|
||||||
|
}
|
||||||
|
resolve(lines.join("\n"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
startReq.on("error", reject);
|
||||||
|
startReq.write(startBody);
|
||||||
|
startReq.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
createReq.on("error", reject);
|
||||||
|
createReq.write(createBody);
|
||||||
|
createReq.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ── Hilfsfunktionen ─────────────────────────────────────
|
// ── Hilfsfunktionen ─────────────────────────────────────
|
||||||
|
|
||||||
function waitForMessage(ws, timeoutMs) {
|
function waitForMessage(ws, timeoutMs) {
|
||||||
|
|
@ -529,6 +608,8 @@ wss.on("connection", (ws) => {
|
||||||
connectRVS();
|
connectRVS();
|
||||||
} else if (msg.action === "test_proxy") {
|
} else if (msg.action === "test_proxy") {
|
||||||
testProxy(msg.text);
|
testProxy(msg.text);
|
||||||
|
} else if (msg.action === "check_proxy_auth") {
|
||||||
|
checkProxyAuth();
|
||||||
} else if (msg.action === "docker_logs") {
|
} else if (msg.action === "docker_logs") {
|
||||||
handleDockerLogs(ws, msg.tab, msg.tail);
|
handleDockerLogs(ws, msg.tab, msg.tail);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue