mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-12 09:47:20 +02:00
276a8287cbfb45b7c3774ae88eea4ee2132b2fd7
16
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
276a8287cb |
Refonte : modèle chargé, attribution, ombres, flèche, favicon
Retours sur la refonte, cinq corrections. Modèle affiché Le sélecteur de l'en-tête ne montrait que le PRESET actif — or un preset n'est « actif » que si son empreinte correspond exactement à la configuration. Une configuration écrite à la main, héritée de l'image ou modifiée d'un cran depuis le dernier preset n'en désigne aucun, et l'en-tête restait muet alors qu'un modèle tournait. Il retombe désormais sur le nom du fichier de la configuration active (loadCfg le lui donne), et l'infobulle porte le chemin complet. Attribution « fork de AJEAN » revient sous le nom de l'app, dans l'en-tête de la barre latérale, au lieu du pied de la zone défilante. Ombres Les bulles du fil et la carte de saisie portent une vraie ombre douce (--shadow-card), comme la maquette — le filet de 1 px ne les décollait pas du fond. Bouton d'envoi Chevron sauge sur fond transparent, à la place de la pastille verte pleine : c'est le dessin de la maquette, et il suit alors la même charte que ses voisins (dépôt, fichiers). Favicon Carré sauge (#5E7F5A) au lieu du carré noir, aux quatre endroits qui le dessinent : favicon SVG, icône d'accueil iOS, icône du .exe (icon.ico) et PNG macOS — tous rendus depuis sys_brand_icon.go, seule source du dessin. La variante « template » de macOS reste noire : le système ne lit que son alpha. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd |
||
|
|
f99e5b59b8 |
Refonte de l'interface : direction « Sober Tech »
Reprise du design d'après la maquette fournie, sans changer d'architecture : l'UI reste du HTML/CSS/JS assemblé dans le binaire (voir plus bas). Charte - Palette ardoise + sauge en remplacement des bruns « Terre ». Deux variantes : claire par défaut (celle de la maquette) et « Deep Dark » (fond #0F172A, cartes #1E293B), à un clic depuis l'en-tête. Une variable --on-accent porte ce qui s'écrit sur les aplats de sauge, pour que le contraste tienne dans les deux variantes. - Typographie Inter (interface) + JetBrains Mono (code, chiffres, chemins), en sous-ensemble latin, embarquées comme l'étaient Bricolage et IBM Plex Mono — toujours aucune requête vers un service de polices. - Boutons sans contour, fond au survol, léger enfoncement au clic. - Coque à plat : plus de cartes flottantes séparées par une gouttière, la barre latérale est collée au bord et le fil occupe tout le reste. Coque - Barre d'en-tête : titre de la discussion + sélecteur de modèle. Changer de preset demandait d'ouvrir la barre latérale et de descendre jusqu'aux presets ; c'est désormais une liste déroulante, toujours visible. - Barre latérale en trois zones — marque, contenu défilant, moniteur machine — et escamotable d'un clic sur grand écran. Les discussions y passent au premier plan, avec une recherche textuelle (filtrage côté client : la liste est déjà chargée, sans les messages) ; les réglages descendent sous un repli unique, d'où openDetails(), qui déplie aussi les parents. - Moniteur machine en pied de colonne : une jauge par ressource (charge GPU, puis VRAM et température en détail, mémoire vive), sauge jusqu'à 75 %, ambre puis rouille quand la machine sature. Il remplace la section « Machine », qui disait la même chose en plus verbeux et en plus loin. - L'option « barre latérale escamotable » disparaît d'Apparence : elle faisait de la barre un tiroir posé SUR la conversation, là où le bouton d'en-tête l'escamote pour de bon. Deux mécanismes concurrents pour la même intention. Fil et saisie - La réponse de l'IA redevient une carte, la question un aplat de sauge : sur un fond de fil coloré, du texte nu flottait sans ancrage. - Saisie en pilule, ses outils (joindre, fichiers, envoyer) dans la barre elle-même. L'envoi est une pastille ronde à flèche ; le mot « Envoyer » reste porté par aria-label et l'infobulle. Corrections croisées - L'heure d'une discussion prenait la moitié de la ligne (flex:1 hérité de `.preset>span`), le titre était tronqué au premier mot. - Une liste déroulante posée directement dans une ligne de modale débordait sous son intitulé quand sa valeur était longue (chemin de destination). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd |
||
|
|
001d633750 |
Un dossier de fichiers par discussion
Les fichiers du chat vivaient dans un pot commun : on changeait de discussion et on revoyait les mêmes pièces jointes, et supprimer une discussion laissait derrière elle tout ce qu'on y avait déposé ou fait écrire à l'agent (seules ses captures, déjà rangées par identifiant, partaient avec). Chaque discussion a désormais son dossier, <workspace>/discussions/<id>/ : - les dépôts (uploads/), les captures (captures/) et ce que l'agent écrit y atterrissent ; le shell et les chemins relatifs du modèle y sont résolus ; - le panneau Fichiers s'ouvre sur ce dossier et n'en sort pas, et se redessine quand la discussion change (bascule ou vidage, signalés par le flux SSE) ; - supprimer une discussion — ou la vider — emporte ses fichiers. Les deux gestes le disent maintenant avant de demander confirmation ; « clear chat » en demandait aucune. La racine du dossier de travail reste la borne de sécurité : les liens des anciens messages (uploads/x.pdf, captures/<id>/y.jpg) continuent d'ouvrir leur fichier par un chemin de repli. Au démarrage, une migration range les captures dans le dossier de leur discussion et rend chaque dépôt à la discussion qui le mentionne dans son journal ; ce que personne ne réclame reste à la racine, atteignable par le bouton « hors discussion » du panneau, qui disparaît une fois le ménage fait. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LPyFxVHNAN9u5pVzSYMwjd |
||
|
|
00b9cc2aee |
Panneau Fichiers : accéder à ce que l'agent écrit
L'agent produit des rapports, des scripts, des exports et des captures dans son dossier de travail. On ne pouvait en récupérer un que si le modèle avait pensé à en mettre le lien dans sa réponse : tout ce qu'il écrivait sans le dire restait invisible, et faire le ménage demandait un shell. Un panneau de droite, ouvert et fermé par le bouton dossier du pied de carte, liste ce dossier avec navigation dans les sous-dossiers, téléchargement et suppression. Il pousse la conversation au lieu de la recouvrir — la largeur de lecture étant pilotée par --measure, le fil se resserre et se recentre tout seul. Sur téléphone c'est un tiroir, comme les réglages à gauche. Le socle existait : /api/chat/file téléchargeait déjà, workspaceRel bornait déjà les chemins, downloadWorkspaceFile gérait déjà le blob. Manquaient les deux verbes qui comptent, /api/chat/files pour lister et /api/chat/file/delete pour supprimer. Trois choix qui méritent d'être dits : - Un dossier affiche la taille de TOUT son contenu, pas celle de son inode : c'est ce qu'on libère en le supprimant, donc c'est le chiffre qui aide à décider. Le parcours est borné à 20 000 entrées pour que la liste reste instantanée si l'agent y dézippe quelque chose d'énorme. - La racine du dossier de travail est refusée à la suppression : l'agent y perd le dossier dans lequel il écrit, et « tout effacer » ne doit pas être à un clic. La suppression d'un dossier annonce le nombre de fichiers et le poids emportés avant de demander confirmation. - Le panneau ne se remplit qu'à l'ouverture. Un ReadDir récursif à chaque chargement de page pour un panneau fermé serait payé par tout le monde. Ouvrir le panneau rétrécit la conversation SANS déclencher de `resize` : la gouttière de barre de défilement mesurée dans --sbw resterait celle de l'ancienne largeur et la carte de saisie serait décalée du fil. On resynchronise donc explicitement ; la hauteur, elle, est déjà suivie par un ResizeObserver. Vérifié. Six tests Go sur le bornage, qui est la partie sensible — ces routes suppriment sur disque à partir d'un chemin venu du navigateur : « .. », chemins absolus, racine, et un lien symbolique posé dans le dossier de travail sont tous refusés, et le fichier voisin survit. Puis au navigateur, en clair et en sombre : listing trié dossiers d'abord, taille récursive, descente et fil d'Ariane, téléchargement réel (l'événement download porte bien rapport.md), suppression confirmée puis disparition de la ligne, persistance de l'état ouvert, tiroir mobile avec voile, et la saisie reste alignée au pixel sur le fil (0 px des deux côtés) une fois le panneau ouvert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VueWA9xcYadaYq65tBisix |
||
|
|
133b30421a |
Postes distants : retirer le bouton oublié du composeur
Le retrait de l'accès distant s'était arrêté à mi-chemin. La section « Accès distant » de la barre latérale et son module 13-remote.js ont bien disparu au commit |
||
|
|
26e93f43ef |
Chercher et installer un modèle depuis Loki
Installer un modèle demandait d'aller sur huggingface.co, de naviguer dans l'arborescence d'un dépôt et de coller un lien à la main. Rien ne disait si le fichier tiendrait en mémoire, et surtout rien ne reliait un modèle à SON projecteur vision : c'est ainsi qu'un mmproj-Qwen3VL-8B s'est retrouvé configuré pour un Qwen3.8-27B — deux modèles sans rapport, moteur qui démarre et ne voit rien. La recherche Hugging Face arrive dans l'éditeur de preset. Elle ne remonte que les dépôts GGUF ; déplier un dépôt montre ses quantifications avec leur taille et un verdict mémoire, et propose le projecteur vision DU MÊME DÉPÔT — le seul qui corresponde. Quand le dépôt n'en publie pas, Loki le dit au lieu d'aller en chercher un ailleurs. Le nouveau code ne télécharge rien : il produit des URL que le chemin existant consomme tel quel (normalizeHFURL, shardURLSet, sonde d'espace disque, reprise et annulation). Une file d'attente enchaîne modèle puis projecteur — le serveur ne mène qu'un transfert à la fois, et le champ Vision ne se remplit que si le modèle est déjà sélectionné. Trois familles de .gguf cohabitent dans un dépôt et ne veulent pas dire la même chose : mmproj-* (projecteur), mtp-* (poids de décodage spéculatif) et le modèle. Les deux premières ressemblent à un modèle ; les proposer en vrac, ce serait offrir de lancer llama-server sur un encodeur d'images. Les tranches d'une famille sont repliées en une entrée de taille TOTALE : annoncer 15 Go pour un modèle qui en occupe 45 promet une place qui n'existe pas. Le verdict mémoire s'appuie enfin sur le GPU. detectHardware() ne renvoyait que la RAM système alors que detectGPUs() existait déjà : sur un serveur à carte NVIDIA, le verdict se prononçait sur la mauvaise grandeur. Le coût du cache KV reste une estimation assumée — l'exact demanderait de parser l'en-tête GGUF — et l'interface l'annonce comme telle plutôt que d'afficher un chiffre faussement sûr. Le catalogue ajean.link disparaît. Sa route n'avait aucun consommateur (l'écran d'accueil qu'elle attendait n'a jamais existé), son repli embarqué proposait du Qwen2.5 de 2024, et un fork qui laisse le serveur de l'amont décider de ce qu'il propose n'est pas vraiment un fork. Une piste écartée en cours de route : marquer les dépôts « vision » d'après les tags Hugging Face. Ils mentent — des deux dépôts GGUF de Qwen3.8-27B qui publient tous deux un mmproj, seul ggml-org est taggé image-text-to-text. Une pastille sur l'un et pas sur l'autre aurait été pire que rien. La vision est donc déduite de la seule source qui ne se trompe pas : la présence d'un mmproj-*.gguf dans l'arborescence. Vérifié : 8 tests unitaires sur les arborescences réelles des deux dépôts, puis au navigateur contre le vrai Hugging Face — 25 dépôts trouvés, 3 quants listés sans aucun mtp ni mmproj, projecteur Q8_0 proposé et coché, verdicts affichés avec leur explication, modale dans l'écran. L'ordre de la file (modèle puis projecteur) est testé en interceptant les appels, sans transfert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VueWA9xcYadaYq65tBisix |
||
|
|
1fa8452e44 |
Le fil ne passe plus sous la carte de saisie
Sur écran large, la fin de la conversation était recouverte par la carte de
saisie et aucun défilement ne la ramenait : le fil réservait 8 px sous lui
là où le composeur en occupe ~160.
styles.css réservait bien la hauteur (#chat{padding-bottom:170px}), mais deux
règles POSTÉRIEURES dans la feuille — ajoutées par le redesign « Terre » puis
par le correctif de largeur de lecture — réécrivaient `padding` en raccourci
sous @media (min-width:721px), ce qui remet padding-bottom à la valeur du
raccourci. Sous 721 px la règle en raccourci est déclarée AVANT, d'où un bug
invisible sur mobile. Ces règles passent en longhands (padding-top +
padding-inline), et un commentaire dit pourquoi le raccourci est proscrit ici.
La réserve devient mesurée au lieu d'être devinée : syncComposer() publie
--composer-h (hauteur réelle du composeur) via un ResizeObserver, à côté de
syncGutter() qui fait déjà ce travail pour --sbw. Une constante redevenait
fausse dès que la saisie grandit ou qu'une pièce jointe s'affiche. Le
scrollbtn suit la même variable. env(safe-area-inset-bottom) disparaît du
calcul : il est déjà dans la hauteur mesurée, le compter deux fois creusait
un trou en PWA iOS.
Le voile de fondu au-dessus de la carte s'exprimait en % de la hauteur TOTALE
du composeur : l'opacité pleine tombait sous le bord haut de la carte, et le
texte restait lisible au ras du bord — l'impression de « passer derrière ».
Une variable --fade pilote désormais la bande réservée ET la course du
dégradé, qui devient donc opaque exactement au bord de la carte.
Mesuré au navigateur, du 380 px au 2000 px, au repos / saisie 10 lignes /
pièce jointe en attente : écart de 46 à 52 px partout. En réinjectant
l'ancienne règle : -119 px, bug reproduit. La largeur de lecture est
inchangée (1080 px de contenu à 2000 px de fenêtre).
Barre latérale : la discussion sélectionnée porte un cadre sauge complet et
fin (1 px) au lieu d'un liseré de 3 px sur le seul bord gauche. La bordure
transparente est portée par tous les états, la sélection ne décale donc pas
le contenu.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VueWA9xcYadaYq65tBisix
|
||
|
|
3740b881a8 |
Hauteur : bulles techniques en rangée, sections groupées, accès distant retiré
Trois gains de place, mesurés au navigateur en 1500×900. - Raisonnement, outils et mémoire se posent CÔTE À CÔTE dans une rangée qui déborde à la ligne : un tour d'agent en enchaîne parfois dix, et empilées elles repoussaient la réponse hors de l'écran alors qu'elles ne portent qu'une étiquette tant qu'elles sont repliées. Mesuré : 8 bulles occupent 2 lignes au lieu de 8. Dépliée, une bulle reprend toute la largeur — son contenu ne doit pas être comprimé dans une colonne étroite. - Les sections de la barre latérale sont réunies en DEUX cartes (réglages d'IA / réglages d'application) au lieu d'une carte chacune : onze arrondis et autant de gouttières faisaient déborder la colonne. Mesuré : 876 px de contenu pour 876 px visibles — plus d'ascenseur. - Section « Accès distant » supprimée, ainsi que son module JS (13-remote.js) et son chargement : elle pilotait le tunnel ajean.link, sans objet ici. Le code serveur du relais reste en place mais inerte (aucun jeton) : le retirer créerait des conflits à chaque reprise de l'amont. |
||
|
|
c90a2d86eb |
Largeur de lecture : suivre le panneau au lieu d'une colonne étroite centrée
Sur un écran large, le fil se réduisait à ~590 px de texte entouré de vide : la mesure était plafonnée à 760 px et centrée sur la fenêtre, alors que la charte fait courir le texte sur toute la largeur du panneau. Elle était en plus codée à TROIS endroits avec des valeurs différentes (450 / 380 / 360 px), donc condamnée à diverger entre le fil et la carte de saisie. Une seule variable --measure les pilote désormais tous les deux. La borne haute reste : au-delà, l'œil perd le début de la ligne suivante. 1080 px ≈ 110 caractères — large, mais encore lisible. Mesuré au navigateur en 2000 px : réponse 1050 px (contre 589), question 788 px (75 %, conforme à la charte), carte de saisie alignée sur le fil. |
||
|
|
e7a3bcca1f |
Direction « Terre » : nouvelle identité visuelle
Reprise de la maquette fournie (LOKI — direction Terre) : bruns chauds, vert sauge, argile, et des surfaces en CARTES arrondies séparées par une gouttière au lieu d'une colonne à filets. - Palette transposée sur les jetons EXISTANTS (--bg, --panel, --accent…) et non par réécriture des 1200 lignes : les 300 usages de variables suivent d'eux-mêmes. Rôles clarifiés — sauge = sélection et action, argile = chiffres et avertissements, terre cuite = arrêt et danger. - Polices Bricolage Grotesque + IBM Plex Mono EMBARQUÉES dans le binaire et servies par Loki (/fonts/), pas par Google Fonts : une instance locale ou coupée d'internet doit s'afficher correctement, sans qu'un tiers apprenne qui consulte l'interface. Sous-ensemble latin, 106 Ko au total. - Structure en cartes : barre latérale en pile de cartes, colonne de chat en panneau unique, carte de saisie posée un ton au-dessus. Liseré sauge sur la discussion active, bulle de question au coin bas-droit rentré. - Bouton d'envoi en sauge : il reprenait --text, donc un brun indistinct du reste ; l'arrêt reste en terre cuite. Bornage au bureau (min-width:721px) : sur téléphone la barre latérale est un tiroir plein écran et le fil occupe toute la largeur — des cartes n'y grignoteraient que des pixels utiles. Vérifié au navigateur, thèmes clair ET sombre, plus un rendu 390 px : polices réellement chargées (200 sur les trois woff2), aucun débordement horizontal, tiroir mobile inchangé. |
||
|
|
72a8925cb4 |
Avatars et prénoms : les afficher pour de bon (ils étaient masqués par le CSS)
Les libellés étaient bien construits — mon test précédent vérifiait le HTML
produit, pas le style appliqué — mais la feuille de style les masquait tous :
#chat .msg .label{display:none}
C'était un choix justifié de l'amont, où le libellé ne disait que « user » ou
« assistant », deux mots que l'alignement des bulles rend redondants. Depuis
qu'ils portent un avatar et un prénom, ils identifient réellement
l'interlocuteur : on les réaffiche pour user et assistant, en ligne et
discrets, aligné à droite côté question. Les bulles techniques non repliables
restent muettes.
Vérifié dans un navigateur : display=flex, boîte non vide, textes rendus
« 🙂 Michael » et « 🦊 Loki » — cette fois sur le style calculé et sur une
capture d'écran, pas seulement sur le DOM.
|
||
|
|
6fe94b9a8d |
Captures de pages web (Playwright) affichées dans le fil
Outil web_screenshot : Chromium piloté par Playwright photographie une page RENDUE (JavaScript exécuté) dans le dossier de travail, et rend au modèle la ligne markdown exacte à recopier — lui laisser composer l'URL reviendrait à lui faire inventer un chemin, donc une image cassée. INDÉPENDANT DE LA VISION, souvent confondu : visionEnabled() (clé MMPROJ) ne décide que d'une chose, l'envoi d'images AU MODÈLE. Capturer et afficher ne passent pas par le modèle — sans projecteur, l'agent photographie sans regarder, ce qui suffit à illustrer une conversation. - route /api/chat/image : sert UNIQUEMENT des images du dossier de travail, en ligne. handleChatFile force le téléchargement de tout pour qu'un .html du modèle ne s'exécute pas dans l'origine de l'UI ; ici la même règle est tenue autrement — type déduit du CONTENU (pas de l'extension), nosniff, et CSP default-src 'none'. Un faux .png contenant du HTML est refusé en 415. - UI : une balise <img> ne peut pas porter d'en-tête Authorization, or /api/* exige la clé dès qu'elle est définie. Les images sont donc récupérées par fetch authentifié puis posées en blob:. - l'outil n'est déclaré au modèle QUE si Playwright est réellement présent : annoncer un outil absent envoie le modèle en boucle de réessai. - Node 22 (NodeSource) au lieu du Node 18 d'Ubuntu, exigé par Playwright et par la plupart des serveurs MCP. PLAYWRIGHT=0 bâtit une image sans navigateur. - CONFIG ACTIVE affichait « llama.cpp personnalisé » pour le moteur de l'image : il annonce maintenant « llama.cpp de l'image ». Description de l'outil tenue au plus court : TestSystemPromptStaysLean a attrapé le dépassement du budget de préambule (7888 car pour 7500). Vérifié dans l'image : capture réelle d'une page, servie en image/png avec CSP ; faux PNG rejeté (415) ; évasion du workspace bloquée (403). Playwright ajoute 816 Mo à l'image. |
||
|
|
54c5eb1334 |
Identité dans le chat, section Paramètres, logo agrandi
- Identité : prénom et avatars (emoji) affichés en tête des bulles, à la place des libellés « user » / « assistant ». Stockés dans les préférences SERVEUR, donc partagés entre appareils comme le thème. La liste d'emojis est servie par /api/prefs : pas de seconde copie côté client. Validation stricte — prénom nettoyé de ses caractères de contrôle et borné à 24 runes, avatar refusé s'il n'est pas dans la liste fermée. - Barre latérale : séparateur « Paramètres » qui regroupe Identité, Apparence, Accès OpenAI, Accès distant et Actions, sous les réglages d'IA (Machine, Presets, Mode agent, System prompt, Moteur). Un séparateur plutôt qu'un second niveau de repli, illisible dans une colonne aussi étroite. - Logo : 10 → 17 px, il était minuscule sur un écran dense. Le prénom vient de l'utilisateur : les libellés sont écrits en textContent, jamais en innerHTML. |
||
|
|
2fbf86cdde |
Historique : plusieurs discussions, et mise à jour par l'image en conteneur
L'amont ne connaît qu'un fil unique (bkChat/conversation) que « clear chat »
effaçait définitivement. On garde toute la machinerie (un seul conv en
mémoire, mêmes flux SSE, même compactage) mais rangée par discussion :
bkChat/index liste des discussions (métadonnées seules)
bkChat/active discussion ouverte, partagée par tous les appareils
bkChat/conv:<id> état complet d'une discussion
Basculer réutilise le mécanisme d'epoch du reset : les abonnés SSE reçoivent
{reset:true} et rejouent le nouveau fil — aucun code de rendu à toucher. Le
fil unique existant est repris comme première discussion au premier
démarrage, et sa clé d'origine est laissée intacte.
- routes /api/conversations (liste, new, switch, rename, delete)
- barre latérale : liste (titre déduit du 1er message, date, nb d'échanges),
bouton +, renommer, supprimer ; lignes construites en DOM et non en
innerHTML, les titres venant de messages utilisateur
- suppression de la dernière discussion : convCreate et non convNew, qui
aurait réenregistré celle qu'on vient d'effacer
Le bouton « Vérifier les mises à jour » répondait « GitHub a répondu 404 » :
il interrogeait les releases du dépôt du fork, qui n'en publie aucune. En
conteneur, remplacer le binaire n'a de toute façon pas de sens — l'UI, l'API
et la CLI renvoient désormais « docker compose pull ».
Vérifié en conteneur : création, bascule, renommage (titre accentué avec
< > &), suppression de l'active puis de la dernière ; /api/update et
loki update renvoient la note Docker.
|
||
|
|
1f24d8ccf5 |
Sélecteur de moteur par modèle : « Image » en conteneur, et mention du fork
Le sélecteur de l'éditeur de modèle proposait encore « Précompilé » et « Compilé » — deux installations que Loki ne fait pas en conteneur : cliquer répondait « installez d'abord llama.cpp… ». Pire, le moteur de l'image ne correspondant à aucun des deux, il était classé « Personnalisé ». En conteneur, ces deux options laissent place à « Image » (sélectionnée par défaut, y compris pour un preset sans BIN) ; « Personnalisé » reste pour un binaire déposé dans /data/backends. Le moteur de l'image est désormais déclaré par l'image elle-même via LOKI_ENGINE_BIN (Dockerfile + entrypoint) au lieu d'être deviné d'après le chemin : /api/llamacpp expose provided et provided_bin. Attribution : sous le nom Loki, « fork de AJEAN » avec lien vers le dépôt d'origine. Vérifié dans l'image : provided=true, provided_bin=/app/llama-server, BIN semé identique ; build, vet et tests verts. |
||
|
|
de6551a153 |
Rebaptise AJEAN en Loki (fork, lignée conservée)
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki) - LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ; units loki-engine / loki-ui ; binaire et aide CLI - updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les binaires AJEAN amont) Conservé à l'identique : le domaine ajean.link (service de tunnel amont), les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et LICENSE (historique et licence de l'amont). go build/vet/test : verts. |