L'historique et la generation vivent desormais sur le serveur jean, plus dans le
localStorage du navigateur :
- conversation.go : store unique (Messages vue modele + Log d'evenements rejouable),
persistance disque JeanHome/conversation.json, generation dans une goroutine
detachee (context.Background) -> fermer le navigateur ne coupe plus la reponse
- runChatStream devient un pur abonne (rejoue Log[from:] puis suit le direct) ;
nouveaux endpoints /api/chat/send|stop|reset|state
- UI : flux d'abonnement permanent + replay du journal (outils/vitesses/raisonnement
reviennent apres refresh), synchro live inter-appareils, reconnexion auto
- compactage manuel neutralise (auto cote serveur), vitesses rendues depuis les
stats persistees
L'heuristique ~4 char/token sous-estimait le contexte (elle ne voit ni le prompt
systeme injecte ni le gabarit de chat), donc le seuil 75% n'etait jamais franchi.
Le client envoie desormais ctx_used (prompt_tokens_total deja affiche) ; repli sur
l'estimation quand inconnu (terminal).
- nouveau compact.go : split head/torso/tail, elagage des vieux tool outputs
sans IA + resume du torse par le modele local (un appel non-streame)
- proactif au seuil (75% de CTX) dans runChatStream + chat terminal, et filet
reactif dans runChat si llama-server refuse un prompt trop long
- resume injecte en tour user->assistant (jamais un system au milieu : garde Qwen)
- toggle COMPACT (defaut on) : endpoint /api/agent/compact + case UI, event
history_replace pour que le client remplace son historique, toast
- tests unitaires des frontieres head/tail et de la non-separation des paires outil
- supprime skills.go (Skill, ListSkills, SkillContent, SaveSkill, AppendSkill,
DeleteSkill, safeSkillDir, skillsSystemPrompt : plus aucun appelant)
- retire les handlers/routes /api/skill, /api/skill/save, /api/skill/delete
(aucun client : ni UI locale, ni ajean-app, ni jean-relay)
- conserve les alias retro-compat /api/skills(/toggle) -> handleAgent, la
migration migrateSkillsToMemory et legacySkillsFlag
- panneau Acces OpenAI dans l'UI (endpoint /v1, cle API masquee, generer/definir/retirer)
- endpoint OpenAI PUBLIC <machine>.oai.ajean.link (passthrough SNI, VPS relais aveugle,
cert Let's Encrypt via TLS-ALPN-01 par le tunnel), toggle 'exposer en public'
- UI: système de thèmes sélectionnable (sombre par défaut, clair) — registre extensible
- UI: refonte propre du panneau Mode agent — Mémoire / Accès internet / Paramètres en cartes, liste des pages repliable
- UI: infobulles (?) à la place des pavés de texte, scrollbars natifs, suppression des touches de vert (palette bleu/blanc/gris)
- UI: favicon (coins arrondis) + icône PWA, nom d'app et titres « Jean »
- Mémoire et accès internet deviennent des sous-réglages du mode agent (aucun outil mem_*/web sans agent)
- Presets: le mode mémoire (MEM_MODE) et l'URL du serveur internet (CRAWL4AI_URL) sont conservés d'un preset à l'autre
- accès web de l'IA via un serveur Crawl4AI configurable (outils
web_search / web_open / web_read / web_grep), réglage CRAWL4AI_URL +
toggle, actifs seulement si le mode agent et le serveur sont joignables.
CLI `jean internet [on|off|status|url <url>]`.
- mémoire réglable en 3 modes indépendants du mode agent : off / sur
demande / auto (proactive). CLI `jean memory [off|ondemand|always|status]`.
- fix : prompt et outils gouvernés par la même condition (plus de
web_search tapé en bash quand le crawl est injoignable) ; consigne
année de recherche durcie ; icône 🌐 des outils web dans l'UI.
Ajout d'un système de modale réutilisable askConfirm/askPrompt/askAlert
(Promise-based, Échap/clic-dehors = annuler, Entrée = valider) qui remplace
les 5 confirm()/prompt() natifs (auth, mode agent, switch preset, suppression,
compactage). _openAsk est polymorphe : accepte (message, opts) [UI] et l'objet
{title,msg,yes,no,placeholder} de e2e.js — sur ajean.link/server.html cette
fonction remplace le window.askConfirm du bootstrap boîte noire, donc doit
servir aussi les invites empreinte/appairage E2E.
La liste des pages mémoire déroulait une barre géante quand elle grossit.
Désormais : compteur, champ de filtre (affiché au-delà de 50 pages), liste
scrollable (max-height 240px) et rendu plafonné par paliers de 50 ("voir
plus"). Rendu en DOM (échappement sûr) au lieu d'interpolation innerHTML.
La limite iter<8 (message [stop: trop d'appels d'outils]) est désormais
pilotée par TOOL_LIMIT dans config.env, exposée par un interrupteur sous
Mode agent. Activée par défaut ; désactivée => plafond quasi illimité
(l'anti-boucle sur appels répétés reste actif). Lu à chaque tour, pas de
restart nécessaire. Tunnelé tel quel via /api/e2e/req pour ajean.link.
- bulles reasoning/outil repliables (clic), repli fluide en diagonale (height+width animes en JS)
- chainage : chaque etape se replie des que la suivante demarre, la reponse finale replie la derniere
- compteur de tokens sur chaque bulle (reasoning : gen tok/s ; outil : ~taille reponse)
- bulles d'outil au meme design pointille transparent que le reasoning
- contexte : comptage exact via usage.prompt_tokens (system prompt inclus meme en cache KV)
- barre de contexte redessinee, integree au composer de saisie
Les tours d'outils (lecture de skill, commandes shell) ne survivaient
qu'a l'interieur de la boucle agentique d'un seul tour : seul le texte
final etait persiste. Resultat : a chaque nouveau message le modele
n'avait aucune trace d'avoir deja lu un skill, donc il le re-appelait
en boucle et confabulait des chemins/resultats disparus du contexte.
runChat retourne desormais les messages intermediaires (assistant
tool_calls + resultats tool). Le CLI les insere dans l'historique avant
la reponse finale ; le serveur web les emet en fin de flux SSE pour que
le client (stateless) les stocke. Couvre aussi ajean.link via E2E
(handleE2EChat -> runChatStream).
Embarque editeur/version/description dans le .exe via goversioninfo (.syso)
pour reduire les faux positifs antivirus sur le binaire Go. Ajoute un
workflow GitHub Actions qui build les 6 cibles et publie la release sur tag.