Commit Graph
17 Commits
Author SHA1 Message Date
MichaelandClaude Opus 5.5 2bf388f7b7 Moteur : garde-fous de fidélité — un cache KV quantifié ou un cache approché se voit, Loki n'en pose jamais
Le cache KV en q8_0 d'un preset MoE vivait dans EXTRA_ARGS : ni l'avertissement
de lenteur ni la liste de l'interface ne le voyaient, qui affichait « f16 (max
qualité) » pendant que le moteur tournait en q8_0. Rien n'empêchait non plus un
--context-shift ou un --cache-reuse de modifier en douce ce que voit le modèle.
Aucun drapeau n'est ajouté ni retiré : on DIT ce que la ligne finale change.

- Type de cache effectif (effectiveKVTypes) : KV_TYPE*, puis -ctk/-ctv et
  --cache-type-k/v d'EXTRA_ARGS par-dessus, la dernière occurrence gagne comme
  dans llama-server. warnSlowKV le reçoit désormais.
- Note au lancement quand ce cache n'est pas f16 : q8_0 modifie légèrement les
  sorties, q4_0 perte mesurable, bf16 numérique différente. Avec -ot ou
  --n-cpu-moe, --fit ne tourne pas : repasser en f16 demandera sans doute de
  relever --n-cpu-moe. Pas d'estimation de VRAM sans les métadonnées du GGUF.
- Avertissement pour --context-shift (jamais --no-context-shift) et
  --cache-reuse N>0 ; --swa-full, sans perte, n'en déclenche aucun. Vision
  chargée : llama.cpp les ignore, on le précise.
- Interface : options du cache KV étiquetées, sous-titre qui montre le type
  effectif (« défini par EXTRA_ARGS ») et les drapeaux de cache approché.
- Tests : notes et type effectif en table, aucun -ctk/-ctv sans KV_TYPE, corps
  réels du chat et de la compaction sans cache_prompt:false ni n_cache_reuse,
  et ces clés réservées au benchmark dans tout le paquet (arbre syntaxique).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 23:04:08 +02:00
MichaelandClaude Opus 5.5 199d7f1e99 Chat : compactage sans redite, file multi-appareils, bascule par identifiant
Repris d'AJEAN 0.17.4.

- Compactage : la dernière demande du torse n'est plus réinjectée quand la
  queue contient déjà un message utilisateur (le modèle répondait une
  seconde fois à une vieille question), ni quand le résumé a échoué (elle
  est déjà dans le torse dégraissé et réapparaissait après ses propres
  résultats d'outils).
- Le texte écrit avant un appel d'outil n'est plus rangé deux fois dans
  l'historique du modèle (message tool_calls ET réponse finale) : du
  contexte gaspillé à chaque tour d'outil.
- Deux appareils qui envoient en même temps : le second message part en
  file au lieu d'un 409. Une tâche planifiée garde le refus.
- Un raisonnement qui reprend après du texte de réponse ouvre une nouvelle
  bulle sous la réponse au lieu de remplir l'ancienne, repliée au-dessus.
- Bascule de preset par identifiant : le numéro seul visait un autre
  preset quand la liste avait bougé sur un autre appareil. Le numéro reste
  accepté.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:21:18 +02:00
MichaelandClaude Opus 5.5 1db987844e Chargement du modèle : --mlock seul ne coupe plus le mmap
UN VRAI BUG D'ABORD
normalizeLoadFlags traduisait --mlock seul en « --load-mode mlock ». Or,
pour llama.cpp (common/arg.cpp), « mlock » veut dire PAS de mmap + résident :
le modèle entier montait en RAM au lieu d'être mappé. L'ancien --mlock, lui,
gardait le mmap — son équivalent est « mmap+mlock ». Sur un modèle plus gros
que la RAM (Qwen3.8-Flash-Next, 82 Go pour 64 Go), un preset qui avait
coché « Garder en RAM » tournait donc à l'OOM dès qu'un moteur récent
prenait le relais. Correspondance alignée sur AJEAN 0.16.0 :
  --mlock seul → mmap+mlock · --no-mmap → none · les deux → mlock.

DANS LES DEUX SENS
Un moteur ancien (ou un fork) ne connaît pas --load-mode et sort en erreur
si on le lui passe : downgradeLoadMode le retraduit en anciens drapeaux
(dio, inconnu de ces moteurs, est abandonné avec un avertissement).

UN SÉLECTEUR À LA PLACE DE DEUX INTERRUPTEURS
« Garder en RAM » et « Charger tout en mémoire » ne disaient pas leur
combinaison. L'éditeur de preset propose les six modes de llama.cpp (auto,
mmap, none, mlock, mmap+mlock, dio), avec ce que fait chacun en sous-titre,
et écrit la forme moderne. Un preset aux anciens drapeaux s'affiche sur le
bon mode sans modification.

Au passage, q5_1 porte la mention « lent sur CUDA » dans la liste du cache
KV (voir le commit du port occupé : non accéléré en Flash-Attention).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:05:34 +02:00
Claude 9bdaf00ca4 Modèles : un .gguf gardé se réutilise et s'efface
Un modèle téléchargé depuis l'éditeur d'un preset survit à la suppression
de ce preset (c'est voulu : on le réutilise ailleurs). Il devenait pourtant
inatteignable — impossible de refaire un preset dessus, impossible de
l'effacer.

Trois causes, trois correctifs.

1. « Le modèle existe déjà » n'est plus une erreur. La recherche Hugging
   Face proposait le quant, le clic lançait la sonde, et le téléchargement
   répondait en rouge « le modèle existe déjà » — fin du parcours. La sonde
   constate maintenant la présence du fichier (sans même sortir sur le
   réseau) et renvoie la valeur à écrire dans MODEL= : l'interface le
   SÉLECTIONNE, et la file continue (le projecteur vision, par exemple).
   Les quants déjà présents portent une pastille « déjà installé » dans la
   liste du dépôt, avant le clic.

2. Le sélecteur de modèle reconnaissait mal ce qu'il avait sous les yeux.
   /api/models comparait le dossier de chaque .gguf à LokiHome() alors que
   les téléchargements atterrissent dans $LOKI_HOME/models : la comparaison
   ne pouvait jamais être vraie. Conséquences : l'étiquette « dossier loki »
   ne s'affichait nulle part, et un preset écrit MODEL=modele.gguf
   s'affichait « introuvable ; ajoute son dossier ci-dessous » — le fichier
   étant juste à côté. Un nom simple est désormais résolu comme le fait le
   moteur : dossier de loki d'abord, puis les autres.

3. Une liste « Modèles installés », dans le groupe Modèle de l'éditeur.
   La route /api/models/delete existait depuis longtemps ; aucun bouton ne
   l'appelait. Le seul moment où un .gguf pouvait disparaître, c'était en
   cochant « supprimer aussi le fichier » à la suppression de son preset.
   La liste montre taille, dossier, tranches manquantes, et qui s'en sert :
   le modèle en service ne s'efface pas (le moteur l'a ouvert, la place ne
   serait même pas rendue), celui que des presets nomment prévient en les
   nommant puis obéit. La suppression dit ce qu'elle a libéré.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129sffVC43rezAXUMQuzUog
2026-09-12 20:20:33 +00:00
MichaelandClaude Fable 5 2d4f5378c0 Presets : modifier le preset en service l'applique aussitôt
CTX passé à 100000 dans l'éditeur, « enregistré »… et la carte du chat
qui affiche toujours 32768. Seul le fichier du preset changeait :
config.env gardait l'ancienne valeur, le moteur tournait avec, et plus
aucun preset n'était détecté actif (empreinte différente). Il fallait
penser à rebasculer dessus à la main.

SavePresetApplying décide AVANT l'écriture si le preset édité est celui
en service (empreinte de l'ancien fichier == configuration courante) ;
si oui, la nouvelle version est installée comme une bascule
(applyPresetFile : réglages machine et moteur préservés) et le service
redémarre en arrière-plan. Un preset inactif ou nouveau reste un simple
fichier. L'UI le dit et rafraîchit l'état — la jauge de contexte suit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFhcmBMUXdK6UesdGUgFPH
2026-08-30 17:13:19 +02:00
MichaelandClaude Fable 5 cfe70f2b70 Presets : un switch Raisonnement laissé sur off ne l'écrivait jamais
onchange ne part que sur une interaction : créer un preset et laisser
l'interrupteur décoché n'écrivait pas REASONING=, et la clé absente
laisse le moteur suivre le gabarit du modèle — il raisonnait malgré le
switch affiché sur off. À l'enregistrement, l'état de l'interrupteur
est désormais matérialisé : off explicite, ou on si aucune valeur active
plus précise (auto/deepseek) n'est déjà là.

Repris de l'amont AJEAN v0.12.1 (issue #46).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fwdmmVbvLHznF9v1npzN
2026-08-30 15:47:10 +02:00
MichaelandClaude Fable 5 b4f4135101 Presets : la section « Moteur » ne servait plus à rien
Depuis 6f6a321 le moteur est un réglage de machine : le preset ne
l'impose plus, la bascule garde le courant. En conteneur l'éditeur ne
proposait de toute façon qu'une seule case, « Image », que personne ne
pouvait changer — et le BIN figé dans le preset servait encore à lister
les cartes graphiques : un vieux preset interrogeait le moteur de
l'image au lieu du moteur mis à jour.

Le groupe disparaît de l'éditeur ; la liste des GPU interroge le moteur
courant (config_bin), mémorisé au préchauffage. CSS mort retiré.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fwdmmVbvLHznF9v1npzN
2026-08-30 15:44:55 +02:00
Claude 7f5765160d Jeton Hugging Face réglable dans l'interface
Le jeton ne vivait que dans la variable d'environnement HF_TOKEN : découvrir
depuis l'interface qu'un dépôt est verrouillé, c'était devoir éditer un
docker-compose et recréer le conteneur pour y répondre.

- Éditeur de preset → Modèle → « Jeton Hugging Face » : ligne repliée comme
  « Dossiers de modèles », qui affiche l'état (aucun / masqué / fourni par
  l'environnement). Le bandeau d'un dépôt verrouillé y mène d'un clic.
- Le jeton est VÉRIFIÉ auprès de /api/whoami-v2 avant d'être enregistré (le
  compte s'affiche) : un jeton mal collé accepté en silence rendrait le 401
  qu'on cherchait à expliquer. Il est rangé avec les secrets en base d'état, pas
  dans config.env que le changement de preset réécrit en bloc, et n'est jamais
  renvoyé en clair — seulement masqué.
- Priorité : jeton enregistré, puis HF_TOKEN. Rien d'enregistré = comportement
  d'avant à l'identique. L'enregistrement vide le cache des réponses obtenues
  sans jeton.
- Le jeton n'est envoyé qu'aux adresses Hugging Face : un lien collé vers un
  autre hébergeur n'a aucune raison de recevoir un secret.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hz1QWmvZqW3t53YC5SJBKC
2026-08-20 10:32:44 +00:00
Claude b339cced0a Dépôts Hugging Face verrouillés : dit lesquels, et pourquoi le 401
Un dépôt « gated » (orcarouter/Qwen3.8-27B-Uncensored-GGUF, vécu) laisse lire
son arborescence sans rien : Loki listait donc ses seize quantifications avec
leur verdict mémoire, puis échouait sur « HTTP 401 depuis la source » au
premier octet. Le message ne disait ni que le dépôt était verrouillé, ni qu'il
fallait accepter ses conditions, ni où poser un jeton.

- Le refus est maintenant traduit à partir de X-Error-Code (GatedRepo,
  RepoNotFound, EntryNotFound…) et nomme le dépôt, l'action à faire et l'état
  du jeton : absent (il en faut un) ou présent mais sans accès. 404, 416, 429
  et les pannes de la source y gagnent aussi une phrase utile.
- Le verrou se voit AVANT de choisir une quantification : la recherche demande
  `expand[]=gated` et la fiche du dépôt est lue à l'ouverture, d'où une
  pastille « accès restreint » dans la liste et un avertissement en toutes
  lettres au-dessus des fichiers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hz1QWmvZqW3t53YC5SJBKC
2026-08-20 10:18:55 +00:00
Claude 03ae361ade Synchronisation avec l'amont AJEAN (v0.9.5 → v0.10.7)
Le fork est parti de la v0.9.4 ; l'amont en est à la v0.10.7. Reprise de ce
qui manque VRAIMENT ici, en laissant de côté ce que loki a déjà résolu à sa
façon (contexte MTP via --parallel 1, jauge de contexte, chrono de tour,
vignettes d'images, ligne d'état de génération).

Rendu du chat cadencé puis lissé (amont v0.9.5 issue #24, v0.10.5). Chaque
token re-parsait le Markdown du bloc ENTIER : du O(n²) qui faisait ramer
l'interface sur un long raisonnement — le moteur débitait toujours autant, mais
les tokens semblaient arriver au ralenti et un simple rafraîchissement
« réparait » tout. Le texte s'accumule désormais et n'est re-rendu qu'à
intervalle adaptatif (16 ms sur un petit bloc, jusqu'à 500 ms sur un énorme),
soldé à chaque frontière (outil, bascule de rôle, fin de tour, erreur, rejeu).
Par-dessus, un lissage d'apparition découple l'arrivée de l'affichage : le
décodage spéculatif rend les tokens par rafales, le texte sautait par paquets ;
il s'écoule maintenant à cadence régulière. Rejeu exclu — relire un fil ne doit
pas être une lente réécriture.

Échantillonnage réglable par preset (amont v0.9.5/v0.9.6) : TEMP, TOP_P, TOP_K,
MIN_P, PRESENCE_PENALTY, REPEAT_PENALTY, injectés dans chaque requête (donc sans
redémarrage du moteur), vide = défaut du serveur. Sans ça seule la température
voyageait et le reste retombait sur les défauts de llama.cpp, rarement ceux que
recommande le modèle. Différence avec l'amont : REASONING_EFFORT n'est PAS
traité là — loki lui réserve un chemin plus riche, et l'écrire ici écraserait
`chat_template_kwargs`, donc la consigne « aucune ».

Un seul message système, en tête, à l'envoi (amont v0.9.8, issue #26).
steerSystem ne couvrait que les consignes de loki ; un historique venu
d'ailleurs peut encore en porter deux, et Qwen3.x en --jinja répond alors
« System message must be at the beginning ». Copie normalisée : l'historique
affiché et persisté garde sa forme.

Détection Vulkan multi-distro (amont issues #28, #29) : le chemin Debian codé en
dur est invisible sur Fedora/RHEL/Atomic, où le plan de build retombait sur le
CPU. ldconfig d'abord, puis les chemins connus.

Dossier de travail (amont v0.10.2) : la consigne dit maintenant ce que le
dossier EST — l'endroit par défaut de tout ce que le modèle produit — et nomme
les dossiers système à ne pas toucher, au lieu d'interdire vaguement d'en sortir.

Non repris : les tâches planifiées (~1200 lignes + interface, à décider), et le
quoting cmd.exe par .bat temporaire (loki tourne en conteneur Linux).
2026-08-20 09:31:59 +00:00
MichaelandClaude Opus 5 b405adea6c Jauge de contexte, espace disque sur partage agrégé, panneau Fichiers
Trois défauts sans rapport entre eux, tous visibles à l'écran.

Jauge de contexte bloquée à « 0 / N (0 %) » : le comptage exact vient de
usage.prompt_tokens (include_usage), qu'un llama-server récent a cessé de
renvoyer. On note désormais si l'usage est arrivé ; sinon la fin de tour
publie l'estimation qui pilote déjà la compaction — approximative, mais
jamais absente. Et la souscription envoie la valeur courante juste après
le rattrapage : une page rechargée affichait zéro sur une discussion
pourtant pleine, faute d'événement ctx_used dans la fenêtre rejouée.

Espace disque : « il ne reste que 11,9 Go » sur un partage Unraid qui en
a des centaines. /mnt/user est servi par shfs, un FUSE qui agrège
plusieurs disques — statfs y renvoie l'espace d'un seul, et ce chiffre
REFUSAIT l'installation du modèle. Les systèmes de fichiers qui
approximent (FUSE, overlay, NFS, CIFS, Ceph, Gluster) sont reconnus par
leur magie : leur chiffre reste affiché, précédé d'un « ~ », mais ne
bloque plus rien.

Panneau Fichiers : le panneau entier défilait, emportant vers le haut
l'en-tête, le fil d'Ariane et le pied (occupation disque, bouton .zip)
dès qu'il y avait quelques fichiers. Seule la liste défile maintenant ;
le pied reste en bas et l'état vide se centre.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 08:28:53 +02:00
MichaelandClaude Opus 5 7ef2c956c5 Chargement du modèle : pourcentage visible ; interface allégée
La pastille « chargement… » restait identique de longues minutes sur un
gros GGUF — indiscernable d'un plantage. llama-server n'expose aucun
progrès, mais charger c'est LIRE le fichier : on rapporte les octets lus
par le process (/proc/<pid>/io, shards compris) à la taille du modèle et
la pastille affiche « chargement 43 % » (rafraîchie toutes les 5 s,
plafonnée à 99 — c'est /health qui dit prêt).

Carte Moteur : bouton « vérifier la version » retiré — « mettre à jour »
fait sa propre vérification et dit s'il n'y a rien de neuf.

Éditeur de preset : en conteneur, l'option de moteur « Personnalisé »
disparaît (rien à compiler dans l'image, la mise à jour passe par la
carte Moteur) ; un BIN non reconnu retombe sur le moteur de l'image.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 23:19:21 +02:00
MichaelandClaude Opus 5 0a3af60715 Intensité du raisonnement dans la barre de saisie, angles moins arrondis
Le niveau de raisonnement n'existait que dans l'éditeur de preset : le changer
demandait d'ouvrir les réglages, éditer, enregistrer. Or ça se décide au moment
d'écrire le message.

- Nouvelle route /api/reasoning-effort (GET/POST), calquée sur /api/memory :
  elle écrit REASONING_EFFORT dans la config vivante, relue à chaque requête au
  moteur. Aucun redémarrage — la valeur voyage dans le corps de la requête.
- Liste blanche côté serveur : cette clé finit dans une requête au moteur, on
  n'y laisse pas passer une chaîne arbitraire venue du navigateur.
- La liste est grisée quand le raisonnement est coupé pour ce modèle, plutôt que
  masquée : le réglage reste trouvable, et l'infobulle dit où le rallumer.
- L'éditeur de preset garde le même réglage comme DÉFAUT du modèle. Appliquer un
  preset réécrit toute la config, donc il reprend la main sur le choix fait à la
  volée — les deux sous-titres le disent, sinon la double présence intrigue.

Angles : les rayons allaient de 5 à 26px selon les composants, ce qui donnait
des cartes très rondes. Tout est ramené à 4px (cartes, boutons, modales) et 3px
(petits éléments), y compris les formes multi-valeurs comme la barre de saisie
(26px 26px 0 0 → 3px 3px 0 0). Les pastilles (999px) et les ronds (50%) sont
laissés intacts : ce sont des interrupteurs et des avatars, pas des cartes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 10:31:37 +02:00
MichaelandClaude Opus 5 847aad217b MCP : catalogue embarqué de serveurs connus
Ajouter un serveur MCP demandait d'écrire soi-même `npx -y @scope/paquet …`
dans la modale, en devinant le nom du paquet. Le catalogue liste une vingtaine
de serveurs connus, commande déjà renseignée, classés par catégorie.

- internal/loki/mcp_catalog.json est EMBARQUÉ dans le binaire (go:embed), pas
  interrogé sur le réseau : Loki tourne hors ligne, et rien de ce qui s'exécute
  sur la machine ne vient d'un annuaire distant. Pour proposer un serveur de
  plus : éditer le fichier et recompiler.
- Choisir une entrée n'installe rien. Ça préremplit la modale d'ajout existante
  et l'utilisateur relit la commande avant d'enregistrer — un serveur stdio
  exécute un process arbitraire, au même titre que l'outil bash du mode agent.
  Aucune ligne de mcp_client.go n'est touchée : le catalogue s'arrête à
  l'affichage, tout le reste passe par l'API MCP déjà en place.
- Une entrée dont le runtime manque (npx ou uvx absent) le signale dans la
  liste, plutôt que de laisser l'utilisateur découvrir l'échec au démarrage du
  serveur.
- Les entrées qui réclament une clé d'API la rappellent avant l'enregistrement,
  au lieu d'enregistrer un serveur qui ne peut pas se connecter.
- Les entrées Python publiées avant le SDK MCP 2.0 sont épinglées avec
  `uvx --with "mcp<2"` : sans cela elles plantent sur ImportError: McpError.
- Le Dockerfile gagne uv/uvx (~35 Mo). Sans lui, 9 des 21 entrées s'affichent
  sans pouvoir démarrer dans le conteneur.

Intensité du raisonnement (REASONING_EFFORT)

L'interrupteur Raisonnement était binaire. llama-server accepte
`reasoning_effort` dans /v1/chat/completions : `none` coupe le raisonnement,
toute autre valeur est passée au gabarit jinja du modèle.

- Nouvelle clé de preset REASONING_EFFORT — donc réglée par modèle, comme le
  reste du preset. Vide = on n'envoie rien et le gabarit garde son comportement.
- Pas de repli à prévoir : un gabarit qui ne lit pas la valeur l'ignore sans
  erreur. En pratique seuls gpt-oss et apparentés changent de comportement, et
  le sous-titre du réglage le dit — promettre un effet universel serait faux.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 10:06:14 +02:00
Claude 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
2026-08-16 11:02:35 +00:00
Loki 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.
2026-08-15 08:37:48 +00:00
Loki 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.
2026-08-14 21:33:15 +00:00