Serveurs MCP?Connecte des serveurs MCP (Model Context Protocol) pour donner de nouveaux outils à l'IA : accès fichiers, bases de données, APIs métier… stdio = programme lancé localement (npx/uvx/binaire) · http = serveur distant. ⚠ un serveur stdio exécute du code sur cette machine, au même titre que le shell.
+
Serveurs MCP?Connecte des serveurs MCP (Model Context Protocol) pour donner de nouveaux outils à l'IA : accès fichiers, bases de données, APIs métier… stdio = programme lancé localement (npx/uvx/binaire) · http = serveur distant. ⚠ un serveur stdio exécute du code sur cette machine, au même titre que le shell.
@@ -826,37 +767,38 @@ button:disabled{opacity:.5;cursor:not-allowed}
compactage automatique du contexte?activé par défaut : quand la conversation approche de la limite de contexte, les vieux tours sont résumés automatiquement (façon Hermes) au lieu de t'imposer un « vider ». Discussions quasi illimitées sans perdre le fil.
- Apparence
- thème
-
-
- mode sombre
-
-
- police?Indépendante du thème. Du thème garde celle prévue par le thème choisi (mono pour AJEAN, système pour ChatGPT, Lexend pour Doux). Lexend est téléchargée depuis Google Fonts, les autres sont déjà sur votre appareil.
-
-
-
Affichage
+ Apparence
+
+ mode sombre
+
+
+
+
Affichage
+
masquer le raisonnement masquer les appels d'outils garder les bulles repliées?Les bulles de raisonnement et d'outil arrivent déjà fermées au lieu de s'ouvrir puis se refermer. Un clic sur leur étiquette les déplie. barre latérale escamotable?La barre latérale devient un tiroir même sur ordinateur : elle reste fermée et s'ouvre avec le bouton ☰. Toute la largeur pour la conversation.
+
- System prompt
-
+ System prompt
+
- Accès OpenAI
+ Accès OpenAI
Endpoint compatible OpenAI?Branchez n'importe quel client compatible OpenAI (OpenCode, Continue, Cursor…) sur ces adresses. Si une clé est définie, le client doit envoyer Authorization: Bearer <clé>.
Modèle : jean
+
Adresse locale (réseau)
- exposer en public (ajean.link)?Rend votre IA joignable depuis n'importe où via https://<machine>.oai.ajean.link/v1 (pour brancher un SaaS). Le trafic est chiffré de bout en bout jusqu'à ce serveur — le relais ajean.link ne voit rien. Nécessite l'accès distant actif.
-
+
+
exposer en public (ajean.link)?Rend votre IA joignable depuis n'importe où via https://<machine>.oai.ajean.link/v1 (pour brancher un SaaS). Le trafic est chiffré de bout en bout jusqu'à ce serveur — le relais ajean.link ne voit rien. Nécessite l'accès distant actif.
+
+
Adresse publique — chiffrée de bout en bout, accessible partout
Clé API?Protège l'endpoint des complétions (llama-server). Indispensable avant d'exposer le serveur sur internet. Modifier la clé redémarre le service.
-
+
Clé API?Protège l'endpoint des complétions (llama-server). Indispensable avant d'exposer le serveur sur internet. Modifier la clé redémarre le service.
ajean.link?Accédez à ce serveur Jean depuis n'importe où, sans ouvrir de port, à travers le relais ajean.link. Le trafic est chiffré de bout en bout : le relais ne voit rien. Abonnement 4,80 €/mois.
-
+
Ouvrez l'accès distant à ce serveur en quelques clics, sans terminal.
+
Votre adresse d'accès distant
-
+
+
Première connexion?À votre première ouverture du portail distant, confirmez l'empreinte et saisissez le code d'appairage : cela verrouille la boîte noire sur CE serveur (anti-interception). Une seule fois par appareil.
Benchmark
@@ -1232,6 +1182,38 @@ function fixMd(s){
return s;
}
function md(src){ return src ? marked.parse(fixMd(src)) : ''; }
+// Les garde-fous du serveur ("[stop: trop d'appels d'outils]") sont concaténés
+// au texte de la réponse : ils arrivent donc en clair, au milieu du markdown.
+// markNotices les sort du fil pour qu'on ne les prenne pas pour une phrase du
+// modèle. En cours de streaming, la parenthèse fermante manque encore → aucune
+// correspondance, donc pas d'encart qui clignote à chaque token.
+const NOTICE_RE=/\[stop\s*:\s*([^\]]+)\]/g;
+function markNotices(root){
+ const walk=document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
+ const hits=[];
+ while(walk.nextNode()){
+ const n=walk.currentNode;
+ // Un exemple dans un bloc de code reste du code.
+ if(n.parentElement && n.parentElement.closest('pre,code')) continue;
+ NOTICE_RE.lastIndex=0;
+ if(NOTICE_RE.test(n.nodeValue)) hits.push(n);
+ }
+ hits.forEach(n=>{
+ const frag=document.createDocumentFragment();
+ let rest=n.nodeValue, m;
+ NOTICE_RE.lastIndex=0;
+ while((m=NOTICE_RE.exec(rest))!==null){
+ if(m.index) frag.appendChild(document.createTextNode(rest.slice(0,m.index)));
+ const tag=document.createElement('span');
+ tag.className='stopnote'; tag.textContent=m[1].trim();
+ frag.appendChild(tag);
+ rest=rest.slice(m.index+m[0].length);
+ NOTICE_RE.lastIndex=0;
+ }
+ if(rest) frag.appendChild(document.createTextNode(rest));
+ n.parentNode.replaceChild(frag, n);
+ });
+}
let msgs = [];
let busy = false;
function toggleSide(){ document.getElementById('side').classList.toggle('open'); document.getElementById('backdrop').classList.toggle('open'); document.body.classList.toggle('drawer-open'); }
@@ -1251,106 +1233,32 @@ async function loadSys(){
if(d && d.ok){ document.getElementById('sysprompt').value = d.text || ''; localStorage.setItem('jean.sys', d.text || ''); }
}catch(e){}
}
-// ===== Thèmes ================================================================
-// Registre des thèmes disponibles. Pour en AJOUTER un : ajouter un bloc
-// [data-theme="…"] dans le
@@ -38,25 +38,27 @@
- GPU
-
…
+
+ Machine
+
+
…
+
+
- RAM
-
…
+ Config active
+
…
- Config active
-
…
-
- Presets
+ Presets
- Mode agent
- activer le mode agent?⚠ active l'accès machine (shell complet via bash sur le serveur) — l'IA peut inspecter, lancer des scripts, lire/éditer des fichiers (timeout 30s, max 300s). Mémoire et accès internet ci-dessous ne fonctionnent que si le mode agent est activé.
+ Mode agent
+
activer le mode agent?⚠ active l'accès machine (shell complet via bash sur le serveur) — l'IA peut inspecter, lancer des scripts, lire/éditer des fichiers (timeout 30s, max 300s). Mémoire et accès internet ci-dessous ne fonctionnent que si le mode agent est activé.
Mémoire?
- mode
-
-
Accès internet?Ajoute les outils web_search / web_open / web_read / web_grep via un serveur Crawl4AI. Actifs seulement si le serveur répond.
+
Accès internet?Ajoute les outils web_search / web_open / web_read / web_grep via un serveur Crawl4AI. Actifs seulement si le serveur répond.
donner internet à l'IA
-
+
-
+
@@ -91,7 +93,7 @@
-
Serveurs MCP?Connecte des serveurs MCP (Model Context Protocol) pour donner de nouveaux outils à l'IA : accès fichiers, bases de données, APIs métier… stdio = programme lancé localement (npx/uvx/binaire) · http = serveur distant. ⚠ un serveur stdio exécute du code sur cette machine, au même titre que le shell.
+
Serveurs MCP?Connecte des serveurs MCP (Model Context Protocol) pour donner de nouveaux outils à l'IA : accès fichiers, bases de données, APIs métier… stdio = programme lancé localement (npx/uvx/binaire) · http = serveur distant. ⚠ un serveur stdio exécute du code sur cette machine, au même titre que le shell.
@@ -101,37 +103,38 @@
compactage automatique du contexte?activé par défaut : quand la conversation approche de la limite de contexte, les vieux tours sont résumés automatiquement (façon Hermes) au lieu de t'imposer un « vider ». Discussions quasi illimitées sans perdre le fil.
- Apparence
- thème
-
-
- mode sombre
-
-
- police?Indépendante du thème. Du thème garde celle prévue par le thème choisi (mono pour AJEAN, système pour ChatGPT, Lexend pour Doux). Lexend est téléchargée depuis Google Fonts, les autres sont déjà sur votre appareil.
-
-
-
Affichage
+ Apparence
+
+ mode sombre
+
+
+
+
Affichage
+
masquer le raisonnement masquer les appels d'outils garder les bulles repliées?Les bulles de raisonnement et d'outil arrivent déjà fermées au lieu de s'ouvrir puis se refermer. Un clic sur leur étiquette les déplie. barre latérale escamotable?La barre latérale devient un tiroir même sur ordinateur : elle reste fermée et s'ouvre avec le bouton ☰. Toute la largeur pour la conversation.
+
- System prompt
-
+ System prompt
+
- Accès OpenAI
+ Accès OpenAI
Endpoint compatible OpenAI?Branchez n'importe quel client compatible OpenAI (OpenCode, Continue, Cursor…) sur ces adresses. Si une clé est définie, le client doit envoyer Authorization: Bearer <clé>.
Modèle : jean
+
Adresse locale (réseau)
- exposer en public (ajean.link)?Rend votre IA joignable depuis n'importe où via https://<machine>.oai.ajean.link/v1 (pour brancher un SaaS). Le trafic est chiffré de bout en bout jusqu'à ce serveur — le relais ajean.link ne voit rien. Nécessite l'accès distant actif.
-
+
+
exposer en public (ajean.link)?Rend votre IA joignable depuis n'importe où via https://<machine>.oai.ajean.link/v1 (pour brancher un SaaS). Le trafic est chiffré de bout en bout jusqu'à ce serveur — le relais ajean.link ne voit rien. Nécessite l'accès distant actif.
+
+
Adresse publique — chiffrée de bout en bout, accessible partout
@@ -139,8 +142,9 @@
-
Clé API?Protège l'endpoint des complétions (llama-server). Indispensable avant d'exposer le serveur sur internet. Modifier la clé redémarre le service.
-
+
Clé API?Protège l'endpoint des complétions (llama-server). Indispensable avant d'exposer le serveur sur internet. Modifier la clé redémarre le service.
+
+
@@ -150,33 +154,36 @@
+
- Accès distant
+ Accès distant
ajean.link?Accédez à ce serveur Jean depuis n'importe où, sans ouvrir de port, à travers le relais ajean.link. Le trafic est chiffré de bout en bout : le relais ne voit rien. Abonnement 4,80 €/mois.
-
+
Ouvrez l'accès distant à ce serveur en quelques clics, sans terminal.
+
Votre adresse d'accès distant
-
+
+
Première connexion?À votre première ouverture du portail distant, confirmez l'empreinte et saisissez le code d'appairage : cela verrouille la boîte noire sur CE serveur (anti-interception). Une seule fois par appareil.
-
-
-
-
+
+
+
+
- MOTEUR
+ Moteur
…
@@ -201,20 +208,24 @@
- Service
+ Service
+
+
- Actions
-
-
-
-
-
-
+ Actions
+
+
+
+
+
+
+
+
@@ -240,7 +251,7 @@
-
+
Benchmark
diff --git a/internal/jean/ui/src/js/00-md.js b/internal/jean/ui/src/js/00-md.js
index f53222b..5576741 100644
--- a/internal/jean/ui/src/js/00-md.js
+++ b/internal/jean/ui/src/js/00-md.js
@@ -15,6 +15,38 @@ function fixMd(s){
return s;
}
function md(src){ return src ? marked.parse(fixMd(src)) : ''; }
+// Les garde-fous du serveur ("[stop: trop d'appels d'outils]") sont concaténés
+// au texte de la réponse : ils arrivent donc en clair, au milieu du markdown.
+// markNotices les sort du fil pour qu'on ne les prenne pas pour une phrase du
+// modèle. En cours de streaming, la parenthèse fermante manque encore → aucune
+// correspondance, donc pas d'encart qui clignote à chaque token.
+const NOTICE_RE=/\[stop\s*:\s*([^\]]+)\]/g;
+function markNotices(root){
+ const walk=document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
+ const hits=[];
+ while(walk.nextNode()){
+ const n=walk.currentNode;
+ // Un exemple dans un bloc de code reste du code.
+ if(n.parentElement && n.parentElement.closest('pre,code')) continue;
+ NOTICE_RE.lastIndex=0;
+ if(NOTICE_RE.test(n.nodeValue)) hits.push(n);
+ }
+ hits.forEach(n=>{
+ const frag=document.createDocumentFragment();
+ let rest=n.nodeValue, m;
+ NOTICE_RE.lastIndex=0;
+ while((m=NOTICE_RE.exec(rest))!==null){
+ if(m.index) frag.appendChild(document.createTextNode(rest.slice(0,m.index)));
+ const tag=document.createElement('span');
+ tag.className='stopnote'; tag.textContent=m[1].trim();
+ frag.appendChild(tag);
+ rest=rest.slice(m.index+m[0].length);
+ NOTICE_RE.lastIndex=0;
+ }
+ if(rest) frag.appendChild(document.createTextNode(rest));
+ n.parentNode.replaceChild(frag, n);
+ });
+}
let msgs = [];
let busy = false;
function toggleSide(){ document.getElementById('side').classList.toggle('open'); document.getElementById('backdrop').classList.toggle('open'); document.body.classList.toggle('drawer-open'); }
diff --git a/internal/jean/ui/src/js/01-theme.js b/internal/jean/ui/src/js/01-theme.js
index 1be7036..7819e39 100644
--- a/internal/jean/ui/src/js/01-theme.js
+++ b/internal/jean/ui/src/js/01-theme.js
@@ -1,103 +1,29 @@
-// ===== Thèmes ================================================================
-// Registre des thèmes disponibles. Pour en AJOUTER un : ajouter un bloc
-// [data-theme="…"] dans le