discord: resolve the city people actually typed #62

Merged
emi merged 1 commit from fix/discord-city-resolution into dev 2026-08-02 01:18:50 +00:00
Owner

Reported live from #general:

@Thermograph Vilnius, Lithuania
I don't track a city called 'Vilnius, Lithuania' yet. Try a major city name.

Vilnius has been in cities.json the whole time, with country: "Lithuania" sitting right there in the record. _resolve_city matched the query against name alone, exact-or-prefix — so the comma form could never match anything, and the country field was never consulted at all.

The same exchange showed the two neighbouring failures:

  • Vilinus — one transposition — fell through to the same refusal, which reads as we've never heard of Vilnius rather than you typed it wrong.
  • Tell me about weather in lithuania was quoted back verbatim as a city we don't track, which is what made it look broken rather than merely unmatched.

What it does now

In descending order of confidence: exact name honouring a City, Country/Region qualifier → the same ignoring an unrecognised qualifier (better to grade Paris and name it in the reply than refuse over "Paris, Wherever") → prefix → close-enough name for typos → a city or country named somewhere inside a sentence, so "weather in lithuania" lands on Vilnius. Accents fold both ways, since people type Zurich and Sao Paulo far more often than Zürich and São Paulo.

Free-text matching is whole-word and ignores names under four characters, so ordinary chatter doesn't become a weather report — how are you today still resolves to nothing. The unmatched reply also stops reading a whole sentence back as a place name.

This fixes /grade identically — it shares the resolver and had the same bug.

Verified

Against the exact strings from the report:

typed before after
Tell me about weather in lithuania refused Vilnius, Lithuania
Vilinus, Lithuania refused Vilnius, Lithuania
Vilnius, Lithuania refused Vilnius, Lithuania
san fran San Francisco San Francisco
Zurich / Sao Paulo refused Zürich / São Paulo
how are you today refused refused

Full backend suite: 416 passed, 8 skipped. Seven new regression tests, each named after a real failure.

Not covered

A typo inside a sentence (whats it like in Toyko) still misses — fuzzy matching applies to the query as a whole, not per word, and loosening that invites false positives. The conversational agent handles that case; this is the always-on deterministic path.

https://claude.ai/code/session_015Z1ebLbhUxeZ9ozpNrVTCP

Reported live from #general: > **@Thermograph** Vilnius, Lithuania > *I don't track a city called 'Vilnius, Lithuania' yet. Try a major city name.* Vilnius has been in `cities.json` the whole time, with `country: "Lithuania"` sitting right there in the record. `_resolve_city` matched the query against `name` alone, exact-or-prefix — so the comma form could never match anything, and the country field was never consulted at all. The same exchange showed the two neighbouring failures: - **`Vilinus`** — one transposition — fell through to the same refusal, which reads as *we've never heard of Vilnius* rather than *you typed it wrong*. - **`Tell me about weather in lithuania`** was quoted back verbatim as a city we don't track, which is what made it look broken rather than merely unmatched. ## What it does now In descending order of confidence: exact name honouring a `City, Country/Region` qualifier → the same ignoring an unrecognised qualifier (better to grade Paris and name it in the reply than refuse over "Paris, Wherever") → prefix → close-enough name for typos → a city or country named somewhere inside a sentence, so "weather in lithuania" lands on Vilnius. Accents fold both ways, since people type Zurich and Sao Paulo far more often than Zürich and São Paulo. Free-text matching is whole-word and ignores names under four characters, so ordinary chatter doesn't become a weather report — `how are you today` still resolves to nothing. The unmatched reply also stops reading a whole sentence back as a place name. **This fixes `/grade` identically** — it shares the resolver and had the same bug. ## Verified Against the exact strings from the report: | typed | before | after | |---|---|---| | `Tell me about weather in lithuania` | refused | Vilnius, Lithuania | | `Vilinus, Lithuania` | refused | Vilnius, Lithuania | | `Vilnius, Lithuania` | refused | Vilnius, Lithuania | | `san fran` | San Francisco | San Francisco | | `Zurich` / `Sao Paulo` | refused | Zürich / São Paulo | | `how are you today` | refused | refused | Full backend suite: 416 passed, 8 skipped. Seven new regression tests, each named after a real failure. ## Not covered A typo *inside* a sentence (`whats it like in Toyko`) still misses — fuzzy matching applies to the query as a whole, not per word, and loosening that invites false positives. The conversational agent handles that case; this is the always-on deterministic path. https://claude.ai/code/session_015Z1ebLbhUxeZ9ozpNrVTCP
admin_emi added 1 commit 2026-07-24 21:48:35 +00:00
discord: resolve the city people actually typed
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / build-frontend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 7s
PR build (required check) / validate-observability (pull_request) Successful in 38s
PR build (required check) / build-backend (pull_request) Successful in 1m19s
PR build (required check) / gate (pull_request) Successful in 2s
1b862aa049
Reported from #general: "@Thermograph Vilnius, Lithuania" came back "I don't
track a city called 'Vilnius, Lithuania' yet." Vilnius has been in cities.json
the whole time, with country "Lithuania" sitting right there in the record. The
resolver matched the query against `name` alone, exact-or-prefix, so the comma
form could never match anything and the country field was never consulted.

The same message also showed the two neighbouring failures: "Vilinus" (one
transposition) fell through to the same refusal, which reads as "we've never
heard of Vilnius" rather than "you typed it wrong"; and "Tell me about weather
in lithuania" was quoted back verbatim as a city we don't track, which is what
made it look broken rather than merely unmatched.

So the resolver now goes, in descending order of confidence: exact name
honouring a "City, Country/Region" qualifier; the same ignoring an unrecognised
qualifier (better to grade Paris and name it in the reply than refuse over
"Paris, Wherever"); prefix; close-enough name for typos; and finally a city or
country named somewhere inside a sentence, so "weather in lithuania" lands on
Vilnius. Accents fold both ways, since people type Zurich and Sao Paulo far more
often than Zürich and São Paulo.

Free-text matching is whole-word and ignores names under four characters, so
ordinary chatter doesn't turn into a weather report -- "how are you today"
still resolves to nothing. And the unmatched reply no longer reads a whole
sentence back as a place name.

This fixes /grade identically; it shared the resolver and the same bug.

Claude-Session: https://claude.ai/code/session_015Z1ebLbhUxeZ9ozpNrVTCP
emi force-pushed fix/discord-city-resolution from 1b862aa049 to 119c54604c 2026-08-02 01:16:56 +00:00 Compare
emi merged commit fbee83cb24 into dev 2026-08-02 01:18:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Jinemi/thermograph#62
No description provided.