mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-23 15:08:16 +02:00
SIDE_SLOT et SLOT_PERSIST ne gardent plus la conversation au Go. La machinerie reste au Go (configuration, requêtes en vol, tampon du slot) ; la façade la consulte avant chaque requête au moteur local. Go : - /internal/v1/turn/slot (facade_slots.go) rend engineSlotFor et, pour une étape de tour, recharge d'abord l'état gardé de la discussion (slotPersistRestore). La sauvegarde à la bascule voit les étapes de la façade : /internal/v1/oai/served marque le slot (engineMarkMain). - facadeChatBlocker : SIDE_SLOT et SLOT_PERSIST retirés. Rust : - TurnHost::engine_slot : l'id_slot posé dans chaque requête (0 pour le fil de la discussion, 1 pour la vérification), le ticket « en vol » ouvert sur le second slot. - Cache KV plein en plein calcul (sideSlotPoolError) : rejoué deux fois tel quel, sans compaction, puis l'erreur. - Résumés de compaction comptés en vol comme postSummary : transcription sur le second slot, continuation sur le slot 0. - La passe de vérification est un travail annexe (engineSideJob) : le Go efface le slot à la fin s'il a servi (écart du lot 7 levé). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
4.0 KiB
4.0 KiB
Lot 31 — Slots du moteur pour le tour tenu par la façade
Contexte
Trois clés opt-in du moteur local gardaient la conversation au Go
(facadeChatBlocker), faute d'être honorées par la façade :
SIDE_SLOT(llm_sideslot.go) : un second slot pour les travaux annexes. Chaque requête de Loki porte sonid_slot: 0 pour le fil de la discussion (étape d'un tour, résumé en continuation), 1 pour le reste (vérification, résumé sur transcription). Un cache KV à court de place en plein calcul est rejoué tel quel, sans compaction : c'est la faute du voisin, pas un prompt trop long.SLOT_PERSIST(llm_slotpersist.go) : l'état du slot de la discussion est gardé sur disque à la bascule de preset, et rechargé avant la première requête de la discussion au retour.
Et l'isolation des travaux annexes (engineSideJob, CACHE_ISOLATE) : après
la passe de vérification du mode Code, le Go efface le slot local s'il a
servi. La façade la sautait (écart du lot 7), le Go ne voyant pas passer ses
requêtes.
Depuis la fusion de main, le Go voit passer chaque requête de la façade au
moteur local (tickets « en vol », /internal/v1/oai/begin, served, end).
La machinerie peut donc rester au Go ; il suffit que la façade la consulte.
Le lot
Go
/internal/v1/turn/slot(facade_slots.go) :- entrée :
{"conv":"…","main":true}; - sortie :
{"slot":0|1|-1}, la valeur d'engineSlotFor; - avec
mainetconv, recharge d'abord l'état gardé de la discussion (slotPersistRestore), comme la boucle Go avant une requête d'un tour.
- entrée :
- La sauvegarde à la bascule ne change pas. Le slot porte la discussion dès
que le moteur accepte une étape de son tour :
/internal/v1/oai/servedappelleengineMarkMain. SIDE_SLOTetSLOT_PERSISTne gardent plus la conversation.
Rust
TurnHost::engine_slot, appelé avant chaque requête. La boucle pose l'id_slotrendu dans le corps.- Le rejeu « cache KV plein » (
sideSlotPoolError) n'a lieu qu'avec un slot en service et un moteur local :- deux fois au plus, après l'attente des reprises réseau ;
- puis l'erreur telle quelle ;
- ni compaction ni réduction.
GoTurnHost:- moteur externe : aucun slot ;
- étape d'un tour :
mainavec la discussion (donc le rechargementSLOT_PERSIST) ; - vérification : le second slot, et le ticket « en vol » ouvert sur lui
(
side).
EngineSummarizer: un résumé est désormais compté en vol, commepostSummary. Il part sur le second slot s'il est fait sur la transcription, sur le slot 0 s'il est fait en continuation.- La passe de vérification est encadrée par
/internal/v1/engine/sidejob. À la fin, le Go efface le slot si le moteur a servi.
Tests
- Go (
facade_slots_test.go) :- sans la clé, aucun slot et
/propsjamais lu ; - fil de la discussion sur le 0, le reste sur le 1 ;
- second slot hors service ;
- rechargement une seule fois, pour la bonne discussion et une étape de tour seulement ;
- une étape de la façade acceptée par le moteur suffit à la sauvegarde ;
- corps illisible, GET refusé.
- sans la clé, aucun slot et
- La boucle du tour :
id_slotdans chaque requête, slot demandé avant chaque envoi ;- cache KV plein : rejoué deux fois sans compaction, puis l'erreur ;
- sans slot, ou moteur externe : un débordement comme un autre ;
- motif
sideSlotPoolErrorrepris des cas du Go.
- Le vrai hôte (
tests/lot6.rs) :- contrat du mode Code : le tour sur le 0, la vérification sur le 1 ;
- tickets ouverts sur le second slot, travail annexe ouvert puis rendu ;
- résumés : transcription sur le 1, continuation sur le 0, tickets rendus.
Écarts assumés
- Le rejeu « cache KV plein » se fie au slot demandé pour cette requête. Le Go
relit
sideSlotLiveau moment de l'erreur ; les deux lectures partagent le même cache de dix secondes. - Le slot est demandé avant de composer la requête, et non juste avant de l'envoyer : rien ne se passe entre les deux.