Files
Maven/internal/router/agenda_test.go
claude 43f2c37538 router: stage 0 claims the other days and the named event (V-471)
"какие планы на сегодня" worked and "какие планы на завтра" answered
"пока не умею": the agenda rule needs "у меня" or a calendar noun, and
that phrasing carries neither. "когда планёрка?" had the same shape.

Two rules. One takes a plan noun aimed at a named day, one takes a closed
list of event nouns after "когда"/"во сколько". Both route intent only,
so the query chain still decides which source answers.

classifier+onnx over the fixture: 55/79, 69.6% full, with the two new
cases passing and no case moving the other way.
2026-08-04 02:52:51 +04:00

122 lines
4.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package router
import (
"context"
"testing"
)
// agendaRouter wires both grammar sets in the order the daemon wires them
// (voicewire.go): the clock rules first, the agenda rules after, so a test
// that passes here is a test of the deployed precedence.
func agendaRouter(t *testing.T) *Router {
t.Helper()
r := newTestRouter(t, 0.0)
r.grammars = append(r.grammars, SystemTimeDateGrammars()...)
r.grammars = append(r.grammars, AgendaQueryGrammars()...)
return r
}
// An agenda question is answered from the calendar, which lives in the query
// chain. Routed to system it reaches replySystem, which has no agenda arm and
// says "пока не умею" — seen on the deployed daemon, 01-08-2026.
func TestAgendaQuestionsRouteToQuery(t *testing.T) {
r := agendaRouter(t)
for _, u := range []string{
"что у меня сегодня",
"что у меня в календаре сегодня",
"что у меня стоит в календаре на послезавтра",
"какие у меня встречи завтра",
"покажи расписание на среду",
} {
d, err := r.Route(context.Background(), u, refNow())
if err != nil {
t.Fatalf("route(%q): %v", u, err)
}
if d.Intent != IntentQuery {
t.Errorf("route(%q) = %s, want query", u, d.Intent)
}
}
}
// The clock rules keep their utterances. They are registered first and the
// agenda patterns do not match them, so both statements have to hold.
func TestAgendaGrammarsLeaveTheClockAlone(t *testing.T) {
r := agendaRouter(t)
for _, u := range []string{
"какой сегодня день",
"какое сегодня число",
"который час",
"сколько сейчас времени",
} {
d, err := r.Route(context.Background(), u, refNow())
if err != nil {
t.Fatalf("route(%q): %v", u, err)
}
if d.Intent != IntentSystem {
t.Errorf("route(%q) = %s, want system", u, d.Intent)
}
}
}
// The agenda pattern is anchored and needs the possessive, so an ordinary
// statement that happens to contain "у меня" is not swallowed.
func TestAgendaGrammarSparesStatements(t *testing.T) {
r := agendaRouter(t)
for _, u := range []string{
"у меня кончилась вода",
"напомни мне завтра позвонить маме",
} {
d, err := r.Route(context.Background(), u, refNow())
if err != nil {
t.Fatalf("route(%q): %v", u, err)
}
if d.Stage == 0 && d.Intent == IntentQuery {
t.Errorf("route(%q) was claimed by the agenda grammar", u)
}
}
}
// The tomorrow form and the bare event noun. Both were measured answering
// "пока не умею" on the deployed daemon, 02-08-2026, while the same question
// about today worked — the first rule set needed "у меня" or a calendar noun
// and these phrasings carry neither (Vikunja #471).
func TestAgendaCoversOtherDaysAndNamedEvents(t *testing.T) {
r := agendaRouter(t)
for _, u := range []string{
"какие планы на завтра?",
"какие планы на послезавтра",
"что по делам в среду",
"какие планы на выходные",
"когда планёрка?",
"во сколько созвон",
"когда будет совещание",
} {
d, err := r.Route(context.Background(), u, refNow())
if err != nil {
t.Fatalf("route(%q): %v", u, err)
}
if d.Intent != IntentQuery {
t.Errorf("route(%q) = %s, want query", u, d.Intent)
}
}
}
// The two new rules are narrow on purpose. A world question that opens with
// "когда" is not an agenda question, and telling her about a plan is not
// asking about one.
func TestAgendaGrammarsLeaveTheWorldAlone(t *testing.T) {
r := agendaRouter(t)
for _, u := range []string{
"когда была битва при ватерлоо",
"когда изобрели телефон",
} {
d, err := r.Route(context.Background(), u, refNow())
if err != nil {
t.Fatalf("route(%q): %v", u, err)
}
if d.Stage == 0 {
t.Errorf("route(%q) was claimed at stage 0 as %s", u, d.Intent)
}
}
}