mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-19 05:07:20 +02:00
Lot 9 : dictée vocale tenue par la façade (LOKI_DICTATE=rust)
La façade sert /api/transcribe et /api/dictate/* quand LOKI_DICTATE=rust (expérimental ; le Go reste le défaut) et supervise elle-même le serveur de transcription sherpa-onnx : lancé à la demande sur la boucle locale, GPU masqués et sans le jeton interne, prêt dès que sa socket répond, mort au démarrage expliquée, éteint après dix minutes d'inactivité ou quand les réglages changent. Modèles Parakeet téléchargés et décompressés au fil de l'eau (tar.bz2, entrées hors du dossier refusées, liens ignorés), protocole WebSocket identique (en-tête de 8 octets, trames de 10 Kio). Côté Go, facade_dictate.go remet ces routes à la façade quand elles arrivent par le tunnel du relais, et asrShutdownVite (libération de la VRAM, optimiseur) lui demande l'arrêt par l'API interne. Parité : parity_dictate_test.go tire du Go la lecture de treize WAV, les chemins d'archive, réglages, catalogue, arguments et treize appels de route, rejoués par tests/dictate.rs ; supervision testée contre un faux sherpa-onnx qui parle le protocole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
21 files changed
+2699
-19
No files matched your search
@@ -427,7 +427,7 @@ async fn handle(st: Arc<FakeGo>, req: Request<Incoming>) -> Response<Full<Bytes>
|
||||
/// Lance le faux Go puis la façade devant lui ; rend (adresse de la façade,
|
||||
/// état du faux Go, garde d'arrêt).
|
||||
pub async fn start(home: std::path::PathBuf) -> (SocketAddr, Arc<FakeGo>, oneshot::Sender<()>) {
|
||||
let (f, st, tx, _) = start_opts(home, false, None, None).await;
|
||||
let (f, st, tx, _) = start_with(home, Opts::default()).await;
|
||||
(f, st, tx)
|
||||
}
|
||||
|
||||
@@ -437,10 +437,36 @@ pub async fn start_models(
|
||||
home: std::path::PathBuf,
|
||||
hf: &str,
|
||||
) -> (SocketAddr, Arc<FakeGo>, oneshot::Sender<()>) {
|
||||
let (f, st, tx, _) = start_opts(home, false, None, Some(hf.to_string())).await;
|
||||
let opts = Opts {
|
||||
models_hf: Some(hf.to_string()),
|
||||
..Opts::default()
|
||||
};
|
||||
let (f, st, tx, _) = start_with(home, opts).await;
|
||||
(f, st, tx)
|
||||
}
|
||||
|
||||
/// Comme [`start`], avec la dictée tenue par la façade (`LOKI_DICTATE=rust`).
|
||||
pub async fn start_dictate(
|
||||
home: std::path::PathBuf,
|
||||
d: Arc<loki_rs::dictate::Dictation>,
|
||||
) -> (SocketAddr, Arc<FakeGo>, oneshot::Sender<()>) {
|
||||
let opts = Opts {
|
||||
dictate: Some(d),
|
||||
..Opts::default()
|
||||
};
|
||||
let (f, st, tx, _) = start_with(home, opts).await;
|
||||
(f, st, tx)
|
||||
}
|
||||
|
||||
/// Ce que la façade tient en plus du proxy.
|
||||
#[derive(Default)]
|
||||
pub struct Opts {
|
||||
pub chat: bool,
|
||||
pub engine_port: Option<u16>,
|
||||
pub models_hf: Option<String>,
|
||||
pub dictate: Option<Arc<loki_rs::dictate::Dictation>>,
|
||||
}
|
||||
|
||||
/// Comme [`start`], avec la conversation tenue par la façade
|
||||
/// (`LOKI_CHAT=rust`) ; `engine_port` : port du faux moteur (config PORT).
|
||||
pub async fn start_chat(
|
||||
@@ -452,15 +478,21 @@ pub async fn start_chat(
|
||||
oneshot::Sender<()>,
|
||||
Arc<loki_rs::chat::generate::ChatService>,
|
||||
) {
|
||||
let (f, st, tx, chat) = start_opts(home, true, Some(engine_port), None).await;
|
||||
let (f, st, tx, chat) = start_with(
|
||||
home,
|
||||
Opts {
|
||||
chat: true,
|
||||
engine_port: Some(engine_port),
|
||||
..Opts::default()
|
||||
},
|
||||
)
|
||||
.await;
|
||||
(f, st, tx, chat.unwrap())
|
||||
}
|
||||
|
||||
async fn start_opts(
|
||||
pub async fn start_with(
|
||||
home: std::path::PathBuf,
|
||||
with_chat: bool,
|
||||
engine_port: Option<u16>,
|
||||
models_hf: Option<String>,
|
||||
opts: Opts,
|
||||
) -> (
|
||||
SocketAddr,
|
||||
Arc<FakeGo>,
|
||||
@@ -468,7 +500,7 @@ async fn start_opts(
|
||||
Option<Arc<loki_rs::chat::generate::ChatService>>,
|
||||
) {
|
||||
let st = Arc::new(FakeGo::default());
|
||||
if let Some(p) = engine_port {
|
||||
if let Some(p) = opts.engine_port {
|
||||
st.set("config", "PORT", &p.to_string());
|
||||
}
|
||||
let l = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -489,7 +521,7 @@ async fn start_opts(
|
||||
});
|
||||
}
|
||||
});
|
||||
let chat = if with_chat {
|
||||
let chat = if opts.chat {
|
||||
use loki_rs::chat::{
|
||||
conv::Conversation, generate::ChatService, host::ChatShared, sessions,
|
||||
};
|
||||
@@ -517,12 +549,13 @@ async fn start_opts(
|
||||
service: "loki-engine".into(),
|
||||
},
|
||||
chat: chat.clone(),
|
||||
models: models_hf.map(|hf| {
|
||||
models: opts.models_hf.map(|hf| {
|
||||
Arc::new(loki_rs::models::Models {
|
||||
downloads: Arc::new(loki_rs::downloads::Downloads::new()),
|
||||
hf: loki_rs::hf::HfClient::new(&hf),
|
||||
})
|
||||
}),
|
||||
dictate: opts.dictate,
|
||||
};
|
||||
tokio::spawn(loki_rs::proxy::serve(fl, cfg, async move {
|
||||
let _ = rx.await;
|
||||
|
||||
Reference in new issue
Block a user