À vide, l'app chauffait le CPU en continu : trois sondages navigateur
séparés (5/8/10 s) tournaient en permanence, y compris onglet caché, et
chaque tick relançait un sous-processus nvidia-smi (cache TTL 5 s = la
cadence, donc jamais efficace) plus deux connexions vers Ollama.
- Nouveau /api/system/pulse : statut + ressources + modèles chargés en
UNE requête (appels Ollama en parallèle, dégradation propre si muet),
avec un cache court qui absorbe les rafales multi-onglets.
- Front : un seul sondage, SUSPENDU quand l'onglet est caché, cadence
adaptative (4 s pendant un flux, 20 s au repos) et rafraîchissement
immédiat au retour sur l'onglet.
- Panneau Matériel : 5 s -> 15 s et rien onglet caché.
- Caches serveur alignés sur la cadence : nvidia-smi mis en cache 12 s,
et _all_local_gpus (vue Matériel) n'était pas caché du tout.
Effet au repos : ~25 requêtes/min et ~12 nvidia-smi/min -> ~3 et ~3
onglet visible, et ZÉRO onglet caché. Le serveur n'a aucune boucle de
fond : sans navigateur ouvert, il ne consomme plus rien.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Un plan « from scratch » (architecture, création des fichiers…) était
régénéré à CHAQUE tâche de code, y compris pour corriger un bug sur une
appli existante — hors-sujet et perturbant (« je n'arrive pas à déplacer
les pièces » → plan de re-création complète).
- want_plan ne se déclenche plus que pour une NOUVELLE construction :
pas de code antérieur dans la session ET workspace vide. Une
modification / correction / suite de travail n'affiche plus de plan.
- Plan de code : l'étape ARCHITECTURE privilégie un seul fichier
autonome (cohérent avec les contraintes appli web), au lieu de
proposer index.html + style.css + app.js.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Les modèles promettaient des libs qui ne se chargent jamais hors-ligne
(Stockfish, CDN…), éclataient le code en fichiers incohérents, puis
déclaraient « ça marche » sans rien vérifier.
- Contraintes « appli web » injectées pour toute tâche web (agent +
moteur code) : UN seul index.html autonome (CSS/JS inline), AUCUNE
ressource externe (implémenter en JS natif à la place), rendu réel au
chargement, interdiction de « simuler » une lib en la disant réelle.
- check_html signale désormais les scripts/styles externes (CDN/WASM)
qui ne se chargeront pas dans le sandbox hors-ligne, en plus des
références locales cassées.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
L'agent termine son tour pour attendre la validation, donc le streaming
s'arrête aussitôt — or la carte de confirmation n'était affichée que
pendant le streaming, elle disparaissait avant qu'on puisse cliquer.
- La carte de validation shell s'affiche tant que `pendingShell` existe,
indépendamment de l'état de streaming (approbation/refus déjà gérés
hors flux).
- Changer de session efface une validation en attente (elle appartenait
à la session quittée).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Adapte github.com/DietrichGebert/ponytail (philosophie anti
sur-ingénierie) en méthode transverse de Loki, remède direct aux rendus
trop ambitieux qui cassent (ex. « moteur IA » dans un jeu d'échecs).
- Échelle de décision injectée pour toute tâche de code (YAGNI ->
réutiliser -> natif -> minimum de code), sur les DEUX chemins : dans
le contexte de l'agent ET dans la consigne du moteur code (Aider ne
voit pas convo).
- Nouvel interrupteur « Ponytail (code minimal) » dans Réglages >
Intelligence, activé par défaut (fusionne sans migration).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- make_plan(code=True) : pour une tâche d'application, produit un plan
d'IMPLÉMENTATION concret (étape 1 = architecture/fichiers, puis une
fonctionnalité testable à la fois), réaliste et sans dépendance
externe — au lieu d'une liste d'objectifs produit (« moteur IA »…)
que les petits modèles n'arrivent pas à livrer.
- run_shell : le garde-fou de confinement ne bloque plus les URLs
(http://localhost:8080 était rejeté à cause du « // »), et autorise
la base du workspace même quand la session cible un projet (ls
/workspace). Les évasions réelles (/etc, /config, ~, ../..) restent
bloquées.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Le plan s'affichait mais restait figé — on ne voyait pas le modèle
avancer. Désormais :
- Le modèle annonce chaque étape accomplie (« ✅ Étape N terminée »),
demandé dans la consigne de plan.
- L'agent détecte ces annonces dans le flux et émet des événements
plan_step, sans jamais recompter deux fois la même étape.
- Le panneau PLAN coche les étapes en temps réel : ✓ vert + barré pour
les faites, sablier sur l'étape en cours, compteur « n/N validées ».
Chemin agent uniquement (le moteur code tourne de bout en bout). Les
messages passés restent affichés tels quels.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
La mémoire long-terme rappelait des échanges d'AUTRES sessions dans la
discussion en cours : demander « un jeu d'échecs » ressortait une « appli
sport » demandée ailleurs, et déroutait les petits modèles.
- rag_enabled désactivé par défaut : chaque discussion ne se souvient que
d'elle-même (résumé + messages récents, déjà en place).
- Migration v7 : désactive le RAG une fois sur les installs existantes
(la valeur persiste en base /data) ; réactivable dans Réglages.
- Rappel plus strict quand le RAG est activé : seuil de similarité 0.45 -> 0.6.
- Réglages : libellé clarifié (« Mémoire entre sessions »).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- edit_file : correspondance tolérante (indentation/espaces ignorés,
repli ligne à ligne + réindentation) pour que les petits modèles
éditent sans devoir tout réécrire ; message d'erreur plus utile.
- Prompt système : privilégier edit_file pour modifier, write_file
seulement pour créer ; rappel de rester dans le workspace.
- Suppression de fichiers/dossiers du workspace : route DELETE
/api/files + boutons × dans l'arborescence (fichiers et dossiers).
- Confinement renforcé : garde-fou run_shell (refus des chemins absolus
hors workspace, ~ et remontées ../) et code_task/Aider (fnames
résolus et confinés au workspace).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Le chip modèle du composer était décoratif (pastille orange fixe) alors
que le TopBar montrait le vrai état de chargement. Le sélecteur complet
(liste + pastille GPU/CPU/à charger/préchargement) vit maintenant dans
la carte du chat, menu vers le haut.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
La relance après « pensée seule » n'agissait qu'à la fin de la
génération : un modèle thinking pouvait ruminer des minutes (jusqu'à
épuiser num_predict) avant qu'elle n'intervienne — vécu comme « aucune
réponse » en mode plan.
Pensée > 12 000 caractères sans aucun contenu ni appel d'outil : la
génération est interrompue immédiatement et la relance repart.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Les noms MCP à tirets (resolve-library-id) cassaient le tool-calling :
modèles et grammaires mélangent tirets et underscores -> « Tool not
found ». Les noms exposés sont assainis en underscores avec table de
correspondance vers le vrai nom, et l'appel tolère les deux formes.
read_file sur un dossier disait « fichier introuvable » : message
explicite « c'est un dossier — utilise list_dir ».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le fallback SPA renvoyait index.html pour /favicon.svg : l'icône
n'apparaissait jamais. Les fichiers statiques racine existants sont
maintenant servis tels quels, le reste retombe sur index.html.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le déplacement de la préparation (plan, recall RAG) dans le flux SSE
laissait un silence total pendant le chargement d'un gros modèle : le
reverse proxy coupait la connexion (« Connexion interrompue pendant le
chargement du modèle »). Avec la réflexion active, l'appel de plan
laissait en plus le modèle penser — silence encore plus long.
- ping SSE toutes les 10 s pendant la préparation du contexte
- plan / auto-critique / résumé : think=False (repli automatique si le
modèle refuse le paramètre) — un appel utilitaire ne réfléchit jamais
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avec la réflexion activée sur les longues tâches, le modèle brûlait tout
son budget de génération à penser : done sans contenu ni appel d'outil,
la boucle s'arrêtait et la tâche restait inachevée.
- itération « réflexion seule » : relance avec consigne d'agir ; si ça
recommence, think est coupé pour la fin du tour (+ notice)
- marge num_predict >= 6144 quand la réflexion est active
- la pensée reste affichée dans l'UI mais n'est plus renvoyée au modèle
(elle regonflait le contexte à chaque itération)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Les résultats d'outils dévoraient le contexte du modèle : sortie shell
tronquée aveuglément à 4000 c. (bruit gardé, erreur parfois coupée),
gros fichiers lus en entier.
- run_shell : succès = 12 dernières lignes ; échec = lignes d'erreur
+ fin de sortie, répétitions dédupliquées (« ligne ×N »)
- read_file : fenêtres de 200 lignes avec marche à suivre
(start_line=N pour la suite, grep_search pour cibler)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
« Corrige les bugs » partait à Aider sans contexte (quel fichier ? quel
projet ?) et le chemin agent ignorait quels fichiers existaient — le
modèle collait alors le code en chat au lieu de modifier le fichier.
- moteur code : récap de session (demande initiale + dernières demandes
+ fichiers touchés) préfixé à l'instruction ; fichiers de la session
passés à Aider quand aucun n'est cité
- chemin agent : liste des fichiers du workspace + fichiers de la tâche
injectée chaque tour en système
- directive renforcée : « ne colle JAMAIS le code corrigé dans ta
réponse sans l'avoir écrit dans le fichier »
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sur une reprise (« ajoute un bouton », « continue »), le routeur ne voyait
que le message courant : score trop bas, jamais le moteur code, et le
modèle décrivait les changements sans les appliquer.
- routage contextuel : si le tour précédent était du code (engine ou
outils write_file/edit_file/code_task), les suites courtes partent au
moteur code (is_code_followup)
- chemin agent sur session code : directive système « AGIS avec les
outils, ne décris jamais sans appliquer »
- fichiers cités dans le message et présents au workspace transmis à
Aider (travail direct, sans deviner via la repo map)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sur un long tour, les gros résultats d'outils (MCP 8 Ko, shell 4 Ko)
saturaient num_ctx et Ollama tronquait silencieusement le DÉBUT de la
conversation : le modèle perdait la consigne et « oubliait » sa tâche.
- élagage : les résultats d'outils des itérations passées sont compactés
(350 c. + marqueur), le dernier lot reste intact
- num_ctx 16384 par défaut (migration v6 : les profils restés sur les
anciens défauts 4096/8192 sont montés, les valeurs perso respectées)
- serveur MCP avec paramètre requis manquant (SEARXNG_URL) : refus clair
au démarrage au lieu d'un échec cryptique à chaque appel
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
L'auto-check séparé dans la boucle agent doublonnait _verify_written et
signalait à tort les fichiers écrits par morceaux (mode append).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ollama reloaded the chat model mid-message because plan/summary/router
calls sent divergent runner options (no num_ctx/num_batch) and omitted
keep_alive — the main cause of perceived slowness.
- share one keep-alive httpx.AsyncClient for all Ollama calls
- unify runner options (runner_options) + keep_alive on every model
call, embeddings included
- drop the blocking LLM routing fallback (pure lexical heuristic)
- run RAG recall + plan + code-model pick in parallel inside the SSE
stream, after the start event
- RAG cosine scoring off the event loop; cache /api/tags 30s and
nvidia-smi 5s; frontend polls 2s->5s, warm poll backoff, dedup
config fetch
feat: working session menu in TopBar (switch/create/rename/delete)
feat: workspace file deletion (DELETE /api/files + UI trash buttons)
docs: recommended Ollama env vars (KEEP_ALIVE, MAX_LOADED_MODELS...)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Modes d'exécution (composer) :
- routes/chat : champ mode ; _apply_mode adapte la config —
plan = outils lecture seule + plan forcé ; yolo = confirm_shell off ;
build = comportement normal.
- Frontend : ModeSelector dans le composer, mode dans le store + requête chat.
Panneau Git & Diff (le workspace est un dépôt git, Aider commite) :
- routes/git : /api/git/log (commits), /api/git/diff (commit ou working),
/api/git/revert (git revert --no-edit, confiné au workspace).
- Frontend : onglet Git dans le PreviewPanel — liste des commits, diff
colorisé, bouton Annuler (revert) avec rafraîchissement de l'arbo.
Bonus : le panneau Matériel explique que « GPU déclaré 12 Go » vient de
GPU_VRAM_MB (valeur manuelle) — à corriger en 16000 pour une 16 Go.
Tests : git log/diff/revert, modes plan/yolo/build via la route chat, builds.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Recherche : un modèle plus gros que la VRAM (ex. qwen3.6:35b-a3b ~20 Go sur
16 Go) déborde sur le CPU et charge lentement ; et le préchargement chargeait
un runner aux options par défaut, aussitôt rechargé par le 1er message avec un
num_ctx différent — double chargement d'un gros modèle.
- ollama_client.warm : accepte et transmet les options de génération.
- routes/models : start_model_warm calcule les options depuis la config du
modèle (ollama_options) et les passe au warm -> runner identique au chat,
plus de rechargement. Après chargement, détecte le placement via /api/ps
(gpu/cpu/mixte + %) et l'expose dans l'état de warm.
- Frontend : warmModel renvoie l'état ; si le modèle se charge sur CPU/mixte,
message d'alerte clair (trop gros pour la VRAM, choisir plus petit/quant).
Tests : options transmises au warm, placement 'mixte 65%' détecté, builds OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- routes/system : /api/system/hardware — liste les GPU vus par le conteneur
(nvidia-smi, multi-GPU) ou l'override GPU_VRAM_MB, et le placement réel des
modèles chargés côté Ollama (GPU/CPU/mixte + VRAM) via /api/ps.
- config : réintègre gpu_vram_mb / gpu_name (perdus lors d'une fusion).
- UI : carte MATÉRIEL dans Configuration (rafraîchie toutes les 5 s) montrant
les deux points de vue et si Ollama est local ou distant.
Répond à « l'appli est-elle réservée à la 3060 ? » (non) et permet de voir
tout de suite si Ollama charge un modèle sur CPU faute de support GPU.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- config/main : LOKI_VERSION (git sha), exposé via /api/health et /api/version ;
affiché dans la barre du haut. Permet de vérifier que l'image déployée est
bien à jour (cause fréquente de 'les nouveautés n'apparaissent pas').
- Dockerfile : ARG/ENV LOKI_VERSION ; workflow : build-arg = github.sha.
- bench : corrige un bug de précédence d'opérateur dans l'épreuve JSON
(le tuple de retour était malformé quand l'extraction était partielle).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Évite le rechargement lent quand Ollama a déchargé le modèle de la VRAM :
- ollama_client.warm() : précharge un modèle (/api/generate sans prompt) ;
chat() accepte keep_alive (durée de rétention en VRAM).
- agent.run_agent transmet keep_alive ; route chat le passe depuis la config.
- config : champ keep_alive (défaut 30m) par profil de modèle.
- routes/models : POST /api/models/warm, GET /api/models/loaded (placement
GPU/CPU via /api/ps).
- main : préchargement du modèle par défaut au démarrage (arrière-plan,
best-effort — n'empêche pas le démarrage si Ollama est absent).
- Frontend : préchargement automatique à la sélection d'un modèle, poll des
modèles chargés (8s), pastille verte (GPU) / orange (CPU) / blanche (à
charger) dans le sélecteur, réglage 'Maintien en VRAM' dans Configuration.
Tests : warm/loaded routes, keep_alive transmis, démarrage résilient sans
Ollama, build front.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
1. Plan-puis-exécute (enhance.make_plan) : les demandes complexes sont
décomposées en 3-5 étapes (event SSE 'plan', carte PLAN dans le fil,
meta.plan persisté) ; le plan guide l'agent et le moteur code.
2. Auto-critique « Qualité + » (enhance.self_review, toggle Intelligence) :
critique éclair puis révision de la réponse (event 'revision').
3. Mémoire long-terme RAG (rag.py) : échanges vectorisés via /api/embed
(modèle d'embedding auto-détecté), rappel cosinus top-3 inter-sessions
injecté en contexte, indexation en arrière-plan, élagage à 2000 souvenirs.
4. Vérification HTML (tools.check_html) : références locales cassées et
balises déséquilibrées ; branchée sur l'auto-vérification des outils ET
sur le moteur code avec une passe d'auto-correction Aider.
5. Benchmark intégré (bench.py + /api/bench) : 5 épreuves notées /100
(appel d'outil, code exécuté en sous-processus isolé, consignes, JSON,
format), streaming SSE, scores stockés ; carte BENCHMARK dans l'UI.
Config : plan_mode / self_review / rag_enabled / embed_model + carte
Intelligence (3 toggles). Client SSE : events plan/revision ; PlanCard.
Tests : heuristique+parsing du plan, révision, index/rappel RAG (exclusion
de la session courante), html_check, bench 100/100 sur modèle simulé,
intégration chat HTTP (event plan + meta persisté), build front.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Faire d'un petit modèle un bon agent :
- memory.py : contexte = invite + résumé des anciens tours + 10 derniers
messages ; résumé régénéré en arrière-plan après chaque réponse (colonne
summary sur sessions, migration douce). Contexte court = modèle concentré
et qui tient sur le GPU.
- tools.py : edit_file (recherche/remplacement exact, erreurs pédagogiques,
unicité exigée), grep_search (regex bornée, dossiers ignorés), et
vérification syntaxique auto (.py/.json) après chaque écriture — l'erreur
revient au modèle qui se corrige dans le même tour.
- coder.pick_code_model : les tâches de code vont au meilleur modèle code
installé (qwen-coder, deepseek-coder…) via config code_model=auto.
- Branché dans la route chat (mémoire + résolution du modèle code) et la
boucle agent (code_task) ; UI : descriptions et glyphes des nouveaux outils.
Tests : edit/grep/vérification, compression mémoire (19 msgs -> 12 dont
résumé), pick auto/explicite, chat HTTP de bout en bout, build front.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N