From e93ab953507e81c997fc6a518427e61ae0051f6e Mon Sep 17 00:00:00 2001 From: Folzo Date: Sun, 2 Aug 2026 01:19:35 +0200 Subject: [PATCH] jean-router: detection a 3 niveaux - PC / Jean / Ollama MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PC: TCP connect (ON/OFF) → WoL uniquement si OFF - Jean: HTTP /api/presets (UP/DOWN) - Ollama: HTTP /api/version (UP/DOWN) - Dashboard: 3 lignes de statut distinctes - WoL ne se declenche que si PC OFF, pas si service DOWN --- jean-router/app.py | 65 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/jean-router/app.py b/jean-router/app.py index d381bcc..6371f02 100644 --- a/jean-router/app.py +++ b/jean-router/app.py @@ -146,16 +146,34 @@ def jean_alive() -> bool: alive = True break except ConnectionRefusedError: - alive = True # PC on, service down + alive = True break except (socket.timeout, OSError): - continue # PC off ou inaccessible + continue jean_alive_cache["alive"] = alive jean_alive_cache["timestamp"] = now return alive +def jean_service_ok() -> bool: + """Verifie que le service Jean repond (HTTP)""" + try: + r = requests.get(f"http://{JEAN_WEB_HOST}:{JEAN_WEB_PORT}/api/presets", timeout=3) + return r.ok + except Exception: + return False + + +def ollama_service_ok() -> bool: + """Verifie que le service Ollama repond (HTTP)""" + try: + r = requests.get(f"http://{OLLAMA_DIRECT_HOST}:{OLLAMA_DIRECT_PORT}/api/version", timeout=2) + return r.ok + except Exception: + return False + + def wait_for_jean(trigger_wol=True): """Attend que Jean soit accessible. Si ENABLE_WOL et trigger_wol, envoie WoL d'abord.""" alive = jean_alive() @@ -888,6 +906,9 @@ def chat_completions(): data, fwd_headers ) + if not jean_service_ok(): + log.warning(f"[Router] PC ON mais Jean DOWN, requete vers {model_id} risque d'echouer") + if not ensure_vram_for_backend("jean"): return jsonify({"error": "Failed to prepare VRAM for Jean"}), 503 @@ -994,13 +1015,9 @@ def dashboard(): @app.route("/api/dashboard/status") def dashboard_status(): """Etat complet en JSON""" - jean_ok = jean_alive() - olla_ok = False - try: - r = requests.get(f"http://{OLLAMA_DIRECT_HOST}:{OLLAMA_DIRECT_PORT}/api/version", timeout=2) - olla_ok = r.ok - except Exception: - pass + pc_alive = jean_alive() + jean_ok = jean_service_ok() if pc_alive else False + olla_ok = ollama_service_ok() if pc_alive else False try: r = requests.get(f"http://{JEAN_WEB_HOST}:{JEAN_WEB_PORT}/api/presets", timeout=1) @@ -1029,6 +1046,10 @@ def dashboard_status(): stats = dict(request_stats) return jsonify({ + "pc": { + "alive": pc_alive, + "host": JEAN_WEB_HOST, + }, "jean": { "alive": jean_ok, "host": f"{JEAN_WEB_HOST}:{JEAN_WEB_PORT}", @@ -1134,7 +1155,7 @@ h1{font-size:18px;color:var(--purple);margin-bottom:12px} .badge-blue{background:#1a2a3a;color:var(--blue);border:1px solid var(--blue)} #logs{grid-column:1/-1;height:400px;overflow-y:auto;font-size:12px;line-height:1.6;border:1px solid var(--border);border-radius:6px;padding:10px;background:#0a0e13} #logs .error{color:var(--red)} -#logs .warn{color:var(--yellow)} +#logs .warn{color:#f0883e;font-weight:500} #logs .info{color:var(--muted)} #logs .debug{color:#484f58} #logs .highlight{color:var(--green);font-weight:700} @@ -1157,10 +1178,11 @@ h1{font-size:18px;color:var(--purple);margin-bottom:12px}

🔌 Statut

-
Jean-
-
Ollama-
-
VRAM Backend-
-
Preset actif-
+
PC Gaming-
+
Jean (8090)-
+
Ollama (11434)-
+
VRAM-
+
Preset-

🎰 Slot Jean

@@ -1211,9 +1233,18 @@ async function fetchStatus() { const d = await r.json(); // Status dots - $('#jean-status').innerHTML = (d.jean.alive ? '' : '') + 'Jean : ' + d.jean.host; - $('#ollama-status').innerHTML = (d.ollama.alive ? '' : '') + 'Ollama : ' + d.ollama.host; - $('#vram-status').innerHTML = (d.jean.vram_backend === 'jean' ? 'JEAN' : 'OLLAMA'); + $('#pc-status').innerHTML = (d.pc.alive + ? ' ON' + : ' OFF — WoL requis'); + $('#jean-status').innerHTML = (d.jean.alive + ? ' UP' + : (d.pc.alive ? ' DOWN (PC ON)' : ' DOWN')); + $('#ollama-status').innerHTML = (d.ollama.alive + ? ' UP' + : (d.pc.alive ? ' DOWN (PC ON)' : ' DOWN')); + $('#vram-status').innerHTML = (d.jean.vram_backend === 'jean' + ? 'JEAN' + : 'OLLAMA'); $('#active-preset').innerHTML = '' + d.jean.active_preset + ''; // Slot