22b43c07a9
- Add reactive_notes_test.go: tests for context-aware reactive nudge generation using LLM phraser with dialogue history. - Add docs/plans/2026-07-10-router-lfm-foundation.md: architecture research on replacing classifier cascade with LFM-based router.
88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/kami/maven/internal/ipc"
|
|
"github.com/kami/maven/internal/memory"
|
|
"github.com/kami/maven/internal/router"
|
|
"github.com/kami/maven/internal/tool"
|
|
"github.com/kami/maven/internal/voice"
|
|
)
|
|
|
|
func TestReactiveNotesReminders(t *testing.T) {
|
|
ctx := context.Background()
|
|
st := newTestStore(t)
|
|
api := ipc.NewStoreAPI(st)
|
|
now := time.Now()
|
|
|
|
emb := router.NewHashEmbedder(1024)
|
|
matcher := tool.NewMatcher(api)
|
|
rtr := buildRouter(emb, matcher, 0.55, nil)
|
|
|
|
h := &reactiveHandler{
|
|
api: api,
|
|
embedder: emb,
|
|
router: rtr,
|
|
replier: voice.NewStubReplier(),
|
|
now: func() time.Time { return now },
|
|
memStore: memory.NewInMemoryStore(),
|
|
dataStore: st,
|
|
}
|
|
|
|
t.Run("reminder capture", func(t *testing.T) {
|
|
fireAt := now.Add(24 * time.Hour).Truncate(time.Millisecond)
|
|
dec := router.Decision{
|
|
Intent: router.IntentReminder,
|
|
Utterance: "напомни завтра позвонить маме",
|
|
Slots: router.Slots{
|
|
Text: "завтра позвонить маме",
|
|
Time: fireAt,
|
|
HasTime: true,
|
|
},
|
|
}
|
|
reply := h.applyAction(ctx, dec)
|
|
if reply != "" {
|
|
t.Errorf("expected empty reply from applyAction, got %q", reply)
|
|
}
|
|
reminders, err := st.ListReminders(ctx, 10)
|
|
if err != nil {
|
|
t.Fatalf("ListReminders: %v", err)
|
|
}
|
|
if len(reminders) == 0 {
|
|
t.Fatal("expected at least one reminder, got none")
|
|
}
|
|
last := reminders[0]
|
|
if last.FireTs.UnixMilli() != fireAt.UnixMilli() {
|
|
t.Errorf("reminder FireTs = %v, want %v", last.FireTs, fireAt)
|
|
}
|
|
if last.Status != "pending" {
|
|
t.Errorf("reminder Status = %q, want pending", last.Status)
|
|
}
|
|
})
|
|
|
|
t.Run("note capture", func(t *testing.T) {
|
|
dec := router.Decision{
|
|
Intent: router.IntentNote,
|
|
Utterance: "запомни что кофе закончился",
|
|
}
|
|
reply := h.applyAction(ctx, dec)
|
|
if reply != "" {
|
|
t.Errorf("expected empty reply from applyAction, got %q", reply)
|
|
}
|
|
notes, err := st.RecentNotes(ctx, 10)
|
|
if err != nil {
|
|
t.Fatalf("RecentNotes: %v", err)
|
|
}
|
|
if len(notes) == 0 {
|
|
t.Fatal("expected at least one note, got none")
|
|
}
|
|
last := notes[0]
|
|
if last.Text != "запомни что кофе закончился" {
|
|
t.Errorf("note text = %q, want %q", last.Text, "запомни что кофе закончился")
|
|
}
|
|
})
|
|
}
|