Merge the k-preposition hour, and refuse an unresolved minute (#254)

V-610: teaching #252 that 'к' names an hour made HasTime true without
making the value resolvable, so 'напомни завтра к трём часам дня'
committed at the current clock. dateparser joins a day word to a clock
through 'в' and no other Russian preposition, so it read the day and
dropped the hour. The rewrite now normalises к, ко, на, во to в, which
also fixes 'напомни завтра на 9', silently broken the same way.

The durable half is ResolvedTheHour: both gates that read NamesAnHour
now refuse a parse whose minute nobody spoke, rather than defaulting to
the current clock. Same class as V-577. Fixture unmoved at 64/91.

(V-610)
This commit is contained in:
2026-08-06 04:12:29 +04:00
6 changed files with 250 additions and 11 deletions
+4 -3
View File
@@ -19,9 +19,10 @@ func (h *reactiveHandler) actionReminder(ctx context.Context, dec router.Decisio
// time wasn't parsed. Run the parser as a fallback.
if dec.Stage == 0 && h.timeParser != nil {
t, ok, err := h.timeParser.Parse(ctx, dec.Utterance, h.now())
// Same gate as the extractor (V-577, V-579): a request that named
// no hour gets asked about, never completed from the clock.
if err == nil && ok && router.NamesAnHour(dec.Utterance) {
// Same gate as the extractor (V-577, V-579, V-610): a request whose
// hour was not spoken, or was spoken and not read, gets asked about
// and is never completed from the clock.
if err == nil && ok && router.ResolvedTheHour(dec.Utterance, t) {
dec.Slots.Time = t
dec.Slots.HasTime = true
}