5815f0b8f3
"что ты умеешь" reached the personal boundary, which claimed it as his and said "не знаю — не нашла у тебя такой записи" about her own description. Letting it past would be no better: SearXNG answers about somebody else's assistant. A self query source above the boundary, reading one frozen description. It is NOT a note — notes are his, and a note about her would come back for "что я записал", would be fed to the digestion worker as something he said, and would be recalled by proximity for questions that are not about her. The description names only what this box does. Everything that depends on config — the house, the LAN, the feeds, the list, weather, telegram — is named as depending on what he allowed, and a test pins that split: inventing a capability here is the same defect as inventing a fact. topicSelf is scored like every other topic, with a narrow keyword floor for the no-embedder case. "что ты умеешь" moved off topicOther, where it had been sitting so an attention question had something to lose to — a phrasing on two sides never clears the margin. TestONNXTopics 38/38 -> 43/43 on held-out utterances.
97 lines
3.4 KiB
Go
97 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/kami/maven/internal/router"
|
|
)
|
|
|
|
// TestSelfFloorClaimsAQuestionAboutHerAndNothingElse — the offline floor, which
|
|
// is what answers with no embedder. Narrow on purpose, so the rows that must
|
|
// NOT match are the point.
|
|
func TestSelfFloorClaimsAQuestionAboutHerAndNothingElse(t *testing.T) {
|
|
claimed := []string{
|
|
"что ты умеешь",
|
|
"что ты можешь",
|
|
"а что ты умеешь?",
|
|
"кто ты",
|
|
"кто ты такая?",
|
|
"расскажи о себе",
|
|
"what can you do",
|
|
"who are you",
|
|
}
|
|
for _, u := range claimed {
|
|
if !selfFloor(u) {
|
|
t.Errorf("%q is a question about her and the floor missed it", u)
|
|
}
|
|
}
|
|
declined := []string{
|
|
"что у меня сегодня",
|
|
"расскажи про байкал",
|
|
"кто изобрёл телефон",
|
|
"что требует внимания",
|
|
"запиши что я пил воду",
|
|
// The floor spells its own word boundaries out, because Go's \b never
|
|
// fires next to a Cyrillic letter. Without that these would match.
|
|
"кто тыкал в розетку",
|
|
"расскажи о себестоимости",
|
|
}
|
|
for _, u := range declined {
|
|
if selfFloor(u) {
|
|
t.Errorf("%q is not about her and the floor claimed it", u)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestSelfSourceAnswersFromTheDescription — with no embedder the source falls
|
|
// to the floor, and the answer has to be the description rather than silence.
|
|
func TestSelfSourceAnswersFromTheDescription(t *testing.T) {
|
|
h := personalHandler()
|
|
reply, claimed := h.querySelf(context.Background(), &queryTurn{
|
|
dec: router.Decision{Utterance: "что ты умеешь"},
|
|
})
|
|
if !claimed {
|
|
t.Fatal("a question about her must be claimed above the boundary")
|
|
}
|
|
if !strings.Contains(reply, "напоминания") {
|
|
t.Errorf("the answer must come from the description: %q", reply)
|
|
}
|
|
if _, claimed := h.querySelf(context.Background(), &queryTurn{
|
|
dec: router.Decision{Utterance: "почему небо синее"},
|
|
}); claimed {
|
|
t.Error("a world question must pass this source")
|
|
}
|
|
}
|
|
|
|
// TestSelfDescriptionHoldsThePersona — it is her own text and she reads it out,
|
|
// so the same rules the phrasing eval enforces apply to it. Feminine
|
|
// self-reference, informal address, no pet names.
|
|
func TestSelfDescriptionHoldsThePersona(t *testing.T) {
|
|
lower := strings.ToLower(selfDescription)
|
|
for _, bad := range []string{"я рад ", "я готов ", "вы ", "ваш", "милый", "дорогой"} {
|
|
if strings.Contains(lower, bad) {
|
|
t.Errorf("the description breaks the persona on %q", bad)
|
|
}
|
|
}
|
|
for _, want := range []string{"тво", "ты"} {
|
|
if !strings.Contains(lower, want) {
|
|
t.Errorf("the description must address him directly, missing %q", want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestSelfDescriptionClaimsNothingUnconditionally — the constraint that makes
|
|
// this text safe to read out. Every capability that depends on config has to be
|
|
// named as depending on it, and inventing one here is the same defect as
|
|
// inventing a fact.
|
|
func TestSelfDescriptionClaimsNothingUnconditionally(t *testing.T) {
|
|
conditional := selfDescription[strings.Index(selfDescription, "Что зависит"):]
|
|
for _, cap := range []string{"дом", "локальная сеть", "ленты", "список покупок", "погода", "телеграм"} {
|
|
if !strings.Contains(conditional, cap) {
|
|
t.Errorf("%q is configured, not wired — it must sit under the conditional half", cap)
|
|
}
|
|
}
|
|
}
|