added claude cli log and test and optimize log windows through seperate tabs, update readme changelog

This commit is contained in:
2026-03-12 01:25:35 +01:00
parent b3a2fd7092
commit 2e4a12c812
5 changed files with 301 additions and 45 deletions
+72
View File
@@ -27,11 +27,13 @@ const RVS_PORT = process.env.RVS_PORT || "443";
const RVS_TLS = process.env.RVS_TLS || "true";
const RVS_TLS_FALLBACK = process.env.RVS_TLS_FALLBACK || "true";
const RVS_TOKEN = process.env.RVS_TOKEN || "";
const PROXY_URL = process.env.PROXY_URL || "http://proxy:3456";
// ── State ───────────────────────────────────────────────
const state = {
gateway: { status: "disconnected", lastError: null, handshakeOk: false },
rvs: { status: "disconnected", lastError: null },
proxy: { status: "unknown", lastError: null },
};
const logs = [];
let gatewayWs = null;
@@ -340,6 +342,73 @@ function sendToRVS(text) {
return true;
}
// ── Claude Proxy Test ────────────────────────────────────
async function testProxy(prompt) {
state.proxy.status = "testing";
state.proxy.lastError = null;
broadcastState();
log("info", "proxy", `Teste Proxy: ${PROXY_URL}`);
try {
// Schritt 1: Erreichbarkeit pruefen
const healthUrl = `${PROXY_URL}/v1/models`;
log("info", "proxy", `Rufe ab: ${healthUrl}`);
const modelsRes = await fetch(healthUrl, {
headers: { "Authorization": "Bearer not-needed" },
signal: AbortSignal.timeout(10000),
});
if (!modelsRes.ok) {
throw new Error(`Models-Endpoint: HTTP ${modelsRes.status} ${modelsRes.statusText}`);
}
const modelsData = await modelsRes.json();
const modelCount = modelsData.data?.length || 0;
log("info", "proxy", `Proxy erreichbar — ${modelCount} Model(s) verfuegbar`);
// Schritt 2: Chat Completion testen (kurzer Prompt)
const testPrompt = prompt || "Antworte mit genau einem Wort: Ping";
log("info", "proxy", `Sende Test-Prompt: "${testPrompt}"`);
const chatRes = await fetch(`${PROXY_URL}/v1/chat/completions`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer not-needed",
},
body: JSON.stringify({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: testPrompt }],
max_tokens: 200,
}),
signal: AbortSignal.timeout(30000),
});
if (!chatRes.ok) {
const errBody = await chatRes.text().catch(() => "");
throw new Error(`Chat-Completion: HTTP ${chatRes.status}${errBody.slice(0, 300)}`);
}
const chatData = await chatRes.json();
const reply = chatData.choices?.[0]?.message?.content || "(leer)";
log("info", "proxy", `Antwort: "${reply.slice(0, 200)}"`);
state.proxy.status = "connected";
state.proxy.lastError = null;
broadcastState();
broadcast({ type: "proxy_result", ok: true, reply });
} catch (err) {
log("error", "proxy", `Fehler: ${err.message}`);
state.proxy.status = "error";
state.proxy.lastError = err.message;
broadcastState();
broadcast({ type: "proxy_result", ok: false, error: err.message });
}
}
// ── Hilfsfunktionen ─────────────────────────────────────
function waitForMessage(ws, timeoutMs) {
@@ -391,6 +460,8 @@ wss.on("connection", (ws) => {
connectGateway();
} else if (msg.action === "reconnect_rvs") {
connectRVS();
} else if (msg.action === "test_proxy") {
testProxy(msg.text);
}
} catch {}
});
@@ -407,6 +478,7 @@ server.listen(HTTP_PORT, "0.0.0.0", () => {
log("info", "server", `Gateway: ${GATEWAY_URL}`);
log("info", "server", `Token: ${GATEWAY_TOKEN ? GATEWAY_TOKEN.slice(0, 8) + "..." : "(keiner)"}`);
log("info", "server", `RVS: ${RVS_HOST ? `${RVS_HOST}:${RVS_PORT}` : "(nicht konfiguriert)"}`);
log("info", "server", `Proxy: ${PROXY_URL}`);
// Verbindungen aufbauen
connectGateway();