From 9a70f7378b397fb0ec6c6f8c6a2fc597499b8205 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 4 Aug 2026 00:47:31 +0400 Subject: [PATCH] phraser: move errEmptyResponse next to its only caller (V-397) It sat in world.go, which is about the workstation model; it is a phrasing error and belongs in llmphraser.go. Also trims the PhraseQuery doc. Co-Authored-By: Claude Opus 5 --- internal/phraser/llmphraser.go | 14 ++++++++++---- internal/phraser/world.go | 5 ----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/internal/phraser/llmphraser.go b/internal/phraser/llmphraser.go index d5f7b31..5fcc6b5 100644 --- a/internal/phraser/llmphraser.go +++ b/internal/phraser/llmphraser.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" "io" "log" @@ -26,6 +27,11 @@ import ( var listenRE = regexp.MustCompile(`listening on (https?://\S+)`) +// errEmptyResponse — the server answered and said nothing. Separate from a +// transport failure: the model is up and produced no tokens, which is still not +// an answer and must not score as one. +var errEmptyResponse = errors.New("phraser: empty response from the model") + type LLMPhraser struct { cfg Config client *http.Client @@ -428,10 +434,10 @@ func (p *LLMPhraser) PhraseNudge(ctx context.Context, c loop.Candidate) (deliver } // PhraseQuery prompts the LLM with the user's utterance and matching notes to -// compose a natural answer. On any LLM error it returns BOTH the fallback text -// ("вот что я нашла: ", or "не знаю." with no notes) AND the error, so a -// caller that wants to keep the turn alive uses the text and a caller that is -// measuring counts the failure. Until Vikunja #397 the error was swallowed and a +// compose a natural answer. On any LLM error it returns the fallback text — +// "вот что я нашла: ", or "не знаю." with no notes — and the error +// together. The daemon uses the text and keeps the turn alive; a caller that is +// measuring counts the failure. Until Vikunja #397 the error was dropped, so a // dead server scored as bad phrasing. func (p *LLMPhraser) PhraseQuery(ctx context.Context, utterance string, notes []string) (string, error) { // Blank sources are no sources. A caller that hands over one empty string — diff --git a/internal/phraser/world.go b/internal/phraser/world.go index b9ebc1e..a021a4b 100644 --- a/internal/phraser/world.go +++ b/internal/phraser/world.go @@ -37,11 +37,6 @@ type Remote interface { // (docs/evals/2026-08-02-workstation-gemma4-12b.md). var ErrNoWorldModel = errors.New("phraser: no world model available") -// errEmptyResponse — the server answered and said nothing. A separate error from -// a transport failure because it means the model is up and produced no tokens, -// which is still not an answer and must not score as one. -var errEmptyResponse = errors.New("phraser: empty response from the model") - // chatTemperature — what the phraser's own transport has always sampled at. // Named so the remote path cannot drift from it silently. Whether 0.7 is right // at all is Vikunja #402, and answering that here would hide a phrasing change