diff --git a/llm.go b/llm.go index 1916585..861f560 100644 --- a/llm.go +++ b/llm.go @@ -478,8 +478,20 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps if err := json.Unmarshal([]byte(data), &chunk); err != nil { continue } - // Le chunk d'usage (include_usage) arrive seul, sans choices : on l'émet - // avant le guard pour ne pas le perdre. + // Timings ET usage (include_usage) arrivent sur le CHUNK FINAL qui, sur ce + // build llama.cpp (MTP/spéculatif), a `choices:[]` — on les traite AVANT le + // garde de choices, sinon `gen_tokens`/`gen_per_second` (decode) sont jetés + // et l'UI retombe à « 0 tok/s » à la fin de la génération. + if chunk.Timings != nil { + stats.PromptTokens = chunk.Timings.PromptN + stats.PromptPerSecond = chunk.Timings.PromptPerSecond + stats.PromptMs = chunk.Timings.PromptMs + stats.GenTokens = chunk.Timings.PredictedN + stats.GenPerSecond = chunk.Timings.PredictedPerSec + stats.GenMs = chunk.Timings.PredictedMs + s := stats + cb(StreamEvent{Stats: &s}) + } if chunk.Usage != nil && chunk.Usage.PromptTokens > 0 { stats.PromptTokensTotal = chunk.Usage.PromptTokens s := stats @@ -492,16 +504,6 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps if ch.FinishReason != "" { finishReason = ch.FinishReason } - if chunk.Timings != nil { - stats.PromptTokens = chunk.Timings.PromptN - stats.PromptPerSecond = chunk.Timings.PromptPerSecond - stats.PromptMs = chunk.Timings.PromptMs - stats.GenTokens = chunk.Timings.PredictedN - stats.GenPerSecond = chunk.Timings.PredictedPerSec - stats.GenMs = chunk.Timings.PredictedMs - s := stats - cb(StreamEvent{Stats: &s}) - } if len(ch.Delta.ToolCalls) > 0 { for i, tc := range ch.Delta.ToolCalls { // llama.cpp's stream may omit index; fall back to slot i. diff --git a/main.go b/main.go index 94f4373..723494e 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ import ( "strings" ) -const Version = "0.2.19" +const Version = "0.2.20" func main() { // Migration one-shot des anciens skills (SKILLS//SKILL.md) vers la diff --git a/resource_windows_amd64.syso b/resource_windows_amd64.syso index fc5dc40..1a44b4c 100644 Binary files a/resource_windows_amd64.syso and b/resource_windows_amd64.syso differ diff --git a/resource_windows_arm64.syso b/resource_windows_arm64.syso index d758a2c..7627904 100644 Binary files a/resource_windows_arm64.syso and b/resource_windows_arm64.syso differ diff --git a/versioninfo.json b/versioninfo.json index 12b4d0b..fad94f8 100644 --- a/versioninfo.json +++ b/versioninfo.json @@ -3,13 +3,13 @@ "FileVersion": { "Major": 0, "Minor": 2, - "Patch": 19, + "Patch": 20, "Build": 0 }, "ProductVersion": { "Major": 0, "Minor": 2, - "Patch": 19, + "Patch": 20, "Build": 0 }, "FileFlagsMask": "3f", @@ -25,7 +25,7 @@ "LegalCopyright": "Copyright (c) 2026 Jean contributors. MIT License.", "OriginalFilename": "jean.exe", "ProductName": "Jean", - "ProductVersion": "0.2.19", + "ProductVersion": "0.2.20", "Comments": "https://github.com/nathaninline/jean — projet open source (MIT)" }, "VarFileInfo": {