mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Attribution du fork, README, logo UI et workflow GHCR
- NOTICE.md : Loki est un fork d'AJEAN (nathaninline, MIT), liste des modifications ; LICENSE amont conservée à l'identique. - README réécrit : bandeau fork, architecture conteneur, démarrage Docker, procédure Unraid (plugin Nvidia Driver), différences avec l'amont. - UI : le logo pixel-art épelle désormais LOKI (il épelait encore AJEAN), infobulle d'attribution sur la marque ; index.html régénéré. - Workflow GHCR : libération d'espace disque du runner (l'étape CUDA devel ne tient pas dans les ~14 Go libres), build-args CUDA_ARCHS/LOKI_VERSION, cache GHA en mode min (plafond 10 Go).
This commit is contained in:
5 files changed
+137
-284
No files matched your search
@@ -16,6 +16,16 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# L'étape llama.cpp CUDA a besoin de place : l'image devel pèse ~8 Go et
|
||||
# un runner ubuntu-latest n'offre que ~14 Go libres. On purge ce qui est
|
||||
# préinstallé et inutile ici (SDK Android, .NET, Haskell…).
|
||||
- name: Libérer l'espace disque du runner
|
||||
run: |
|
||||
sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc \
|
||||
/usr/local/.ghcup /opt/hostedtoolcache/CodeQL
|
||||
sudo docker image prune -af
|
||||
df -h /
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
@@ -43,7 +53,11 @@ jobs:
|
||||
push: true
|
||||
build-args: |
|
||||
LOKI_VERSION=${{ github.sha }}
|
||||
CUDA_ARCHS=75;86;89
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# Cache limité : les couches CUDA (plusieurs Go) satureraient le
|
||||
# plafond de 10 Go du cache GitHub Actions — on ne cache que le mode
|
||||
# min (couches finales), le gain principal restant le cache apt/go.
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-to: type=gha,mode=min
|
||||
@@ -0,0 +1,27 @@
|
||||
# Avis d'attribution
|
||||
|
||||
**Loki est un fork de [AJEAN](https://github.com/nathaninline/ajean)**, créé
|
||||
par [nathaninline](https://github.com/nathaninline) et publié sous licence MIT.
|
||||
L'essentiel du code de ce dépôt — moteur d'assistant IA en Go, interface web
|
||||
embarquée, mémoire persistante, accès internet, outils MCP, accès distant
|
||||
chiffré — est l'œuvre du projet AJEAN. Merci à son auteur.
|
||||
|
||||
La licence d'origine est conservée à l'identique dans [`LICENSE`](LICENSE).
|
||||
|
||||
## Modifications apportées par le fork
|
||||
|
||||
- **Renommage** AJEAN → Loki (binaire `loki`, `LOKI_HOME`, `/etc/loki`,
|
||||
units `loki-engine` / `loki-ui`).
|
||||
- **Conteneurisation** : image Docker autonome (llama.cpp compilé CUDA +
|
||||
binaire Go), `docker-compose` et variante Unraid, publication GHCR.
|
||||
- **Supervision sans systemd** (`sys_service_container.go`) : en conteneur,
|
||||
le moteur est piloté par fichier PID au lieu de systemctl — indispensable
|
||||
pour que l'UI puisse redémarrer le moteur (changement de modèle).
|
||||
- **`loki config get/set`** : lecture/écriture non interactive de la
|
||||
configuration, utilisée par l'entrypoint Docker.
|
||||
|
||||
## Services externes
|
||||
|
||||
Le tunnel d'accès distant continue de pointer vers **ajean.link**, le relais
|
||||
opéré par l'auteur d'AJEAN ; le catalogue de modèles intégré est également
|
||||
servi par ajean.link. Ces services appartiennent au projet amont.
|
||||
@@ -1,309 +1,121 @@
|
||||
# Loki — Agent IA local sur Ollama
|
||||
# Loki — assistant IA local en conteneur (fork d'AJEAN)
|
||||
|
||||
Loki est un atelier d'agent IA **100 % local**, conçu pour se connecter à
|
||||
[Ollama](https://ollama.com) et travailler en mode agentique : un tchat, des
|
||||
outils (lecture/écriture de fichiers, aperçu HTML en direct…) et un workspace
|
||||
de fichiers. Pensé pour un déploiement **Docker** simple.
|
||||
> **Loki est un fork de [AJEAN](https://github.com/nathaninline/ajean)** de
|
||||
> [nathaninline](https://github.com/nathaninline), sous licence MIT — voir
|
||||
> [`NOTICE.md`](NOTICE.md) et [`LICENSE`](LICENSE). L'essentiel du code et des
|
||||
> fonctionnalités vient d'AJEAN ; ce fork le rebaptise et le fait tourner dans
|
||||
> **un conteneur Docker GPU autonome**, là où l'amont s'installe en binaire +
|
||||
> systemd sur la machine hôte.
|
||||
|
||||
Le thème visuel (« atelier café », sombre et chaleureux, accent ambre) est
|
||||
décliné fidèlement depuis la maquette d'origine.
|
||||
Loki fait tourner un modèle de langage **100 % en local** : tchat, mémoire
|
||||
persistante, accès internet, outils MCP, agent (shell, fichiers), accès distant
|
||||
chiffré — serveur d'inférence llama.cpp compris, dans une seule image.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Frontend (React + Vite + TS + Tailwind)
|
||||
│ HTTP + SSE
|
||||
Backend (FastAPI, Python)
|
||||
├── /api/status, /api/models, /api/models/pull (Ollama)
|
||||
├── /api/sessions (CRUD sessions)
|
||||
├── /api/chat (boucle agentique + outils, streaming SSE)
|
||||
├── /api/files (arborescence + contenu du workspace)
|
||||
│ Outils agent : read_file · write_file · list_dir (confinés au workspace)
|
||||
│ httpx │ volume
|
||||
Ollama (:11434) /workspace + /data (SQLite)
|
||||
┌────────────────── conteneur loki ──────────────────┐
|
||||
│ loki web (UI + API, port 8090, premier plan) │
|
||||
│ │ pilote (fichier PID — pas de systemd) │
|
||||
│ loki serve ──exec──► llama-server (CUDA, :8080) │
|
||||
│ ▲ modèles .gguf │
|
||||
│ /data (config, bbolt, mémoire, workspace) │
|
||||
│ /models (GGUF déposés à la main) │
|
||||
└────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Un seul conteneur : le backend FastAPI sert l'API **et** le frontend compilé.
|
||||
Loki se connecte à un **Ollama existant** via `OLLAMA_HOST`.
|
||||
- **Un seul conteneur** : l'UI joint le moteur sur `localhost` (contrainte
|
||||
héritée de l'amont), les deux partagent donc le même conteneur.
|
||||
- **Sans systemd** : l'amont pilote le moteur via systemctl ; en conteneur,
|
||||
Loki bascule automatiquement sur une supervision par fichier PID
|
||||
(`internal/loki/sys_service_container.go`). Changer de modèle depuis l'UI
|
||||
redémarre le moteur normalement.
|
||||
- Le moteur (port 8080, non authentifié par défaut) **n'est pas exposé** ;
|
||||
seule l'UI (8090) l'est.
|
||||
|
||||
## Démarrage rapide (Docker)
|
||||
## Démarrage rapide (Docker, GPU NVIDIA)
|
||||
|
||||
Pré-requis : pilote NVIDIA + [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html).
|
||||
|
||||
```bash
|
||||
cp .env.example .env # ajuste OLLAMA_HOST si besoin
|
||||
docker compose up --build
|
||||
cp .env.example .env # CUDA_ARCHS=86 pour une RTX 30xx, etc.
|
||||
docker compose up --build # 30-45 min : compilation CUDA de llama.cpp
|
||||
```
|
||||
|
||||
Application disponible sur http://localhost:8717
|
||||
|
||||
> **Ollama** : par défaut Loki vise `http://host.docker.internal:11434`
|
||||
> (un Ollama installé sur la machine hôte). Pour embarquer Ollama dans la
|
||||
> stack : `docker compose --profile ollama up` puis règle
|
||||
> `OLLAMA_HOST=http://ollama:11434`.
|
||||
Interface : http://localhost:8090 — télécharge un modèle depuis le catalogue
|
||||
intégré (onglet modèles), il démarre tout seul.
|
||||
|
||||
## Installation sur Unraid
|
||||
|
||||
L'image est **construite et publiée automatiquement par GitHub Actions** sur GHCR
|
||||
(`ghcr.io/r0m1k3/loki:latest`) à chaque push sur `main`. Aucun build ni `git`
|
||||
n'est nécessaire sur Unraid — un simple `pull`. Compose prêt à l'emploi :
|
||||
[`docker-compose.unraid.yml`](docker-compose.unraid.yml).
|
||||
L'image est construite et publiée par GitHub Actions sur GHCR
|
||||
(`ghcr.io/r0m1k3/loki:latest`) à chaque push sur `main` — aucun build sur
|
||||
Unraid. Compose prêt à l'emploi : [`docker-compose.unraid.yml`](docker-compose.unraid.yml).
|
||||
|
||||
1. Dans le terminal Unraid, crée les dossiers de données :
|
||||
1. Installe le plugin **Nvidia Driver** (Apps) et vérifie `nvidia-smi`.
|
||||
2. Crée les dossiers :
|
||||
```bash
|
||||
mkdir -p /mnt/user/appdata/loki/workspace /mnt/user/appdata/loki/data
|
||||
mkdir -p /mnt/user/appdata/loki/data /mnt/user/appdata/loki/models
|
||||
```
|
||||
2. Installe le plugin **Compose Manager** (Apps), crée une nouvelle stack, et
|
||||
colle le contenu de `docker-compose.unraid.yml`.
|
||||
3. **Adapte `OLLAMA_HOST`** : mets l'IP de ton serveur Unraid où tourne le
|
||||
conteneur Ollama, p. ex. `http://192.168.1.10:11434`.
|
||||
4. **Compose Up**. Loki est accessible sur `http://<ip-unraid>:8717`
|
||||
(change le port à gauche du mapping `8717:8080` s'il est déjà pris).
|
||||
3. Plugin **Compose Manager** → nouvelle stack → colle
|
||||
`docker-compose.unraid.yml` → **Compose Up**.
|
||||
4. Interface : `http://<ip-unraid>:8090`.
|
||||
|
||||
> La première publication de l'image prend quelques minutes (le temps que le
|
||||
> workflow GitHub se termine). Si l'image est privée, rends le package **public**
|
||||
> une fois (GitHub → Packages → `loki` → Package settings → Change visibility).
|
||||
>
|
||||
> Les modèles déjà présents dans ton Ollama sont **détectés automatiquement** ;
|
||||
> tu peux en télécharger d'autres depuis l'onglet Configuration.
|
||||
> Mise à jour : Compose Down/Up (avec pull), ou `docker compose pull`.
|
||||
## Configuration
|
||||
|
||||
## Développement (sans Docker)
|
||||
Tout se règle **dans l'UI** (modèle, contexte, presets…) et survit aux
|
||||
redémarrages (volume `/data`). Variables d'environnement du conteneur :
|
||||
|
||||
| Variable | Rôle | Défaut |
|
||||
|---|---|---|
|
||||
| `LOKI_WEB_PORT` | port de l'UI | `8090` |
|
||||
| `LOKI_MODEL` | modèle initial (semé au 1er boot seulement) | — |
|
||||
| `LOKI_CTX` | taille de contexte initiale | `32768` |
|
||||
| `LOKI_NGL` | couches GPU initiales | `999` (tout) |
|
||||
| `LOKI_HOME` | données (volume) | `/data` |
|
||||
| `LOKI_MODEL_DIRS` | dossiers .gguf additionnels | `/models` |
|
||||
|
||||
En CLI dans le conteneur : `docker exec -it loki loki status` (aussi :
|
||||
`logs`, `restart`, `config`, `bench`, `test`…).
|
||||
|
||||
## Fonctionnalités (héritées d'AJEAN)
|
||||
|
||||
- **Tchat** avec streaming, raisonnement visible, pièces jointes, vision
|
||||
(selon modèle), export de conversations.
|
||||
- **Mémoire persistante** (`memory off|ondemand|always`).
|
||||
- **Accès internet** : recherche + lecture de pages, moteur Go intégré ou
|
||||
[Crawl4AI](https://github.com/unclecode/crawl4ai) pour les pages JS.
|
||||
- **Agent** : shell, fichiers, workspace (`agent on`).
|
||||
- **Serveurs MCP** : Node.js est inclus dans l'image pour les serveurs `npx`.
|
||||
- **Presets** de configuration par modèle, bench, auto-détection GPU.
|
||||
- **Accès distant chiffré** via le relais [ajean.link](https://ajean.link)
|
||||
(service opéré par l'auteur de l'amont).
|
||||
- **API OpenAI-compatible** exposable (`network on`, protégée par clé).
|
||||
|
||||
## Différences avec l'amont
|
||||
|
||||
| | AJEAN (amont) | Loki (ce fork) |
|
||||
|---|---|---|
|
||||
| Installation | binaire + `sudo ajean install` (systemd) | `docker compose up` |
|
||||
| Moteur llama.cpp | compilé sur la machine (`ajean llamacpp install`) | précompilé CUDA dans l'image |
|
||||
| Supervision moteur | systemd / launchd / PID (Windows) | fichier PID (`LOKI_CONTAINER=1`) |
|
||||
| Configuration initiale | `ajean edit` ($EDITOR) | entrypoint + `loki config set` |
|
||||
| Mise à jour | `ajean update` (binaire GitHub) | `docker compose pull` |
|
||||
|
||||
Le reste — UI, mémoire, outils, protocole — est celui d'AJEAN. Pour récupérer
|
||||
les évolutions de l'amont :
|
||||
|
||||
**Backend**
|
||||
```bash
|
||||
cd backend
|
||||
pip install -r requirements.txt
|
||||
OLLAMA_HOST=http://localhost:11434 uvicorn app.main:app --reload --port 8080
|
||||
git fetch upstream && git merge upstream/main # conflits de renommage à arbitrer
|
||||
```
|
||||
|
||||
**Frontend** (proxy `/api` → `:8080`)
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev # http://localhost:5173
|
||||
```
|
||||
## Build sans GPU / autres accélérateurs
|
||||
|
||||
## Configuration (variables d'environnement)
|
||||
L'image par défaut cible CUDA. Pour un essai CPU, remplace dans le
|
||||
`Dockerfile` les bases `nvidia/cuda:*` par `ubuntu:24.04` et retire les flags
|
||||
`-DGGML_CUDA=*` (llama.cpp bascule en CPU). Vulkan/ROCm : adapter les flags
|
||||
comme le fait l'amont (`internal/loki/backend_build.go`).
|
||||
|
||||
| Variable | Défaut | Rôle |
|
||||
| --------------- | ----------------------------------- | ----------------------------- |
|
||||
| `OLLAMA_HOST` | `http://host.docker.internal:11434` | URL de l'instance Ollama |
|
||||
| `DEFAULT_MODEL` | `gemma4:12b` | Modèle sélectionné au démarrage |
|
||||
| `WORKSPACE_DIR` | `/workspace` | Dossier de travail de l'agent |
|
||||
| `DATA_DIR` | `/data` | Base SQLite (sessions + config) |
|
||||
| `PORT` | `8717` | Port de l'application (dedans = dehors) |
|
||||
| `SEARX_URL` | *(vide)* | Instance SearxNG pour `web_search` (sinon DuckDuckGo) |
|
||||
## Licence
|
||||
|
||||
## Utilisation
|
||||
|
||||
1. Vérifie la pastille **Ollama** (verte = connecté) en haut à droite, et choisis
|
||||
un modèle qui supporte le *function calling* (profil fourni : `gemma4:12b`).
|
||||
2. Décris une tâche dans le tchat, p. ex. *« Crée une landing page pour un café
|
||||
nommé Café Lumière, avec menu et horaires »*.
|
||||
3. L'agent lit/écrit des fichiers dans le **workspace** ; chaque appel d'outil
|
||||
s'affiche dans le fil, et l'aperçu HTML apparaît à droite (onglets **Aperçu /
|
||||
Code / Logs**).
|
||||
4. Règle le comportement dans **Configuration** (modèle, température/top-p/top-k,
|
||||
jetons max, outils actifs, invite système).
|
||||
|
||||
## Outils de l'agent
|
||||
|
||||
| Outil | Rôle | Par défaut |
|
||||
| ------------- | -------------------------------------- | ---------- |
|
||||
| `read_file` | Lire un fichier du workspace | activé |
|
||||
| `write_file` | Créer / modifier un fichier | activé |
|
||||
| `list_dir` | Lister un répertoire | activé |
|
||||
| `web_search` | Recherche web (DuckDuckGo / SearxNG) | désactivé |
|
||||
| `run_shell` | Exécuter une commande **(sensible)** | désactivé |
|
||||
|
||||
## Préchargement des modèles (réponses instantanées)
|
||||
|
||||
Ollama décharge un modèle de la VRAM après quelques minutes d'inactivité : le
|
||||
message suivant paie alors un rechargement complet (lent). Loki évite ça :
|
||||
|
||||
- **Préchargement à la sélection** : choisir un modèle le charge immédiatement
|
||||
en VRAM (`/api/models/warm`).
|
||||
- **Maintien au chaud** : chaque requête envoie un `keep_alive` (défaut 30 min,
|
||||
réglable dans Configuration → Intelligence : de « décharger aussitôt » à
|
||||
« toujours »).
|
||||
- **Préchargement au démarrage** du modèle par défaut (en arrière-plan).
|
||||
- **Indicateur d'état** : la pastille du sélecteur de modèle est verte quand le
|
||||
modèle est chargé sur GPU, orange sur CPU, blanche s'il reste à charger.
|
||||
|
||||
## Performance Ollama (recommandé)
|
||||
|
||||
Réglages **côté serveur Ollama** qui rendent Loki nettement plus fluide
|
||||
(variables d'environnement du service/conteneur Ollama, redémarrage requis) :
|
||||
|
||||
| Variable | Valeur conseillée | Effet |
|
||||
| -------- | ----------------- | ----- |
|
||||
| `OLLAMA_KEEP_ALIVE` | `30m` (ou `-1`) | Durée de rétention par défaut d'un modèle en VRAM. `-1` = jamais déchargé (machine dédiée). Doit être ≥ au `keep_alive` configuré dans Loki. |
|
||||
| `OLLAMA_MAX_LOADED_MODELS` | `2` | Autorise le modèle de chat **et** le modèle d'embedding (RAG) à résider ensemble en VRAM — supprime les allers-retours de chargement à chaque message. |
|
||||
| `OLLAMA_NUM_PARALLEL` | `1` | Loki est mono-utilisateur ; chaque slot parallèle multiplie la VRAM du cache KV. |
|
||||
| `OLLAMA_FLASH_ATTENTION` | `1` | Attention plus rapide et plus sobre en VRAM. |
|
||||
| `OLLAMA_KV_CACHE_TYPE` | `q8_0` | Cache KV quantifié : ~moitié de VRAM en moins, marge pour un 12B sur 12 Go. |
|
||||
|
||||
Exemple pour un Ollama en Docker (service `ollama` du compose) :
|
||||
|
||||
```yaml
|
||||
ollama:
|
||||
image: ollama/ollama
|
||||
environment:
|
||||
- OLLAMA_KEEP_ALIVE=30m
|
||||
- OLLAMA_MAX_LOADED_MODELS=2
|
||||
- OLLAMA_NUM_PARALLEL=1
|
||||
- OLLAMA_FLASH_ATTENTION=1
|
||||
- OLLAMA_KV_CACHE_TYPE=q8_0
|
||||
```
|
||||
|
||||
Côté Loki, tout est déjà optimisé : pool HTTP keep-alive partagé vers Ollama,
|
||||
options runner identiques sur tous les appels (pas de rechargement du modèle en
|
||||
plein message), `keep_alive` systématique (chat **et** embeddings), préparation
|
||||
du contexte (RAG + plan) en parallèle après l'ouverture du flux, et caches
|
||||
courts (`/api/tags`, stats GPU).
|
||||
|
||||
## Modes d'exécution (Plan / Build / Yolo)
|
||||
|
||||
Un sélecteur dans le composer contrôle le niveau d'autonomie de l'agent :
|
||||
- **Plan** 🔍 — lecture seule (`read_file`, `list_dir`, `grep_search`) : l'agent
|
||||
analyse et propose sans jamais modifier de fichier ni exécuter de commande.
|
||||
- **Build** 🔨 — normal : écrit les fichiers, `run_shell` demande confirmation.
|
||||
- **Yolo** ⚡ — autonomie maximale : approuve tout, y compris le shell.
|
||||
|
||||
## Panneau Git & Diff
|
||||
|
||||
Le workspace étant un dépôt git (chaque action de l'agent = un commit), l'onglet
|
||||
**Git** du panneau de droite montre l'historique des commits, le **diff coloré**
|
||||
de chacun, et un bouton **↶ Annuler** (revert) pour défaire une modification en
|
||||
un clic.
|
||||
|
||||
## Projets (répertoires de travail)
|
||||
|
||||
Chaque session peut travailler dans un **projet** : un sous-dossier du
|
||||
workspace choisi via le chip 📁 du composer (« + Nouveau projet » pour en
|
||||
créer un). L'agent, le shell, le moteur code et l'arborescence sont confinés
|
||||
au projet ; chaque projet a son propre dépôt git (historique et revert
|
||||
indépendants). Session sans projet = racine du workspace.
|
||||
|
||||
## Intelligence augmentée
|
||||
|
||||
- **Plan-puis-exécute** : les demandes complexes sont décomposées en 3-5 étapes
|
||||
affichées dans le fil ; l'agent (ou le moteur code) suit le plan.
|
||||
- **Auto-critique « Qualité + »** (Configuration → Intelligence) : la réponse
|
||||
est relue et révisée avant d'être finalisée.
|
||||
- **Mémoire long-terme (RAG)** : chaque échange est vectorisé (`/api/embed`)
|
||||
et les souvenirs pertinents des anciennes sessions sont réinjectés en
|
||||
contexte. Nécessite un modèle d'embedding installé (ex.
|
||||
`ollama pull nomic-embed-text`) — sinon désactivé silencieusement.
|
||||
- **Vérification HTML** : liens locaux cassés et balises déséquilibrées sont
|
||||
détectés après chaque génération ; le moteur code fait une passe
|
||||
d'auto-correction.
|
||||
- **Benchmark intégré** (Configuration → Benchmark) : 5 mini-épreuves notées
|
||||
/100 (appel d'outil, code exécutable, consignes, extraction JSON, format)
|
||||
pour comparer objectivement tes modèles installés.
|
||||
|
||||
## Serveurs MCP (outils professionnels)
|
||||
|
||||
Configuration → **Serveurs MCP** : catalogue préconfiguré, tout désactivé par
|
||||
défaut (un serveur inactif ne coûte rien — aucun process, aucun outil dans le
|
||||
prompt du modèle).
|
||||
|
||||
| Serveur | Apport |
|
||||
| ------- | ------ |
|
||||
| Playwright | l'agent pilote un vrai navigateur : teste ses pages, lit la console |
|
||||
| Context7 | documentation à jour de n'importe quelle librairie |
|
||||
| Fetch | lecture propre d'URL (markdown) |
|
||||
| SearxNG | vraie recherche web (URL d'instance requise) |
|
||||
| Personnalisé | n'importe quel serveur MCP (commande stdio ou URL) |
|
||||
|
||||
Chaque carte a un bouton **Tester** (connexion d'essai + liste des outils
|
||||
découverts). Un serveur en panne n'interrompt jamais le chat : notice dans le
|
||||
fil, nouvelle tentative au message suivant.
|
||||
|
||||
## Skills automatiques
|
||||
|
||||
Cinq méthodes expertes (débogage systématique, création web, refactor sûr,
|
||||
analyse de données, rédaction structurée) sont injectées automatiquement selon
|
||||
la tâche détectée — sélection lexicale instantanée, une seule à la fois, badge
|
||||
« 📘 Méthode : … » dans le fil. Désactivable dans Configuration → Intelligence.
|
||||
|
||||
## Tirer le meilleur des petits modèles
|
||||
|
||||
Loki est conçu pour qu'un modèle local modeste se comporte comme un bon agent :
|
||||
|
||||
- **Mémoire compressée** : au-delà d'un seuil, les anciens tours sont résumés
|
||||
en arrière-plan et le modèle ne reçoit que « invite + résumé + 10 derniers
|
||||
messages ». Contexte court = modèle concentré, et qui reste sur le GPU.
|
||||
- **Outils chirurgicaux** : `edit_file` (recherche/remplacement exact — pas de
|
||||
réécriture intégrale ratée), `grep_search` (trouver avant de modifier), et
|
||||
`write_file` par morceaux (overwrite/append).
|
||||
- **Auto-vérification** : après chaque écriture, la syntaxe (`.py`, `.json`)
|
||||
est contrôlée ; l'erreur est renvoyée immédiatement au modèle, qui se
|
||||
corrige dans le même tour.
|
||||
- **Bon modèle au bon poste** : les tâches de code sont confiées au meilleur
|
||||
modèle code installé (`qwen-coder`, `deepseek-coder`…), automatiquement
|
||||
(config `code_model: auto`), même si tu discutes avec un généraliste.
|
||||
- **Récupération d'appels d'outils malformés** : arguments réparés ou
|
||||
redemandés, modèles sans function-calling détectés et gérés.
|
||||
|
||||
## Moteur code (façon Claude Code) — routage automatique
|
||||
|
||||
Loki embarque [Aider](https://aider.chat) (Apache-2.0, version figée) comme
|
||||
**moteur code** : édition multi-fichiers fiable (formats diff/search-replace,
|
||||
efficaces même avec de petits modèles), repo map, et **commits git
|
||||
automatiques** dans le workspace.
|
||||
|
||||
**C'est invisible** : un routeur classe chaque message.
|
||||
- Tâche de code détectée (heuristique lexicale instantanée) → le message part
|
||||
au **moteur code** ; le fil affiche la carte `code_task`, les fichiers
|
||||
modifiés et le commit.
|
||||
- Sinon → **boucle agent** classique ; et l'agent peut lui-même déléguer au
|
||||
moteur via l'outil `code_task` quand il juge qu'il faut coder.
|
||||
|
||||
Désactivable dans Configuration → Outils (`code_task`). Le workspace est
|
||||
auto-initialisé en dépôt git : chaque modification de code = un commit
|
||||
(historique et rollback via `git log` / `git revert` dans le workspace).
|
||||
|
||||
## Profil GPU fourni
|
||||
|
||||
Loki est préconfiguré pour une **RTX 3060 12 Go** avec `gemma4:12b` en Q4 :
|
||||
contexte 8192, sortie 4096 jetons, batch 256, GPU principal 0 et les 49 couches
|
||||
du modèle sur le GPU. Les paramètres de génération et de cache/contexte sont
|
||||
enregistrés séparément pour chaque modèle.
|
||||
|
||||
La quantification du cache KV reste globale dans Ollama. Pour économiser environ
|
||||
la moitié de sa VRAM, démarre Ollama avec `OLLAMA_FLASH_ATTENTION=1` et
|
||||
`OLLAMA_KV_CACHE_TYPE=q8_0`. Un redémarrage d'Ollama est requis. Le conteneur
|
||||
doit également exposer le GPU (`--gpus=all`) ; Loki ne peut pas contourner une
|
||||
configuration Docker sans accès CUDA.
|
||||
|
||||
## Sécurité
|
||||
|
||||
- **Confinement** : toutes les opérations fichier (`read_file`, `write_file`,
|
||||
`list_dir`) et `run_shell` sont strictement confinées au `WORKSPACE_DIR`. Toute
|
||||
tentative de sortie (`../`, chemin absolu) est rejetée.
|
||||
- **`run_shell`** est désactivé par défaut. Une fois activé, chaque commande
|
||||
proposée par l'agent demande une **validation explicite** dans l'interface
|
||||
(option *confirm_shell*, activée par défaut) avant exécution.
|
||||
- Le conteneur tourne en **utilisateur non-root** et expose un **HEALTHCHECK**.
|
||||
- Loki est conçu pour un usage **local** : n'expose pas le port publiquement sans
|
||||
ajouter ta propre couche d'authentification.
|
||||
|
||||
## Feuille de route
|
||||
|
||||
- [x] **Phase 1** — Socle + design system fidèle au thème, layout 3 panneaux
|
||||
- [x] **Phase 2** — Connexion Ollama : statut, liste des modèles, pull avec progression, sélecteur
|
||||
- [x] **Phase 3** — Chat streaming (SSE) + persistance des sessions (SQLite)
|
||||
- [x] **Phase 4** — Boucle agentique & outils fichiers (read/write/list), confinés au workspace, rendu des appels d'outils dans le fil
|
||||
- [x] **Phase 5** — Aperçu HTML live + onglets Code/Logs + arborescence du workspace
|
||||
- [x] **Phase 6** — Configuration complète (génération, toggles d'outils, invite système)
|
||||
- [x] **Phase 7** — Outils avancés : `web_search` (DuckDuckGo/SearxNG) et `run_shell` avec validation utilisateur
|
||||
- [x] **Phase 8** — Durcissement & documentation Docker
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
backend/ FastAPI : routes Ollama, client httpx, config
|
||||
frontend/ React : design system (tailwind.config), panneaux, store Zustand
|
||||
workspace/ fichiers créés par l'agent (monté en volume)
|
||||
data/ base SQLite (monté en volume)
|
||||
```
|
||||
MIT — © les contributeurs d'AJEAN (« Jean contributors ») pour le code amont,
|
||||
voir [`LICENSE`](LICENSE) et [`NOTICE.md`](NOTICE.md).
|
||||
@@ -1204,7 +1204,7 @@ button:hover{border-color:var(--dim);color:var(--text)}
|
||||
<div id="backdrop" onclick="toggleSide()"></div>
|
||||
<div class="side" id="side">
|
||||
<div class="sidehead">
|
||||
<h1 id="brand" aria-label="loki"><span id="brand-a"><svg viewBox="0 0 4 5" shape-rendering="crispEdges" fill="currentColor"><rect x="1" y="0" width="2" height="1"/><rect x="0" y="1" width="1" height="1"/><rect x="3" y="1" width="1" height="1"/><rect x="0" y="2" width="4" height="1"/><rect x="0" y="3" width="1" height="1"/><rect x="3" y="3" width="1" height="1"/><rect x="0" y="4" width="1" height="1"/><rect x="3" y="4" width="1" height="1"/></svg></span><span id="brand-word"><svg viewBox="0 0 17 5" shape-rendering="crispEdges" fill="currentColor"><rect x="1" y="0" width="1" height="1"/><rect x="1" y="1" width="1" height="1"/><rect x="1" y="2" width="1" height="1"/><rect x="1" y="3" width="1" height="1"/><rect x="0" y="4" width="1" height="1"/><rect x="3" y="0" width="4" height="1"/><rect x="3" y="1" width="1" height="1"/><rect x="3" y="2" width="3" height="1"/><rect x="3" y="3" width="1" height="1"/><rect x="3" y="4" width="4" height="1"/><rect x="9" y="0" width="2" height="1"/><rect x="8" y="1" width="1" height="1"/><rect x="11" y="1" width="1" height="1"/><rect x="8" y="2" width="4" height="1"/><rect x="8" y="3" width="1" height="1"/><rect x="11" y="3" width="1" height="1"/><rect x="8" y="4" width="1" height="1"/><rect x="11" y="4" width="1" height="1"/><rect x="13" y="0" width="1" height="1"/><rect x="16" y="0" width="1" height="1"/><rect x="13" y="1" width="2" height="1"/><rect x="16" y="1" width="1" height="1"/><rect x="13" y="2" width="1" height="1"/><rect x="15" y="2" width="2" height="1"/><rect x="13" y="3" width="1" height="1"/><rect x="16" y="3" width="1" height="1"/><rect x="13" y="4" width="1" height="1"/><rect x="16" y="4" width="1" height="1"/></svg></span><span id="ver"></span></h1>
|
||||
<h1 id="brand" aria-label="loki" title="Loki — fork d'AJEAN (github.com/nathaninline/ajean, MIT)"><span id="brand-a"><svg viewBox="0 0 4 5" shape-rendering="crispEdges" fill="currentColor"><rect x="0" y="0" width="1" height="5"/><rect x="1" y="4" width="3" height="1"/></svg></span><span id="brand-word"><svg viewBox="0 0 11 5" shape-rendering="crispEdges" fill="currentColor"><rect x="0" y="0" width="3" height="1"/><rect x="0" y="1" width="1" height="3"/><rect x="2" y="1" width="1" height="3"/><rect x="0" y="4" width="3" height="1"/><rect x="4" y="0" width="1" height="5"/><rect x="6" y="0" width="1" height="2"/><rect x="5" y="2" width="1" height="1"/><rect x="6" y="3" width="1" height="2"/><rect x="8" y="0" width="3" height="1"/><rect x="9" y="1" width="1" height="3"/><rect x="8" y="4" width="3" height="1"/></svg></span><span id="ver"></span></h1>
|
||||
<span id="status-svc" class="statuspill" onclick="toggleSvcLog()" title="voir le journal du moteur">…</span>
|
||||
</div>
|
||||
<!-- Avertissement de lancement (App Translocation macOS) — masqué par défaut. -->
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<div id="backdrop" onclick="toggleSide()"></div>
|
||||
<div class="side" id="side">
|
||||
<div class="sidehead">
|
||||
<h1 id="brand" aria-label="loki"><span id="brand-a"><svg viewBox="0 0 4 5" shape-rendering="crispEdges" fill="currentColor"><rect x="1" y="0" width="2" height="1"/><rect x="0" y="1" width="1" height="1"/><rect x="3" y="1" width="1" height="1"/><rect x="0" y="2" width="4" height="1"/><rect x="0" y="3" width="1" height="1"/><rect x="3" y="3" width="1" height="1"/><rect x="0" y="4" width="1" height="1"/><rect x="3" y="4" width="1" height="1"/></svg></span><span id="brand-word"><svg viewBox="0 0 17 5" shape-rendering="crispEdges" fill="currentColor"><rect x="1" y="0" width="1" height="1"/><rect x="1" y="1" width="1" height="1"/><rect x="1" y="2" width="1" height="1"/><rect x="1" y="3" width="1" height="1"/><rect x="0" y="4" width="1" height="1"/><rect x="3" y="0" width="4" height="1"/><rect x="3" y="1" width="1" height="1"/><rect x="3" y="2" width="3" height="1"/><rect x="3" y="3" width="1" height="1"/><rect x="3" y="4" width="4" height="1"/><rect x="9" y="0" width="2" height="1"/><rect x="8" y="1" width="1" height="1"/><rect x="11" y="1" width="1" height="1"/><rect x="8" y="2" width="4" height="1"/><rect x="8" y="3" width="1" height="1"/><rect x="11" y="3" width="1" height="1"/><rect x="8" y="4" width="1" height="1"/><rect x="11" y="4" width="1" height="1"/><rect x="13" y="0" width="1" height="1"/><rect x="16" y="0" width="1" height="1"/><rect x="13" y="1" width="2" height="1"/><rect x="16" y="1" width="1" height="1"/><rect x="13" y="2" width="1" height="1"/><rect x="15" y="2" width="2" height="1"/><rect x="13" y="3" width="1" height="1"/><rect x="16" y="3" width="1" height="1"/><rect x="13" y="4" width="1" height="1"/><rect x="16" y="4" width="1" height="1"/></svg></span><span id="ver"></span></h1>
|
||||
<h1 id="brand" aria-label="loki" title="Loki — fork d'AJEAN (github.com/nathaninline/ajean, MIT)"><span id="brand-a"><svg viewBox="0 0 4 5" shape-rendering="crispEdges" fill="currentColor"><rect x="0" y="0" width="1" height="5"/><rect x="1" y="4" width="3" height="1"/></svg></span><span id="brand-word"><svg viewBox="0 0 11 5" shape-rendering="crispEdges" fill="currentColor"><rect x="0" y="0" width="3" height="1"/><rect x="0" y="1" width="1" height="3"/><rect x="2" y="1" width="1" height="3"/><rect x="0" y="4" width="3" height="1"/><rect x="4" y="0" width="1" height="5"/><rect x="6" y="0" width="1" height="2"/><rect x="5" y="2" width="1" height="1"/><rect x="6" y="3" width="1" height="2"/><rect x="8" y="0" width="3" height="1"/><rect x="9" y="1" width="1" height="3"/><rect x="8" y="4" width="3" height="1"/></svg></span><span id="ver"></span></h1>
|
||||
<span id="status-svc" class="statuspill" onclick="toggleSvcLog()" title="voir le journal du moteur">…</span>
|
||||
</div>
|
||||
<!-- Avertissement de lancement (App Translocation macOS) — masqué par défaut. -->
|
||||
|
||||
Reference in new issue
Block a user