If you're building an AI agent that touches dates — booking flows, scheduling bots, "remind me on Friday" assistants — you've probably noticed:
LLMs are terrible at dates.
They hallucinate weekday-to-date mappings. They fencepost-error ranges. They forget what "next Friday" means in Ukrainian vs English. Asking the model to "be careful" doesn't fix it — what fixes it is moving date interpretation out of the model and into a deterministic tool.
That's what whenis
is.
Define a resolveDate(expression, reference)
tool that calls whenis
. Let the model invoke it instead of guessing.
import { createParser } from '@whenis/core';
import { uk } from '@whenis/locale-uk';
import { booking } from '@whenis/booking';
const parser = createParser({
locales: [uk],
plugins: [booking],
options: { preferFuture: true },
});
const ref = new Date('2026-05-28');
parser.parse("наступної п'ятниці", { reference: ref });
// → { type: 'date', date: '2026-06-05', confidence: 1 }
parser.parse('з 5 по 10 червня', { reference: ref });
// → { type: 'range', start: '2026-06-05', end: '2026-06-11', nights: 6 }
parser.parse('після свят', { reference: ref });
// → { type: 'fuzzy', reason: 'holiday_ref',
// metadata: { suggest_next_month: true } }
English works the same way:
import { en } from '@whenis/locale-en';
const parser = createParser({ locales: [en], options: { preferFuture: true } });
parser.parse('next Friday', { reference: new Date('2026-05-28') });
// → { type: 'date', date: '2026-06-05', confidence: 1 }
@whenis/booking
, not the core. Build your own plugin for your domain.Duckling-style 4-layer pipeline:
input
↓
preprocess → tokenize + tag → rule engine → resolver
↓
ParseResult
Each layer is independently testable. The rule engine is iterative and compositional — rules match tokens or previously emitted IR nodes, looping until fixpoint.
The output is a ParseResult
with matches[].candidates[]
— each candidate has a type
, ISO dates, optional nights
, a confidence
score, a human-readable reason
, and a metadata
bag plugins can extend.
ESM + CJS dual builds, strict TypeScript, Node ≥18, zero DOM dependencies.
npm i @whenis/core @whenis/locale-uk @whenis/booking
npm i @whenis/core @whenis/locale-en
@whenis/core
is a peer dependency of every locale and plugin — install it explicitly so you control the version in one place.
v0.1 ships UA + EN locales and the booking plugin. v0.2 backlog: ISO passthrough rule, DD.MM numeric forms, Ukrainian word-numerals, до кінця тижня/місяця
window, more English coverage. Issues and PRs welcome.
Repo: github.com/norens/whenis · MIT