fix(radio): resolve common country exonyms Intl.DisplayNames omits (#232)

Recognize common country names and exonyms in Radio country requests and station filtering. Keep ambiguous country names rejected.
This commit is contained in:
Malek authored and GitHub committed 2026-09-10 21:01:39 -07:00
1 parent 024738a8d2
commit 87a92c8bc4
4 files changed
+57 -3

No files matched your search

+5
View File
@@ -15,6 +15,11 @@ of current runtime behavior, see [`docs/CURRENT-STATE.md`](docs/CURRENT-STATE.md
### Fixed
- Radio country filtering and voice country requests now resolve common English
names and exonyms that `Intl.DisplayNames`' primary label omits, so requests
like "play radio in Turkey" no longer fail closed (Turkey → Türkiye, plus
Myanmar/Burma, UAE, Holland, Swaziland, East Timor, Cabo Verde, Vatican).
Ambiguous names such as a bare "Congo" or "Korea" still fail closed.
- Mapped-site outages show their scheduled retry countdown and distinguish
known Overpass rate limits, timeouts, and query failures. Search feedback no
longer claims a refresh succeeded while the layer is unavailable or loading.
+5 -3
View File
@@ -1692,9 +1692,11 @@ preserves object identity for an idempotent repeat of the same generation, and
degrades without replacement if a fresh response presents an older generation.
Snapshot records mark community metadata as untrusted, and Radio tool results
omit station names so directory text never becomes model instruction context.
One bounded country parser maps recognized ISO codes and English/common names
through proxy metadata and final station selection, while malformed, non-ISO,
control-containing, and oversized inputs fail closed. Literal or resolved
One bounded country parser maps recognized ISO codes and English/common names —
including widely used exonyms the Intl display label omits (Turkey, Holland,
Burma, and similar) — through proxy metadata and final station selection, while
malformed, non-ISO, control-containing, ambiguous, and oversized inputs fail
closed. Literal or resolved
non-global IPv4/IPv6 targets are refused. Destroy fully releases the Radio audio
session, voice ducking/restoration, request state, filter, selection, volume,
accepted snapshot, and feed telemetry before re-initialization; monotonic
+16
View File
@@ -55,6 +55,22 @@ for (const [name, code] of Object.entries({
brunei: 'BN',
'cape verde': 'CV',
'the netherlands': 'NL',
// Common English names and exonyms whose code is not reachable through the
// Intl.DisplayNames primary label, so they would otherwise fail closed
// (verified against ICU 77): TR resolves only as 'Türkiye', MM only as
// 'Myanmar (Burma)', AE only as 'United Arab Emirates', SZ as 'Eswatini',
// TL as 'Timor-Leste'. Each maps to exactly one country; ambiguous names
// (e.g. bare "Congo") are deliberately left to fail closed.
turkey: 'TR',
turkiye: 'TR',
myanmar: 'MM',
burma: 'MM',
uae: 'AE',
holland: 'NL',
swaziland: 'SZ',
'east timor': 'TL',
'cabo verde': 'CV',
vatican: 'VA',
})) COUNTRY_NAME_TO_CODE.set(countryKey(name), code);
function canonicalCountryName(code) {
+31
View File
@@ -18,6 +18,37 @@ test('Radio country normalization maps ISO codes and bounded common names', () =
}
});
test('Radio country normalization resolves common English names/exonyms ICU misses', () => {
// Each of these fails closed against the Intl.DisplayNames primary label
// alone (e.g. TR is "Türkiye", MM is "Myanmar (Burma)", AE is "United Arab
// Emirates"), so a request like "play radio in Turkey" would return nothing.
for (const [input, code] of [
['Turkey', 'TR'],
['Turkiye', 'TR'],
['Myanmar', 'MM'],
['Burma', 'MM'],
['UAE', 'AE'],
['U.A.E.', 'AE'],
['Holland', 'NL'],
['Swaziland', 'SZ'],
['East Timor', 'TL'],
['Cabo Verde', 'CV'],
['Vatican', 'VA'],
]) {
const result = normalizeRadioCountryInput(input);
assert.equal(result.valid, true, input);
assert.equal(result.code, code, input);
}
});
test('Ambiguous country names still fail closed (no broadened selection)', () => {
// Two states share the name "Congo" (CD/CG), so a bare mention must not
// resolve to either — it stays low-confidence and fails closed.
for (const input of ['Congo', 'Korea']) {
assert.equal(normalizeRadioCountryInput(input).valid, false, input);
}
});
test('Radio country normalization rejects malformed, non-ISO, and oversized values', () => {
for (const input of [
'ZZ',