From 142dd872995fa84be55db8ba5880d6f49671d756 Mon Sep 17 00:00:00 2001 From: nathaninline Date: Fri, 24 Jul 2026 17:06:13 +0200 Subject: [PATCH] v0.5.2 : robustesse appels d'outils + nettoyage UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Chat : valide le JSON des arguments d'outil avant de les stocker dans l'historique. Un modèle très quantifié pouvait émettre des arguments tronqués/non-JSON (non vides) qui, persistés, faisaient échouer le template de chat de llama.cpp à chaque requête → 500 en boucle jusqu'au reset. json.Valid remplace le simple test != "" (llm_client.go). - UI : section « Accès OpenAI » remise au propre (adresses locale/publique groupées, clé API), sans émojis ; « Accès distant » sans émojis. Classes .io-input/.io-cap partagées. --- cmd/jean/resource_windows_amd64.syso | Bin 8340 -> 8340 bytes cmd/jean/resource_windows_arm64.syso | Bin 8340 -> 8340 bytes cmd/jean/versioninfo.json | 6 +-- internal/jean/llm_client.go | 10 ++++- internal/jean/run.go | 2 +- internal/jean/ui/index.html | 53 ++++++++++++++----------- internal/jean/ui/src/index.tmpl.html | 45 +++++++++++---------- internal/jean/ui/src/js/06-settings.js | 2 +- internal/jean/ui/src/styles.css | 6 +++ 9 files changed, 73 insertions(+), 51 deletions(-) diff --git a/cmd/jean/resource_windows_amd64.syso b/cmd/jean/resource_windows_amd64.syso index bc0a39b3b7f6d675d05456065a7c8154fcd1d8a8..49a3bc40cf70da22a7588075ba0cceb7f5f677d6 100644 GIT binary patch delta 36 ncmbQ@IK^>;lnf^m11kdvFl|;lnf^$11kdvFm6_s5oBUC+-xcr%m}19<+&LFgJ%ZI diff --git a/cmd/jean/resource_windows_arm64.syso b/cmd/jean/resource_windows_arm64.syso index 2552e14c5e54ba0b33d0fecdd12533bacd0c9f0b..45c3f44cc6da12271636c25eed6c4277c4020e1c 100644 GIT binary patch delta 36 ncmbQ@IK^>;lnf^m11kdvFl|;lnf^$11kdvFm6_s5oBUC+-xcr%m}19<+&LFgJ%ZI diff --git a/cmd/jean/versioninfo.json b/cmd/jean/versioninfo.json index 02208c7..64ff05d 100644 --- a/cmd/jean/versioninfo.json +++ b/cmd/jean/versioninfo.json @@ -3,13 +3,13 @@ "FileVersion": { "Major": 0, "Minor": 5, - "Patch": 1, + "Patch": 2, "Build": 0 }, "ProductVersion": { "Major": 0, "Minor": 5, - "Patch": 1, + "Patch": 2, "Build": 0 }, "FileFlagsMask": "3f", @@ -25,7 +25,7 @@ "LegalCopyright": "Copyright (c) 2026 Jean contributors. MIT License.", "OriginalFilename": "jean.exe", "ProductName": "Jean", - "ProductVersion": "0.5.1", + "ProductVersion": "0.5.2", "Comments": "https://github.com/nathaninline/jean — projet open source (MIT)" }, "VarFileInfo": { diff --git a/internal/jean/llm_client.go b/internal/jean/llm_client.go index 88bd1aa..9ed4837 100644 --- a/internal/jean/llm_client.go +++ b/internal/jean/llm_client.go @@ -679,7 +679,15 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps if tc.ID == "" { tc.ID = fmt.Sprintf("call_%d_%d", iter, i) } - if tc.Function.Arguments == "" { + // Les arguments DOIVENT être du JSON valide : ils sont rangés dans + // l'historique vu par le modèle, et le template de chat de llama.cpp les + // re-parse à CHAQUE requête suivante. Un modèle très quantifié peut sortir + // des arguments vides OU tronqués/non-JSON (ex: `{"command":"python3 …`) ; + // stockés tels quels, ils font échouer le parsing du template → 500 en + // boucle jusqu'au reset. On neutralise tout ce qui n'est pas du JSON valide + // en objet vide (l'appel a de toute façon déjà été exécuté). json.Valid("") + // étant faux, ça couvre aussi le cas vide d'origine. + if !json.Valid([]byte(tc.Function.Arguments)) { tc.Function.Arguments = "{}" } tcs = append(tcs, tc) diff --git a/internal/jean/run.go b/internal/jean/run.go index 8fc0d61..c8712a8 100644 --- a/internal/jean/run.go +++ b/internal/jean/run.go @@ -10,7 +10,7 @@ import ( "strings" ) -const Version = "0.5.1" +const Version = "0.5.2" // Main est le vrai main() du binaire (cmd/jean ne fait que l'appeler). func Main() { diff --git a/internal/jean/ui/index.html b/internal/jean/ui/index.html index d4f3233..45c91c6 100644 --- a/internal/jean/ui/index.html +++ b/internal/jean/ui/index.html @@ -378,6 +378,12 @@ button:disabled{opacity:.5;cursor:not-allowed} .mcp-tool-row:hover{background:var(--panel)} .mcp-tool-switch{flex:none;transform:scale(.85)} .mcp-tool-name{font-size:12px;color:var(--text);word-break:break-all} + +/* Accès OpenAI / Accès distant : champs lecture seule (URL, clé) + libellés + compacts, pour une présentation homogène et sans surcharge visuelle. */ +.io-cap{color:var(--dim);font-size:11px;margin:0 0 3px} +.io-input{flex:1;min-width:0;background:var(--panel);color:var(--text);border:1px solid var(--border);border-radius:6px;padding:6px;font:inherit;font-size:12px} +.io-group{margin-top:12px}
@@ -455,27 +461,28 @@ button:disabled{opacity:.5;cursor:not-allowed}
Accès OpenAI -
Endpoint compatible OpenAI?Branche n'importe quel client compatible OpenAI (OpenCode, Continue, Cursor…) sur cette URL. Modèle : jean. Si une clé est définie, le client doit envoyer Authorization: Bearer <clé>.
- -
Accès OpenAI -
Endpoint compatible OpenAI?Branche n'importe quel client compatible OpenAI (OpenCode, Continue, Cursor…) sur cette URL. Modèle : jean. Si une clé est définie, le client doit envoyer Authorization: Bearer <clé>.
- -