show-me / src /lib /ai /command-parser.js
PierreRouanet's picture
Auto-detect language for STT, TTS, and command responses
11a59ad
Raw
History Blame Contribute Delete
3.79 kB
/**
* Keyword-based command parser.
*
* Maps spoken text to robot actions via regex matching.
* Supports both French and English keywords, responds in the detected language.
* Returns { response, action? } — designed to be a drop-in replacement
* for an LLM-based parser in V2 (same parse() interface).
*/
const COMMANDS = [
{
pattern: /\b(wake\s*up|r[eé]veille[- ]?toi|debout)\b/i,
response: { fr: "Je me r\u00e9veille !", en: "Waking up!" },
action: { type: "wakeUp" },
},
{
pattern: /\b((go\s*to\s*)?sleep|dors|endors[- ]?toi|au dodo)\b/i,
response: { fr: "Je vais dormir.", en: "Going to sleep." },
action: { type: "gotoSleep" },
},
{
pattern: /\b(look\s+left|regarde\s+[àa]\s+gauche|tourne\s+[àa]\s+gauche|gauche)\b/i,
response: { fr: "Je regarde \u00e0 gauche.", en: "Looking left." },
action: { type: "lookDirection", params: { direction: "left" } },
},
{
pattern: /\b(look\s+right|regarde\s+[àa]\s+droite|tourne\s+[àa]\s+droite|droite)\b/i,
response: { fr: "Je regarde \u00e0 droite.", en: "Looking right." },
action: { type: "lookDirection", params: { direction: "right" } },
},
{
pattern: /\b(look\s+up|regarde\s+en\s+haut|l[eè]ve\s+la\s+t[eê]te|en haut)\b/i,
response: { fr: "Je regarde en haut.", en: "Looking up." },
action: { type: "lookDirection", params: { direction: "up" } },
},
{
pattern: /\b(look\s+down|regarde\s+en\s+bas|baisse\s+la\s+t[eê]te|en bas)\b/i,
response: { fr: "Je regarde en bas.", en: "Looking down." },
action: { type: "lookDirection", params: { direction: "down" } },
},
{
pattern: /\b(look\s+(at\s+me|center|straight|forward)|centre|regarde[- ]?moi|devant\s+toi|en face)\b/i,
response: { fr: "Me voil\u00e0 !", en: "Here I am!" },
action: { type: "lookDirection", params: { direction: "center" } },
},
{
pattern: /\b(turn\s+around|tourne[- ]?toi|fais\s+un\s+tour|retourne[- ]?toi|demi[- ]?tour)\b/i,
response: { fr: "Youhou !", en: "Wheee!" },
action: { type: "turnAround" },
},
{
pattern: /\b(hello|hi|hey|bonjour|salut|coucou)\b/i,
response: { fr: "Bonjour ! Ravi de te parler.", en: "Hello! Nice to talk to you." },
action: { type: "wiggleAntennas" },
},
{
pattern: /\b(help|what can you do|commands|aide|qu'?est[- ]ce que tu (sais|peux) faire|que sais[- ]tu faire)\b/i,
response: {
fr: "Je peux : me r\u00e9veiller, dormir, regarder \u00e0 gauche/droite/haut/bas, te regarder, me retourner, et dire bonjour !",
en: "I can: wake up, go to sleep, look left/right/up/down, look at me, turn around, and say hello!",
},
action: { type: "nod" },
},
];
/**
* Pick the response string for the detected language, falling back to French.
*/
function localize(response, lang) {
if (typeof response === "string") return response;
return response[lang] || response.fr;
}
/**
* Parse spoken text into a response and optional robot action.
* @param {string} text
* @param {string} language Detected language code, e.g. "fr", "en"
* @returns {{ response: string, action?: { type: string, params?: object } }}
*/
export function parse(text, language = "fr") {
const trimmed = text.trim();
if (!trimmed) {
return { response: localize({ fr: "Je n'ai pas compris.", en: "I didn't catch that." }, language) };
}
for (const cmd of COMMANDS) {
if (cmd.pattern.test(trimmed)) {
return {
response: localize(cmd.response, language),
action: cmd.action,
};
}
}
// Fallback — echo what we heard with a quizzical reaction
const fallback = language === "en"
? `I heard: "${trimmed}"`
: `J'ai entendu : \u00ab ${trimmed} \u00bb`;
return {
response: fallback,
action: { type: "headTilt" },
};
}