Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 1x 1x 1x 16x 16x 12x 9x 9x 9x 138x 138x 5x 8x 5x | import { tokenise } from "./text";
export type RrmLocale = "en" | "te" | "te-Latn";
/**
* Telugu Unicode block. Any character here means the person is typing in
* script, which is unambiguous — no scoring needed.
*/
const TELUGU_SCRIPT = /[ఀ-౿]/;
/**
* Romanised-Telugu markers.
*
* Deliberately common, short, high-frequency words rather than a dictionary:
* the goal is to notice "this person is writing Telugu in Latin letters", not
* to translate. Two matches are required because several of these are also
* English or Hindi words in other contexts ("sare", "undi"), and misdetecting
* an English speaker into Telugu replies is worse than missing the switch.
*/
const TE_LATN_MARKERS = [
"kada",
"cheppandi",
"enti",
"ela",
"vaddu",
"kaavali",
"meeru",
"naaku",
"cheyandi",
"undi",
"ledu",
"unnaru",
"pampandi",
"telusu",
"sare",
"chestunnaru",
"ippudu",
"parledu",
"chala",
"emi",
] as const;
/** Minimum marker hits before we call a message romanised Telugu. */
export const TE_LATN_THRESHOLD = 2;
/**
* Detects the locale of an inbound message.
*
* Matters more than it looks: getting a Telugu reply and answering in English
* is worse than never offering Telugu at all, and this is the only signal we
* get — the prospect never picks a language from a menu.
*
* Note that outbound templates being approved in Telugu SCRIPT does not mean
* inbound will be. Many Hyderabad agents read script comfortably but type
* romanised, so `te-Latn` has to be detectable even in a script-first campaign.
*/
export function detectLocale(text: string | null | undefined): RrmLocale {
const raw = (text ?? "").trim();
if (!raw) return "en";
if (TELUGU_SCRIPT.test(raw)) return "te";
const tokens = new Set(tokenise(raw));
let hits = 0;
for (const marker of TE_LATN_MARKERS) {
if (tokens.has(marker)) hits += 1;
if (hits >= TE_LATN_THRESHOLD) return "te-Latn";
}
return "en";
}
/**
* Whether a newly detected locale should overwrite what is stored.
*
* A locale the person stated themselves always wins; a detection only
* overwrites the default. Without this, one English word in an otherwise
* Telugu conversation would flip them back and forth mid-thread.
*/
export function shouldUpdateLocale(
storedSource: "default" | "detected" | "stated" | null | undefined,
incomingSource: "detected" | "stated",
): boolean {
if (incomingSource === "stated") return true;
return storedSource !== "stated";
}
|