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
É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
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
- Sépare le port hôte (HOST_PORT, défaut 8717) du port interne du conteneur (8080)
- docker-compose.yml : mapping ${HOST_PORT:-8717}:8080
- docker-compose.unraid.yml : 8717:8080
- .env.example : HOST_PORT=8717
- README : références de port mises à jour
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- .github/workflows/docker-publish.yml : build + push de ghcr.io/r0m1k3/loki
(linux/amd64, tags latest + sha, cache GHA) à chaque push sur main
- docker-compose.unraid.yml : utilise l'image préconstruite (plus de build/git
sur Unraid, simple pull)
- README : instructions Unraid mises à jour (image GHCR, visibilité du package)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
- docker-compose.unraid.yml : stack prête pour Unraid (Compose Manager),
build depuis le repo cloné dans appdata, volumes /mnt/user/appdata/loki,
OLLAMA_HOST à adapter, healthcheck
- README : section Installation sur Unraid (détection auto des modèles Ollama)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
Backend :
- tools.py : web_search (DuckDuckGo HTML sans clé, ou SearxNG via SEARX_URL) et
run_shell (confiné au workspace, sortie bornée, timeout)
- agent.py : run_shell sensible -> émet tool_confirm et ne s'exécute pas tant que
l'utilisateur n'a pas validé (confirm_shell)
- agent_config.py : web_search/run_shell désactivés par défaut, flag confirm_shell
- routes/shell.py : POST /api/shell/run exécute une commande validée
- routes/chat.py : relaie l'événement tool_confirm, passe confirm_shell
Frontend :
- streamChat : événement tool_confirm
- store : pendingShell + approveShell/rejectShell (réinjecte le résultat à l'agent)
- ChatPanel : carte de validation de commande (Approuver / Refuser)
- SettingsView : toggles web_search/run_shell, marqueur sensible, switch confirm_shell
- ToolCard : glyphes web_search/run_shell, statut 'à valider', aperçu d'argument
Tests : run_shell confiné, gate de confirmation (commande dangereuse non exécutée),
route shell, parser DuckDuckGo.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N