feat: LLM router with chat intent and Cyrillic wake-word support

- Add LLMRouter: grammar-constrained LFM call for intent classification
  after stage-0, before classifier cascade. Errors fall through gracefully.
- Add IntentChat: conversational intent with no store side-effect, routed
  through LLM -> phraser chat endpoint.
- Extract slots for Chat: no structured slots, full utterance is payload.
- Extend stage-0 grammars to fire through Cyrillic wake-word spellings
  (Мэйвен/Мейвен/Майвен/etc.) produced by Russian STT model.
- StripWakeToken helper strips leading wake in any script so time/date
  grammars still match when wake is present.
- Add classifier examples for chat utterances (EN + RU).
- Wire LLMRouter into Router.Config; optional, nil-safe.
This commit is contained in:
kami
2026-07-10 15:48:48 +04:00
parent 6bab68e96d
commit 28a940ebbe
8 changed files with 280 additions and 4 deletions
+4 -1
View File
@@ -28,7 +28,7 @@ package router
import "time"
// Intent — the five save-where labels from the spec's routing table. The
// Intent — the six save-where labels from the spec's routing table. The
// discriminator is "does the loop evaluate a predicate against it?":
//
// - act: command now, not stored (function call into the allowlist)
@@ -36,6 +36,8 @@ import "time"
// - fact: structured state the loop reasons over → facts (sqlite)
// - note: recall/preference, no predicate touches it → chroma
// - query: answer, don't store → slm reads sqlite or chroma (RAG)
// - chat: conversational, no store side-effect — LLM replies from
// dialogue history + general knowledge
//
// fact-vs-note is the whole line: predicate will read it → structured facts
// row; just "recall when relevant" → semantic store. reminder splits off by
@@ -48,6 +50,7 @@ const (
IntentFact Intent = "fact"
IntentNote Intent = "note"
IntentQuery Intent = "query"
IntentChat Intent = "chat"
IntentSystem Intent = "system"
)