Lot 6 : la façade reçoit le chat du Go et ses événements

Une requête qui porte le jeton interne vient du Go, qui l'a déjà
authentifiée (tunnel du relais) : les routes du chat la servent sans
redemander la clé. L'API interne de la façade, réservée à ce jeton, reçoit
les événements d'affichage nés au Go (mode Code, critères) et le
rechargement après déverrouillage : une discussion chargée vide mémoire
verrouillée revient au déverrouillage, jamais par-dessus un fil rempli
(sinon le premier message aurait écrasé la discussion chiffrée).

Le relais par la façade de /api/chat/mode et /api/chat/criteria et les
critères rendus par l'outil disparaissent : le Go pousse ses événements
lui-même, une seule source quel que soit le chemin.

README : LOKI_CHAT=rust et ce qu'il ne prend pas encore en charge.

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 11:19:42 +00:00
1 parent 306c7a2f6c
commit ad46bb69a6
9 files changed
+175 -90

No files matched your search

+13
View File
@@ -26,6 +26,19 @@ pub struct Ctx {
pub engine: engine::Paths,
/// Conversation tenue par la façade (`LOKI_CHAT=rust`) ; `None` : au Go.
pub chat: Option<std::sync::Arc<crate::chat::generate::ChatService>>,
/// Jeton de l'API interne : une requête qui le porte vient du Go.
pub internal_token: String,
}
impl Ctx {
/// La requête vient du Go (jeton interne valide) : déjà authentifiée par
/// lui (tunnel du relais, redistribution E2E).
pub fn from_go(&self, headers: &HeaderMap) -> bool {
!self.internal_token.is_empty()
&& headers.get(crate::auth::INTERNAL_HEADER).is_some_and(|v| {
auth::constant_time_eq(v.as_bytes(), self.internal_token.as_bytes())
})
}
}
impl Ctx {