date in code.
The function you build here, extract_date(document, role), takes a document and a
phrase naming the date you want, such as “the deadline to return the form”, and hands
back a date with a confidence. It flags a low-confidence read, a read whose parts do not
make a date, and a date the document never states. The date can be spelled out (“August
14, 2027”) or written relative to today (“tomorrow”, “next Thursday”).
TypeSafe answers Choice questions about the date in one call: what kind of date it is,
and
which month, day, year, or weekday the text names. Code turns those answers into a date.
The model reads what the text says and never does the calendar math.

Setup
TYPESAFE_API_KEY. To replay the published numbers without an API key, download
json_cache.json from typesafe-public-examples into the folder you run
the script from.
The questions
SevenChoice questions go out in one call. mode says how the date is written:
absolute
for a date that names a month, relative for one written relative to today, and none
when the document does not state the date at all.
The other six read the pieces. An absolute date needs month, day, and year. A
relative one needs day_anchor: today, tomorrow, the day after, or a named weekday. When
it names a weekday, weekday and week_offset say which one and which week. Code reads
only the pieces mode calls for.
year lists one option per year from 1900 to 2050, plus two escapes. none means the text
states no year and code fills one in. out_of_range means the text states a year outside
the list, and code flags that instead of guessing. If a list that long bothers you, pull
the year-like numbers out of the text first and offer the model only those.
Resolve it in code
One call reads all seven parts. The answers then become adate, with the year filled in
when the text states none and a named weekday resolved to the day it points at. Both of
those count from TODAY, which is pinned so relative dates come out the same on every run.
A date’s confidence is the lowest among the parts it used, so a weak answer on any one part
can send the whole date to review.
“next Thursday” can mean two different days, so code decides which. A weekday with no
qualifier means the next one on or after today. next means the following calendar week,
and current means this week.
Run it
Six dates to find in four short documents: two from a contract that states its years, a form deadline written without a year, a survey that closes “today”, a review set for “next Thursday”, and a date the form never mentions. All of them resolve againstTODAY =
2026-07-30, a Thursday.
absolute date incomplete means mode came back absolute with no
month to go with it. The date came back empty, the confidence reads 0.46, and the row is
flagged for a person.
Confidence to route on
A date underREVIEW_BELOW = 0.60 goes to a person, and so does any date that could not be
assembled. The rest go straight through.

