- Subscribe rejoue le journal COALESCE (deltas texte consecutifs fusionnes en un
evenement, avec toks + bornes ts) : chargement rapide meme sur longue conv, fini
le rendu markdown quadratique token par token
- send() resilient : retry, 409/generating traite comme succes -> plus de 'network
error' alarmiste alors que l'IA repond quand meme ; reconnexion du flux plus rapide
- serveur emet {caught_up} quand le replay est draine ; le client cree alors les
bulles raisonnement/outil DEJA repliees (collapseInstant, sans animation) tant
qu'on rejoue le journal -> au refresh elles apparaissent fermees direct
- 'Mise a jour' passe au-dessus de 'Actions'
- le toggle compactage rejoint la section Parametres (sous le mode agent)
Le calcul cote client (performance.now) donnait une vitesse presente ou non selon
que le tour etait live ou rejoue. On horodate chaque LogEvent cote serveur (TS) et
le client derive tok/s de firstTs->lastTs : correct en direct ET au replay. Hack
replayTarget supprime.
La refonte serveur avait supprime le compteur live par bulle. On le recalcule
cote client au fil des deltas ; en replay (refresh) on n'affiche que le nombre de
tokens (pas de vitesse absurde car tout arrive d'un bloc), via replayTarget.
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.