File size: 3,791 Bytes
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
aaf834a
 
 
 
11a59ad
 
 
 
aaf834a
 
 
 
11a59ad
 
 
 
 
 
 
 
aaf834a
 
 
11a59ad
aaf834a
 
11a59ad
aaf834a
 
11a59ad
aaf834a
 
 
 
 
11a59ad
aaf834a
 
 
 
 
 
11a59ad
 
 
aaf834a
11a59ad
aaf834a
 
 
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
 * 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" },
  };
}