8833a9c76b
The prompt, the call and the output parsing now live in internal/phraser. What is left here is the one thing the daemon adds: a clarify, a model error and an unusable generation all answer from voice.StubReplier, so a turn never breaks on the model. The duplicated stripThink and parseResponseMood copies are gone; capture.go uses phraser.StripThink.
58 lines
1.8 KiB
Go
58 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/kami/maven/internal/llm"
|
|
"github.com/kami/maven/internal/router"
|
|
"github.com/kami/maven/internal/voice"
|
|
)
|
|
|
|
// The phrasing itself is tested in internal/phraser. What is left here is the
|
|
// only thing the daemon adds: the stub floor, on the three ways a reply can
|
|
// fail to arrive.
|
|
type stubCompleter struct {
|
|
out string
|
|
err error
|
|
}
|
|
|
|
func (s stubCompleter) Complete(_ context.Context, _ llm.Req) (string, error) { return s.out, s.err }
|
|
|
|
func TestLLMReplierPassesTheModelReplyThrough(t *testing.T) {
|
|
r := newLLMReplier(stubCompleter{out: `{"response":"записала, кофе закончился","mood":"neutral"}`}, nil)
|
|
got := r.Reply(router.Decision{Intent: router.IntentNote, Slots: router.Slots{Text: "кофе закончился"}})
|
|
if got != "записала, кофе закончился" {
|
|
t.Errorf("got %q, want %q", got, "записала, кофе закончился")
|
|
}
|
|
}
|
|
|
|
func TestLLMReplierFallsBackToStubOnError(t *testing.T) {
|
|
r := newLLMReplier(stubCompleter{err: errReplierTest}, nil)
|
|
assertStub(t, r, router.Decision{Intent: router.IntentNote}, "llm error")
|
|
}
|
|
|
|
func TestLLMReplierFallsBackToStubOnEmpty(t *testing.T) {
|
|
r := newLLMReplier(stubCompleter{out: ""}, nil)
|
|
assertStub(t, r, router.Decision{Intent: router.IntentNote}, "empty llm")
|
|
}
|
|
|
|
func TestLLMReplierClarifyUsesStub(t *testing.T) {
|
|
r := newLLMReplier(stubCompleter{out: "я всё поняла"}, nil)
|
|
assertStub(t, r, router.Decision{Clarify: true}, "clarify")
|
|
}
|
|
|
|
func assertStub(t *testing.T, r *llmReplier, d router.Decision, what string) {
|
|
t.Helper()
|
|
got, want := r.Reply(d), voice.NewStubReplier().Reply(d)
|
|
if got != want {
|
|
t.Errorf("on %s: got %q, want stub %q", what, got, want)
|
|
}
|
|
}
|
|
|
|
var errReplierTest = errTest("llm down")
|
|
|
|
type errTest string
|
|
|
|
func (e errTest) Error() string { return string(e) }
|