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
aider-chat 0.86.2 fige fastapi==0.128.8, pydantic==2.12.5 et psutil==7.2.2,
en conflit avec nos anciens pins (fastapi 0.115.6, psutil 6.1.1) -> pip
ResolutionImpossible pendant le build de l'image. On aligne nos versions sur
celles d'Aider (résolution vérifiée par pip --dry-run sur venv vierge ;
/api/system/stats testé OK avec psutil 7).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Favicon now matches the LokiMark topbar icon instead of an unrelated
arrow glyph. New /api/system/stats endpoint (psutil + nvidia-smi)
polled every 2s and shown in the topbar next to the Ollama status.
Le bloc de code avait un texte gris fonce (text-ink-2) sur fond sombre apres
le passage au theme clair -> illisible. Texte repasse en clair (on-dark),
bordure noire 3px + ombre dure pour coller au theme neo-brutaliste.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Certains modèles « thinking » ne renvoyaient que du raisonnement, sans reponse
finale -> erreur. Nouvel interrupteur global `think` (Reglages > Generation) :
- think=false envoie `think:false` a Ollama pour desactiver le raisonnement
- repli automatique si le modele refuse le parametre (does not support thinking)
- message d'erreur mis a jour pour pointer vers l'interrupteur
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
UI : reskin complet vers un theme neo-brutaliste clair (bordures noires 3px,
ombres dures, accent orange, polices Press Start 2P + DM Mono).
- tailwind.config / index.css / index.html : palette, polices, ombres, scrollbars
- TopBar, ActivityBar, LeftPanel, ChatPanel, PreviewPanel, SettingsView,
ToolCard, ModelSelector, Icon : restyle complet
Chat : panneau « Raisonnement » repliable et redimensionnable affichant le
thinking de l'agent en direct (diffuse depuis le backend, persiste dans meta).
Robustesse Ollama : les echecs de generation de parseur d'outils
(« Unable to generate parser for this template ») declenchent desormais le
repli automatique en conversation simple sans outils, au lieu d'un 400.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Frontend
- MessageContent: rendu Markdown complet (react-markdown + remark-gfm) avec
blocs de code dans un cadre + bouton Copier, et styles thematises (titres,
listes, gras, liens, tableaux, citations).
- ChatPanel: affiche sous chaque reponse de l'agent la vitesse (tokens/s) et le
nombre de jetons generes / en entree.
- PreviewPanel: iframe en sandbox="allow-scripts" pour que le JS des pages
generees s'execute (animations, canvas) tout en gardant une origine opaque.
- Icon: ajout CopyIcon / CheckIcon.
Backend
- agent: cumule les metriques Ollama (eval_count, eval_duration,
prompt_eval_count) et calcule les tokens/seconde, emis dans l'evenement final.
- chat: persiste les stats dans meta et les renvoie au client.
- agent_config: l'invite systeme par defaut demande un formatage Markdown.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- agent_config: num_gpu auto (-1) par défaut au lieu de forcer un nombre
de couches codé en dur (RTX 3060), qui faisait basculer Ollama sur CPU
quand la config ne tenait pas en VRAM. num_gpu/main_gpu ne sont transmis
que si l'utilisateur force explicitement une valeur (>= 0).
- agent_config: migration v4 remettant a -1 les profils deja enregistres
avec un num_gpu fige.
- agent: la boucle de reparation d'appel d'outil reinjecte son rappel en
role "user" au lieu de "system" (les templates Gemma/Mistral refusent un
message system hors tete -> 400 "System message must be at the beginning").
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ollama signale certains échecs en cours de génération (OOM, contexte trop
grand, débordement sur CPU) via une ligne JSON {"error": ...} avec un statut
HTTP 200. La boucle de streaming ne lisait que message.content / tool_calls /
done : ces lignes étaient ignorées, le flux se terminait avec un contenu vide,
et l'UI n'affichait rien — l'agent semblait "ne pas répondre".
- ollama_client: OllamaError + détection des chunks {"error": ...} (chat & pull),
corps de réponse remonté sur erreur HTTP, timeout de connexion court
(échec rapide si Ollama injoignable) avec lecture sans limite, et parsing
JSON tolérant aux lignes partielles.
- agent: capture d'OllamaError -> événement "error" affiché à l'utilisateur.
- docker-compose: config GPU NVIDIA pour le service Ollama embarqué (sinon CPU).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Si Ollama tourne sur une autre machine, le conteneur Loki ne voit aucun GPU :
l'auto-réglage prenait alors un chemin 'CPU' et fixait num_ctx=8192, ce qui
forçait Ollama à charger une instance distincte du modèle qui débordait sur le
CPU (lenteur). Désormais, GPU non détecté -> num_ctx=0 (défaut du modèle), donc
Ollama réutilise l'instance déjà sur GPU. Déclarer GPU_VRAM_MB active le vrai
réglage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Backend :
- agent_config : num_ctx dans la config, envoyé à Ollama (0 = défaut modèle)
- ollama_client : méthode ps() (placement GPU/CPU via /api/ps)
- autotune : placement() lit size vs size_vram pour savoir si le modèle est sur GPU
- routes/config : POST /api/config/auto (détecte GPU + modèle, calcule et applique
num_ctx/max_tokens, renvoie la détection et le placement)
Frontend :
- client/store : autoTune(), état tuning + résultat
- SettingsView : bouton ⚡ Réglage auto, bannière de détection (GPU/VRAM,
contexte, placement GPU/CPU), slider Contexte (num_ctx)
Config :
- GPU_VRAM_MB / GPU_NAME pour déclarer la VRAM si Ollama est distant
Tests : recommandation (8B sur 12 Go -> ctx 32768), route /auto + persistance,
transmission num_ctx aux options Ollama, placement via /api/ps.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Le conteneur écoutait sur 8717 alors que le mapping pointait host:8717 ->
conteneur:8080, d'où la connexion refusée. On standardise sur un seul numéro de
port (8717) identique dedans/dehors, et on laisse le HEALTHCHECK de l'image
gérer le bon port (suppression des healthcheck compose codés en dur sur 8080).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- config.py : overrides GPU_VRAM_MB / GPU_NAME
- ollama_client.py : méthode show() (/api/show)
- autotune.py : détection GPU (nvidia-smi/rocm-smi/env), profil modèle et calcul
du num_ctx optimal via estimation du cache KV
Module isolé, pas encore exposé via route ni UI (sans impact sur l'app).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N