Commit Graph
29 Commits
Author SHA1 Message Date
MichaelandClaude Opus 4.8 cb2872c78a perf: fix model reload thrash and cut time-to-first-token
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>
2026-07-18 13:58:18 +02:00
Michael 803b28a39a Stabilise Ollama et les benchmarks longs 2026-07-07 15:56:04 +02:00
Michael c9b6c8bb3e Évite le timeout du préchargement 2026-07-07 15:34:08 +02:00
Michael 0f6abf6dde Fiabilise le préchargement et le benchmark 2026-07-07 15:25:12 +02:00
Michael ecadf55743 Add real-time system stats (CPU/RAM/GPU/VRAM) and fix favicon
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.
2026-07-01 14:56:50 +02:00
Michael b9bccac4ba add stop streaming and robust code copy 2026-06-30 20:12:20 +02:00
Michael c794d58718 save full agent config per model 2026-06-30 19:31:09 +02:00
Michael f6793daed3 improve session activity and model display 2026-06-30 19:19:49 +02:00
Michael a7290039f6 Add workspace navigation and model management 2026-06-30 16:28:44 +02:00
MichaelandClaude Opus 4.8 765c7b31d5 Fix lisibilite des blocs de code : texte clair sur fond sombre
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>
2026-06-30 15:00:10 +02:00
MichaelandClaude Opus 4.8 5c1b92daa3 Ajoute un interrupteur « Mode réflexion » (think) pour les modèles thinking
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>
2026-06-30 14:29:18 +02:00
MichaelandClaude Opus 4.8 b4fc8cee3d Theme neo-brutaliste + panneau raisonnement + repli sans outils
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>
2026-06-30 14:21:05 +02:00
MichaelandClaude Opus 4.8 e8e6a1446c Chat: rendu Markdown, blocs de code copiables, metriques de tokens, apercu HTML
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>
2026-06-30 13:45:59 +02:00
MichaelandClaude Opus 4.8 aed5f8148c Fix: garder l'inférence sur GPU et réparer l'erreur 400 de template
- 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>
2026-06-30 12:26:49 +02:00
Michael e24d397d31 Add per-model GPU and context profiles 2026-06-30 11:58:39 +02:00
Michael cdbb5f03fa Keep Ollama chat streams alive 2026-06-30 10:55:15 +02:00
Michael e9c83e3a0d Fix Ollama chat reliability 2026-06-30 10:36:29 +02:00
MichaelandClaude Opus 4.8 d47f7476ed Fix: remonter les erreurs Ollama au lieu de les avaler (agent muet)
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>
2026-06-30 09:52:11 +02:00
MichaelandClaude Opus 4.8 24cd39c5af WIP auto-tuning GPU : détection GPU + profil modèle (backend, non câblé)
- 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
2026-06-29 21:46:28 +00:00
MichaelandClaude Opus 4.8 6aa2f8fd5a Fix Docker: tourne en root par défaut (compat volumes Unraid)
Le conteneur tournait en utilisateur non-root (uid 10001) et ne pouvait pas
écrire dans /data et /workspace montés depuis /mnt/user/appdata (détenus par
root sur Unraid), provoquant un crash au démarrage (connexion refusée).
On revient à root par défaut ; durcissement possible via user: au niveau compose.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 21:45:36 +00:00
MichaelandClaude Opus 4.8 1f3a6908a6 Change le port d'accès par défaut 8080 -> 8717
- 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
2026-06-29 21:38:24 +00:00
MichaelandClaude Opus 4.8 a35ec98ebc CI : publication automatique de l'image Docker sur GHCR
- .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
2026-06-29 21:36:29 +00:00
MichaelandClaude Opus 4.8 8bb55c7ea7 Ajout compose Unraid et documentation d'installation
- 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
2026-06-29 21:33:22 +00:00
MichaelandClaude Opus 4.8 66be893ea6 Phases 5 & 8 : onglet Logs, durcissement Docker et documentation
Phase 5 (fin) :
- PreviewPanel : onglet Logs (journal d'activité des outils de la session,
  compteur dynamique, statuts ✓/✕/⏸/…)

Phase 8 :
- .dockerignore
- Dockerfile : utilisateur non-root (uid 10001), HEALTHCHECK via curl, dossiers
  de runtime détenus par l'utilisateur
- docker-compose : healthcheck, variable SEARX_URL optionnelle
- .env.example : SEARX_URL
- README : sections Utilisation, Outils de l'agent, Sécurité (confinement,
  validation run_shell, non-root) ; feuille de route complète

Validation : config docker compose OK ; build d'image non exécutable ici
(démon Docker absent de l'environnement).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 21:12:08 +00:00
MichaelandClaude Opus 4.8 de2befe31e Phase 7 : outils web_search et run_shell avec validation
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
2026-06-29 21:09:27 +00:00
MichaelandClaude Opus 4.8 2db6beea5c Phase 6 : configuration de l'agent fonctionnelle
Backend :
- agent_config.py : profil persisté (invite système, génération, outils actifs)
  avec valeurs par défaut et fusion robuste
- routes/config.py : GET/PUT /api/config
- db.py : table config clé/valeur (get/set JSON)
- agent.py : run_agent filtre les outils selon enabled_tools
- routes/chat.py : utilise l'invite système, les options de génération et les
  outils actifs issus de la config sauvegardée

Frontend :
- api/client.ts + store : getConfig/saveConfig, état config
- SettingsView : sliders interactifs (température, top-p, top-k, jetons max),
  toggles d'outils réels, éditeur d'invite système, bouton Enregistrer
- ChatPanel : la barre de contexte reflète température et outils actifs réels

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 21:03:14 +00:00
MichaelandClaude Opus 4.8 b6bf4edf97 Phase 4 : boucle agentique, outils fichiers et aperçu live
Backend :
- tools.py : read_file / write_file / list_dir confinés au workspace (anti-traversal)
- agent.py : boucle de tool-calling itérative au-dessus d'Ollama, génère des
  événements (token, tool_call, tool_result, final)
- routes/chat.py : pilote run_agent, relaie les événements en SSE, persiste la
  réponse finale + le récap des outils (meta)
- routes/files.py : arborescence et contenu du workspace (confiné)
- db.py : colonne meta sur messages (+ migration douce), list_messages_for_model

Frontend :
- ToolCard : carte d'appel d'outil dans le fil (statut en cours/terminé/échec)
- streamChat : événements tool_call / tool_result
- store : streamTools, fileTree, preview (ouverture auto d'un HTML écrit)
- LeftPanel : arborescence réelle du workspace, clic -> aperçu
- PreviewPanel : rendu HTML en iframe + onglet Code
- ChatPanel : rendu des outils dans les bulles agent (streaming + persisté)

Tests manuels : outils + confinement, boucle agent (mock Ollama), chat HTTP de
bout en bout (SSE, persistance meta, fichiers écrits, confinement route).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 18:55:16 +00:00
MichaelandClaude Opus 4.8 48cbcaafaf Phase 3 : chat streaming SSE et persistance des sessions
Backend :
- db.py : SQLite (sessions + messages), schéma et CRUD
- routes/sessions.py : créer/lister/ouvrir/renommer/supprimer une session
- routes/chat.py : POST /api/chat, relais token par token depuis Ollama (SSE),
  persistance des messages, titrage auto de la session au 1er message
- main.py : lifespan -> init_db, montage des nouvelles routes

Frontend :
- api/client.ts : APIs sessions + streamChat (parsing SSE event/data)
- store : sessions, messages, état de streaming, envoi optimiste
- ChatPanel : fil de conversation réel, bulles user/agent, curseur de frappe
- LeftPanel : historique réel (ouvrir/supprimer, horodatage relatif)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 18:46:51 +00:00
MichaelandClaude Opus 4.8 3ad37ae2c7 Phase 1-2 : socle Loki, design system et connexion Ollama
- Scaffold full-stack : backend FastAPI + frontend React/Vite/TS/Tailwind
- Design system fidèle au thème (palette ambre/café, JetBrains Mono, tokens Tailwind)
- Layout 3 panneaux : activity bar, historique/fichiers, chat, aperçu
- Connexion Ollama : statut live, liste des modèles, pull avec progression SSE, sélecteur de modèle
- Vue Configuration (Frame 2) : modèles, génération, outils, invite système
- Dockerfile multi-stage + docker-compose (Ollama externe par défaut, profil ollama optionnel)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVay7z3y7q2gEe54ByAE6N
2026-06-29 16:51:25 +00:00