Lot 16 : pilotage du moteur tenu par la façade (LOKI_ENGINE=rust)

La façade sert /api/start, /api/stop, /api/restart, /api/vram/unload et
/api/vram/reload quand LOKI_ENGINE=rust (expérimental ; le Go reste le
défaut). Elle lance elle-même « loki-rs engine <action> », le superviseur
que le Go appelait déjà en conteneur, avec l'environnement qu'il lui
passait et de quoi joindre l'API interne du Go ; sa dernière ligne
d'erreur devient l'erreur rendue. Le contrôle d'avant démarrage
(preflightEngine : preset externe, Strata, BIN, MODEL, tranches) et le
bilan de VRAM du déchargement (gpuSettle) sont portés.

La façade ne tient ce lot qu'en conteneur : sous systemd ou avec
LOKI_ENGINE_SUPERVISOR=go, loki-rs ne passe pas la variable au Go.

Restent au Go derrière son API interne (facade_engine.go) : le verrou de
l'optimiseur avant tout démarrage (/internal/v1/service/prestart), la
réponse en cours quand il tient la conversation
(/internal/v1/chat/generating) et l'arrêt de la dictée quand il la tient
(/internal/v1/dictate/stop).

Parité : parity_engine_test.go tire du Go dix bilans de VRAM, vingt-six
installations passées au préflight, les messages du superviseur et dix
réponses de route, rejoués par tests/enginectl.rs ; démarrage, arrêt,
redémarrage, déchargement chiffré et rechargement vérifiés de bout en bout
avec un faux superviseur et un faux nvidia-smi ; TestFacadeMoteur côté Go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
Claude committed 2026-10-15 18:33:31 +00:00
1 parent a50b8f3cc6
commit 2da2efc1fd
19 files changed
+2225 -2

No files matched your search

+21
View File
@@ -78,6 +78,12 @@ pub struct FakeGo {
pub tune_busy: Mutex<Option<String>>,
/// /internal/v1/preset/apply reçus : (chemin, mode).
pub preset_applies: Mutex<Vec<(String, String)>>,
/// /internal/v1/chat/generating : le Go écrit une réponse.
pub generating: Mutex<bool>,
/// /internal/v1/service/prestart reçus.
pub prestarts: Mutex<u32>,
/// /internal/v1/dictate/stop reçus.
pub dictate_stops: Mutex<u32>,
/// Comportement de /internal/v1/crypt/* (préfixe « SCELLE: » par défaut).
pub crypt_mode: Mutex<CryptMode>,
/// Réponse de /internal/v1/conv/workspace (None : 404).
@@ -336,6 +342,19 @@ async fn handle(st: Arc<FakeGo>, req: Request<Incoming>) -> Response<Full<Bytes>
),
None => resp(200, r#"{"busy":false}"#),
},
"/internal/v1/service/prestart" => {
*st.prestarts.lock().unwrap() += 1;
let e = st.tune_busy.lock().unwrap().clone().unwrap_or_default();
resp(200, serde_json::json!({ "error": e }).to_string())
}
"/internal/v1/chat/generating" => resp(
200,
serde_json::json!({ "generating": *st.generating.lock().unwrap() }).to_string(),
),
"/internal/v1/dictate/stop" => {
*st.dictate_stops.lock().unwrap() += 1;
resp(204, "")
}
"/internal/v1/preset/apply" => {
let body = req.into_body().collect().await.unwrap().to_bytes();
let v: serde_json::Value = serde_json::from_slice(&body).unwrap_or_default();
@@ -530,6 +549,7 @@ pub struct Opts {
pub push: Option<Arc<loki_rs::push::Push>>,
pub mem: Option<Arc<loki_rs::memory::Memory>>,
pub presets: bool,
pub engine_ctl: Option<Arc<loki_rs::enginectl::EngineCtl>>,
}
/// Comme [`start`], avec la conversation tenue par la façade
@@ -626,6 +646,7 @@ pub async fn start_with(
push: opts.push,
mem: opts.mem,
presets: opts.presets,
engine_ctl: opts.engine_ctl,
};
tokio::spawn(loki_rs::proxy::serve(fl, cfg, async move {
let _ = rx.await;