mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
StartTurn persistait AVANT de lancer la génération : un marshal, puis deux commits bbolt (contenu, puis index), soit deux fsync et plusieurs ouvertures de base — 26-30 ms mesurés sur un NVMe Windows, bien plus sur un /mnt/user d'Unraid ou un disque de parité, payés à chaque message avant que la requête ne parte vers llama-server. Même facture au milieu d'un tour (vérification du mode Code) et pour chaque résultat d'outil coupé (« voir plus »). - chat_persist.go : un écrivain unique et ordonné. L'instantané reste pris sous c.mu (images → références, marshal, identifiant de la discussion) ; seule l'E/S part en différé. Le dernier instantané de chaque discussion l'emporte (numéro pris sous c.mu), les lots sont fusionnés en UNE transaction : contenu + index ensemble, résultats d'outils compris. - Seuls StartTurn, la persistance en cours de tour et les résultats d'outils sont asynchrones. Fin de tour, reset, bascules, compactage manuel restent synchrones et attendent tout ce qui précède ; la suppression écarte puis attend les écritures qui la visent (plus de discussion ressuscitée). - Discussion active gardée en RAM, créée sous verrou (plus de double identifiant sur base neuve) et changée sous c.mu avec le contenu : un instantané ne peut plus écrire l'ancien fil sous le nouvel identifiant. - « Voir plus » servi depuis la mémoire tant que le résultat n'est pas écrit ; verrouillage vérifié avant de rendre un id. - En plein tour, la base reçoit le journal sous sa forme de fin de tour (compactLog, version pure de compactLogLocked) ; la mémoire n'est pas touchée. - Vidage de l'écrivain avant redémarrage, « Quitter », exec et (dé)chiffrement. Le contexte vu par le modèle ne change pas : il lit c.Messages en mémoire, les résultats complets d'outils et la compaction du journal ne servent qu'à l'UI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.3 KiB
Go
65 lines
2.3 KiB
Go
//go:build windows
|
|
|
|
package loki
|
|
|
|
// sys_tray_windows.go — icône de Loki dans la zone de notification Windows (system
|
|
// tray). Quand on lance l'app (double-clic ou `loki app`), l'UI web s'ouvre dans
|
|
// le navigateur ET une petite icône apparaît près de l'horloge : elle montre que
|
|
// Loki tourne et offre un menu « Ouvrir Loki » / « Quitter ».
|
|
//
|
|
// getlantern/systray est pur Go sur Windows (Win32 via x/sys, aucun CGO) — le
|
|
// binaire reste statique. L'équivalent macOS vit dans sys_tray_darwin.go (Cocoa,
|
|
// donc CGO) ; les builds Linux ne touchent jamais systray.
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/getlantern/systray"
|
|
)
|
|
|
|
// runTray ouvre l'UI dans le navigateur puis fait tourner l'icône de la zone de
|
|
// notification. Bloque jusqu'à ce que l'utilisateur choisisse « Quitter ».
|
|
func runTray(url string) {
|
|
systray.Run(func() {
|
|
systray.SetIcon(trayIcon())
|
|
systray.SetTitle("Loki")
|
|
systray.SetTooltip("Loki — votre IA locale")
|
|
mOpen := systray.AddMenuItem("Ouvrir Loki", "Ouvrir l'interface")
|
|
systray.AddSeparator()
|
|
mQuit := systray.AddMenuItem("Quitter", "Arrêter Loki et décharger le modèle")
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case <-mOpen.ClickedCh:
|
|
_ = openBrowser(url)
|
|
case <-mQuit.ClickedCh:
|
|
systray.Quit()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}, func() {
|
|
// « Quitter » doit tout arrêter, moteur compris.
|
|
//
|
|
// Le moteur tourne dans un process DÉTACHÉ (voir svcStart) : il survit
|
|
// délibérément à la fermeture de l'app pour que le modèle reste chargé
|
|
// entre deux ouvertures de l'interface. Mais quand on quitte pour de
|
|
// bon, il n'a plus rien pour le piloter et garde des dizaines de Go de
|
|
// RAM, sans la moindre fenêtre pour l'expliquer. svcStop tue l'arbre
|
|
// (taskkill /T), donc llama-server avec lui.
|
|
//
|
|
// Windows seulement : ici l'app EST le propriétaire du moteur. Sous
|
|
// Linux et macOS c'est systemd ou launchd, et fermer une interface n'a
|
|
// pas à arrêter un service système.
|
|
_ = svcStop(false)
|
|
flushPersister(persistExitWait) // écritures différées de la discussion
|
|
os.Exit(0)
|
|
})
|
|
}
|
|
|
|
// trayIcon : l'icône de marque en .ico, deux tailles pour rester nette selon
|
|
// l'échelle d'affichage. Le rendu vit dans sys_brand_icon.go, partagé avec
|
|
// l'icône du .exe.
|
|
func trayIcon() []byte { return BrandICO(16, trayIconSize) }
|