package router import "strings" // Money questions, matched deterministically (Vikunja #125). // // No new intent, for the same reason as tasks: the intent enum is a contract // with the relabelling prompt. "сколько я потратил?" is a query; which figure // it asks for is a lookup, not something to ask a 1.7B — and a model asked to // invent a spending total will happily do it. // MoneyWindow — which period a money question asks about. type MoneyWindow int const ( MoneyNone MoneyWindow = iota MoneyToday MoneyMonth ) // moneyNouns — the words that make a question be about his money. var moneyNouns = []string{ "потратил", "потратила", "тратил", "траты", "трат", "расходы", "расходов", "заработал", "потрачено", "денег", "spend", "spent", "expenses", } // ParseMoneyQuery reports whether an utterance asks about spending or income, // and over which window. Defaults to the month: "сколько я потратил?" without a // period is the month-to-date question, which is the one worth answering. // // Narrow on purpose. A money noun alone is not enough — "я потратил весь день // на это" is him talking about his day, so an amount word or an explicit // question word has to be there too. func ParseMoneyQuery(text string) (MoneyWindow, bool) { toks := planTokens(text) if len(toks) == 0 { return MoneyNone, false } hasNoun := false for _, t := range toks { for _, n := range moneyNouns { if t == n { hasNoun = true } } } if !hasNoun { return MoneyNone, false } // "весь день", "время", "силы" — spending that is not money. for _, t := range toks { switch t { case "день", "дня", "время", "времени", "силы", "сил", "нервы": return MoneyNone, false } } asking := hasTok(toks, "сколько") || hasTok(toks, "какие") || hasTok(toks, "покажи") || hasTok(toks, "how") || hasTok(toks, "much") || hasTok(toks, "my") || hasTok(toks, "мои") || hasTok(toks, "траты") || hasTok(toks, "расходы") if !asking { return MoneyNone, false } lower := strings.ToLower(text) switch { case hasTok(toks, "сегодня") || strings.Contains(lower, "today"): return MoneyToday, true case hasTok(toks, "месяц") || hasTok(toks, "месяце") || strings.Contains(lower, "month"): return MoneyMonth, true } return MoneyMonth, true }