package router import "strings" // interrogatives — the question words that mark an utterance as asking rather // than telling. Tokenized, never substring: "что" inside "чтобы" and "как" // inside "какао" are not questions. var interrogatives = []string{ "что", "чего", "какой", "какая", "какое", "какие", "каких", "кто", "кого", "кому", "чей", "почему", "зачем", "отчего", "где", "куда", "откуда", "когда", "сколько", "как", "what", "who", "whom", "why", "when", "where", "which", "how", } // narrativeRequests — "tell me about X" asks for knowledge Maven does not // hold about him. It carries no question mark and no interrogative, which is // how "расскажи про битву при Ватерлоо" reached the fact store (#470). var narrativeRequests = []string{ "расскажи", "объясни", "опиши", "перечисли", "tell", "explain", "describe", } // captureVerbs — an explicit instruction to record something. These win over // every test below, because "запиши что я пил воду" contains an interrogative // and is still a capture: the word he said is "запиши". var captureVerbs = []string{ "запиши", "запомни", "отметь", "заметь", "добавь", "сохрани", "note", "remember", "log", "save", } // IsQuestionShaped reports whether text asks for something rather than // records it. It is a deterministic offline test over tokens, so it costs // nothing and never depends on the model that produced the routing decision. // // It exists because a mis-routed question used to be persisted as a fact // about the owner, with the model's invented answer as the value (#470). The // predicate is deliberately blunt: refusing to store a question is cheap and // reversible, storing an invented fact about him is neither. func IsQuestionShaped(text string) bool { t := strings.TrimSpace(text) if t == "" { return false } toks := planTokens(t) for _, v := range captureVerbs { if hasTok(toks, v) { return false } } if strings.HasSuffix(t, "?") { return true } for _, w := range interrogatives { if hasTok(toks, w) { return true } } for _, w := range narrativeRequests { if hasTok(toks, w) { return true } } return false }