913 lines
51 KiB
JSON
913 lines
51 KiB
JSON
{
|
||
"_description": "Bilingual voice command instructions — single source of truth for the voice dispatch tables. Loaded by Voice/marcus_voice.py at module level. Adding a new motion command, a new accent variant, a new Arabic phrasing, or fixing a misheard wake-word transcription is a JSON-only edit; no Python change required. Arabic phrase tables cover MSA (Fusha) plus Gulf/Khaleeji, Egyptian (Masri), Levantine (Shami), Iraqi, and Maghrebi dialects.",
|
||
|
||
"_format": "wake_words = whole-word substrings the dispatch gate looks for in the user's transcript. Any match (English or Arabic) opens motion for the current turn. actions = per-motion phrase tables. Each action has a `canonical` string (what marcus_brain receives), `user_phrases` (what the user might SAY when asking for the motion — used for fuzzy-match + Arabic-to-English translation after wake-word strip), and `bot_phrases` (what Gemini might SPEAK when acknowledging — used by the bot-side dispatcher to fire motion off Gemini's own confirmation). All matching is substring-based; English entries are matched case-insensitively, Arabic entries match as-is. Keep the canonical string consistent with Brain/command_parser.py vocabulary.",
|
||
|
||
"wake_words": {
|
||
"_comment": "All variants of the robot's name 'Sanad' — the gate that authorises motion. Add new mishearings here when you see them in logs/transcript.log under HEARD lines that should have triggered motion but didn't.",
|
||
"english": [
|
||
"sanad", "sannad", "sennad", "sunnad", "sinnad", "sonnad",
|
||
"sanat", "sunnat", "sonnat", "sinnat", "sennat",
|
||
"sanid", "sanud", "saned", "sanod", "sanaad",
|
||
"senad", "sinad", "sonad", "sunad",
|
||
"sanah", "sanath", "sanadh", "sonadh",
|
||
"samad", "somad", "sumad",
|
||
"thanad", "zanad",
|
||
"sa nad", "san ad", "san odd", "san add"
|
||
],
|
||
"arabic": [
|
||
"سند", "سنّاد", "ساند", "سنود", "سنَد", "سنّد", "سَند", "سنّود", "ساندي", "سنادي",
|
||
"يا سند", "يا سنّاد", "يا ساند", "يا سَند", "يا سنود", "ياسند", "ياسنود",
|
||
"السند", "السنّاد"
|
||
]
|
||
},
|
||
|
||
"actions": {
|
||
"turn_right": {
|
||
"canonical": "turn right",
|
||
"user_phrases": {
|
||
"english": ["turn right", "rotate right", "spin right", "go right", "face right", "right"],
|
||
"arabic": [
|
||
"استدر يميناً", "استدر يمينا", "ادر يميناً", "ادر يمينا", "لف يمين", "لف يميناً", "يمين",
|
||
"دور يمين", "دور لليمين", "دور على اليمين", "دور ع اليمين",
|
||
"خش يمين", "خش ع اليمين", "حوّد يمين", "حود يمين", "حوّد لليمين",
|
||
"دير يمين", "دير لليمين", "دير على ليمن", "دير ع اليمين",
|
||
"لف لليمين", "لف على اليمين", "لف عاليمين", "لف ع اليمين",
|
||
"روح يمين", "اتجه يمين", "اتجه لليمين", "تجه يمين"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["turning right"],
|
||
"arabic": [
|
||
"أستدير يميناً", "أستدير يمينا", "استدير يميناً", "استدير يمينا", "ألف يميناً", "ألف يمينا",
|
||
"بلف يمين", "بدور يمين", "أدور يمين", "أحوّد يمين", "أخش يمين"
|
||
]
|
||
}
|
||
},
|
||
|
||
"turn_left": {
|
||
"canonical": "turn left",
|
||
"user_phrases": {
|
||
"english": ["turn left", "rotate left", "spin left", "go left", "face left", "left"],
|
||
"arabic": [
|
||
"استدر يساراً", "استدر يسارا", "ادر يساراً", "ادر يسارا", "لف يسار", "لف يساراً", "يسار", "شمال",
|
||
"دور يسار", "دور شمال", "دور لليسار", "دور على اليسار", "دور ع الشمال",
|
||
"خش يسار", "خش شمال", "خش ع الشمال", "حوّد شمال", "حود شمال", "حوّد يسار", "حوّد لليسار",
|
||
"دير يسار", "دير شمال", "دير لليسار", "دير على ليسار", "دير ع الشمال",
|
||
"لف لليسار", "لف على اليسار", "لف عاشمال", "لف ع الشمال",
|
||
"روح يسار", "روح شمال", "اتجه يسار", "اتجه شمال", "اتجه لليسار", "تجه شمال"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["turning left"],
|
||
"arabic": [
|
||
"أستدير يساراً", "أستدير يسارا", "استدير يساراً", "استدير يسارا", "ألف يساراً", "ألف يسارا",
|
||
"بلف شمال", "بدور شمال", "أدور شمال", "أحوّد شمال", "أخش شمال"
|
||
]
|
||
}
|
||
},
|
||
|
||
"turn_around": {
|
||
"canonical": "turn around",
|
||
"user_phrases": {
|
||
"english": ["turn around", "turn back", "spin around", "about face", "face the other way", "spin in place", "spin yourself", "turn yourself around"],
|
||
"arabic": [
|
||
"استدر للخلف", "استدر إلى الوراء", "اتجه للخلف", "ادر للخلف", "ارجع وجهك",
|
||
"لف ورا", "لف للورا", "لف للخلف", "دور ورا", "دور للورا", "دور للخلف",
|
||
"اتلف", "اتلف ورا", "دير وراك", "دير للورا", "استدر ورا",
|
||
"اقلب وجهك", "اقلب", "اعكس اتجاهك", "غيّر اتجاهك",
|
||
"لف حول نفسك", "لف حوالين نفسك", "لف على نفسك",
|
||
"دور حول نفسك", "دور حوالين نفسك", "دور على نفسك",
|
||
"استدر حول نفسك", "استدر حوالين نفسك",
|
||
"حول نفسك", "حوالين نفسك",
|
||
"لف بنفسك", "دور بنفسك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["turning around"],
|
||
"arabic": [
|
||
"أستدير للخلف", "أستدير إلى الوراء", "استدير للخلف",
|
||
"بلف ورا", "بدور للورا", "أدور للخلف",
|
||
"أستدير حول نفسي", "ألف حول نفسي", "أدور حول نفسي",
|
||
"بلف حول نفسي", "بدور حول نفسي"
|
||
]
|
||
}
|
||
},
|
||
|
||
"move_forward": {
|
||
"canonical": "move forward",
|
||
"user_phrases": {
|
||
"english": ["move forward", "go forward", "walk forward", "step forward", "forward", "keep going", "walk ahead", "move ahead"],
|
||
"arabic": [
|
||
"تحرك للأمام", "تحرك إلى الأمام", "اذهب للأمام", "امش للأمام", "تقدم", "للأمام", "أمام",
|
||
"روح قدام", "روح لقدام", "روح كدام",
|
||
"امشي قدام", "امشي لقدام", "امش قدام",
|
||
"اتقدم", "تقدم لقدام", "يلا قدام", "يالله قدام",
|
||
"فوت", "فوت لقدام", "فوت قدام",
|
||
"سير لقدام", "سير قدام", "اسير قدام",
|
||
"خش قدام", "تعال قدام", "للقدام", "قدام"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"_": "Direction-anchored only. We do NOT add destination-phrased needles like 'walking towards X' / 'أمشي نحو X' even though Gemini occasionally says them — those false-fire when Gemini DESCRIBES a third party ('I see a person walking towards us'). Persona RULE 4b forbids destination phrasing in motion confirmations; trust the prompt. If a real motion phrase ever slips through and we miss it, add the EXACT slip to this list — not generic destination patterns.",
|
||
"english": [
|
||
"moving forward", "walking forward", "stepping forward",
|
||
"going forward", "going ahead", "heading forward", "walking ahead"
|
||
],
|
||
"arabic": [
|
||
"أتحرك للأمام", "أتحرك إلى الأمام", "أتقدم", "أمشي للأمام", "أذهب للأمام",
|
||
"بمشي قدام", "براح قدام", "أروح قدام", "بتقدم", "بفوت لقدام"
|
||
]
|
||
}
|
||
},
|
||
|
||
"move_backward": {
|
||
"canonical": "move backward",
|
||
"user_phrases": {
|
||
"english": ["move back", "move backward", "go back", "go backward", "walk back", "walk backward", "step back", "backward", "back", "reverse"],
|
||
"arabic": [
|
||
"تحرك للخلف", "تحرك إلى الخلف", "اذهب للخلف", "امش للخلف", "ارجع", "ارجع للخلف", "للخلف", "خلف",
|
||
"روح ورا", "روح للورا", "ارجع ورا", "ارجع للورا",
|
||
"امشي ورا", "امشي للورا", "امش ورا",
|
||
"تأخر", "تراجع", "ورا", "للورا",
|
||
"رجع للخلف", "ارجع لورا", "رجع لورا",
|
||
"سير للورا", "سير ورا"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["moving backward", "moving back", "walking backward", "walking back", "stepping back", "going back"],
|
||
"arabic": [
|
||
"أتحرك للخلف", "أتحرك إلى الخلف", "أرجع", "أمشي للخلف", "أعود للخلف",
|
||
"بمشي ورا", "براح ورا", "أرجع ورا", "بتراجع"
|
||
]
|
||
}
|
||
},
|
||
|
||
"move_right": {
|
||
"canonical": "move right",
|
||
"user_phrases": {
|
||
"english": ["step right", "move right", "slide right", "strafe right", "sidestep right"],
|
||
"arabic": [
|
||
"تحرك يميناً", "تحرك يمينا", "خطوة يمين", "اتجه يميناً",
|
||
"زحلق يمين", "زحلق لليمين", "اتزحلق يمين",
|
||
"خطوة لليمين", "خطوة ع اليمين", "خطوة على اليمين",
|
||
"حرك يمين", "حرّك يمين", "اخطو يمين", "اخطو لليمين",
|
||
"زح يمين", "زح لليمين"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["moving right", "stepping right", "sliding right"],
|
||
"arabic": [
|
||
"أتحرك يميناً", "أتحرك يمينا", "أخطو يميناً",
|
||
"بزحلق يمين", "أزحلق يمين", "بخطو يمين"
|
||
]
|
||
}
|
||
},
|
||
|
||
"move_left": {
|
||
"canonical": "move left",
|
||
"user_phrases": {
|
||
"english": ["step left", "move left", "slide left", "strafe left", "sidestep left"],
|
||
"arabic": [
|
||
"تحرك يساراً", "تحرك يسارا", "خطوة يسار", "اتجه يساراً",
|
||
"زحلق يسار", "زحلق شمال", "زحلق لليسار", "اتزحلق شمال",
|
||
"خطوة شمال", "خطوة لليسار", "خطوة ع الشمال", "خطوة على اليسار",
|
||
"حرك يسار", "حرك شمال", "حرّك شمال", "اخطو يسار", "اخطو شمال", "اخطو لليسار",
|
||
"زح يسار", "زح شمال"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["moving left", "stepping left", "sliding left"],
|
||
"arabic": [
|
||
"أتحرك يساراً", "أتحرك يسارا", "أخطو يساراً",
|
||
"بزحلق شمال", "أزحلق شمال", "بخطو شمال"
|
||
]
|
||
}
|
||
},
|
||
|
||
"stop": {
|
||
"canonical": "stop",
|
||
"user_phrases": {
|
||
"english": ["stop", "halt", "wait", "pause", "freeze", "hold", "stop moving", "stand still", "don't move"],
|
||
"arabic": [
|
||
"توقف", "قف مكانك", "اوقف", "انتظر", "اثبت", "لا تتحرك",
|
||
"وقّف", "وقف", "وگف", "بطّل", "بطل حركة", "بطل",
|
||
"خلاص", "كفاية", "يكفي",
|
||
"استنى", "استنى شوية", "اصبر", "صبر", "اصبر شوية",
|
||
"تو", "ثبات", "اثبت مكانك", "ما تتحرك", "ما تمشي",
|
||
"هدّي", "هدّى", "روّق"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"_": "Removed 'أنتظر' from this list — it's also a pause_motion bot_phrase ('I wait' is more naturally a pause than a stop). Keeping it here would cause Gemini saying 'أنتظر' to fire BOTH stop and pause_motion in the same chunk.",
|
||
"english": ["stopping", "halting", "holding"],
|
||
"arabic": [
|
||
"أتوقف", "توقفت",
|
||
"بوقّف", "وقّفت", "بستنى", "أصبر", "بطّلت"
|
||
]
|
||
}
|
||
},
|
||
|
||
"sit_down": {
|
||
"canonical": "sit down",
|
||
"user_phrases": {
|
||
"english": ["sit down", "sit", "take a seat", "have a seat"],
|
||
"arabic": [
|
||
"اجلس", "ارتح", "اقعد",
|
||
"اقعد على الأرض", "اقعد ع الأرض", "اجلس على الأرض",
|
||
"اگعد", "گلس", "تفضل اقعد", "ارتاح",
|
||
"خد راحتك واقعد", "اقعد يا سند"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["sitting down", "sitting"],
|
||
"arabic": [
|
||
"أجلس", "أقعد", "جلست",
|
||
"بقعد", "قعدت", "بجلس", "أرتاح"
|
||
]
|
||
}
|
||
},
|
||
|
||
"stand_up": {
|
||
"canonical": "stand up",
|
||
"user_phrases": {
|
||
"english": ["stand up", "stand", "get up", "rise"],
|
||
"arabic": [
|
||
"قف", "انهض", "ارفع نفسك",
|
||
"قوم", "گوم", "نوض", "نض",
|
||
"قوم على رجلك", "قوم على رجليك", "انهض من مكانك",
|
||
"اوقف على رجلك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["standing up", "getting up", "rising"],
|
||
"arabic": [
|
||
"أقف", "أنهض", "وقفت",
|
||
"بقوم", "قمت", "نضت", "بنهض"
|
||
]
|
||
}
|
||
},
|
||
|
||
"wave_hello": {
|
||
"canonical": "wave hello",
|
||
"user_phrases": {
|
||
"english": ["wave hello", "wave", "say hi", "greet", "wave to me", "wave at me"],
|
||
"arabic": [
|
||
"لوّح", "لوح", "لوّح بيدك", "حيّ", "سلّم",
|
||
"لوّح لي", "لوّحلي", "لوّح بيدك لي",
|
||
"سلّم بيدك", "سلّم علي", "حيّيني", "حيي",
|
||
"هز يدك", "هز إيدك", "هزّ ايدك",
|
||
"قول هاي", "قول مرحبا", "قول السلام",
|
||
"حييني", "سلم علي"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["waving hello", "waving", "saying hi", "greeting"],
|
||
"arabic": [
|
||
"ألوّح", "ألوح", "ألوّح بيدي", "أحيّ", "أسلّم",
|
||
"بلوّح", "بسلّم", "بهز إيدي", "أهز يدي"
|
||
]
|
||
}
|
||
},
|
||
|
||
"raise_arm": {
|
||
"canonical": "raise arm",
|
||
"user_phrases": {
|
||
"english": ["raise arm", "raise your arm", "lift your arm", "arm up", "hand up"],
|
||
"arabic": [
|
||
"ارفع يدك", "ارفع ذراعك", "اليد للأعلى",
|
||
"ارفع إيدك", "ارفع ايدك", "ارفع يديك",
|
||
"طلّع يدك", "طلع يدك", "طلّع إيدك", "طلع إيدك",
|
||
"علّي يدك", "علّي إيدك", "علي يدك",
|
||
"يدك فوق", "إيدك فوق", "اليد فوق", "حط يدك فوق",
|
||
"ارفع اليد", "ارفع ايديك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["raising arm", "raising my arm", "lifting my arm", "arm up"],
|
||
"arabic": [
|
||
"أرفع يدي", "أرفع ذراعي",
|
||
"برفع إيدي", "بطلّع إيدي", "بعلّي إيدي", "رفعت يدي"
|
||
]
|
||
}
|
||
},
|
||
|
||
"lower_arm": {
|
||
"canonical": "lower arm",
|
||
"user_phrases": {
|
||
"english": ["lower arm", "lower your arm", "drop your arm", "arm down", "hand down", "rest your arm"],
|
||
"arabic": [
|
||
"اخفض يدك", "اخفض ذراعك", "اليد للأسفل", "نزل يدك",
|
||
"نزّل يدك", "نزّل إيدك", "نزل إيدك", "نزّل ايدك",
|
||
"حط يدك", "حط إيدك", "حط ايدك", "خلي يدك تحت",
|
||
"طيح يدك", "طيّح يدك", "طيح إيدك",
|
||
"يدك تحت", "إيدك تحت", "اليد تحت",
|
||
"ارح يدك", "ريّح يدك", "ريّح إيدك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["lowering arm", "lowering my arm", "dropping my arm", "arm down"],
|
||
"arabic": [
|
||
"أخفض يدي", "أخفض ذراعي", "أنزل يدي",
|
||
"بنزّل إيدي", "نزّلت إيدي", "بريّح إيدي"
|
||
]
|
||
}
|
||
},
|
||
|
||
"point": {
|
||
"canonical": "point",
|
||
"user_phrases": {
|
||
"english": ["point", "point at it", "point to it", "point there"],
|
||
"arabic": [
|
||
"اشر", "أشِر", "اشر إلى", "اشر هناك",
|
||
"أشّر", "اشّر", "أشر بأصبعك", "أشر بصبعك", "اشر بصبعك",
|
||
"شاور", "شاورلي", "أشاور", "شاور هناك",
|
||
"ورّيني", "وريني", "ورجيني",
|
||
"بصبعك", "حدد", "حدد بصبعك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["pointing"],
|
||
"arabic": [
|
||
"أشير",
|
||
"بشاور", "بأشر", "بشير", "أشّرت"
|
||
]
|
||
}
|
||
},
|
||
|
||
"come_here": {
|
||
"canonical": "come here",
|
||
"user_phrases": {
|
||
"english": ["come here", "come to me", "come closer", "approach", "get closer", "come over here", "come"],
|
||
"arabic": [
|
||
"تعال", "تعال هنا", "تعال إليّ", "اقترب", "تقرب",
|
||
"تعالى", "تعالى هنا", "تعالى لي", "تعالى عندي",
|
||
"تعا", "تعا لهون", "تعا عندي",
|
||
"أجي", "أرواح", "ارواحلي",
|
||
"قرّب", "قرب", "قرّب لي", "قرّب مني", "قرب مني",
|
||
"گرّب", "گرب لي",
|
||
"يلا تعال", "يا الله تعال", "تعال جنبي", "خش جنبي",
|
||
"تعال يا سند", "تعال بسرعة", "هلم"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"_": "Expanded Arabic forms because Gemini sometimes emits non-canonical conjugations (e.g. 'أتعال' is grammatically wrong but phonetically what it produces for 'I come'). Persona Rule 5d gives Gemini correct example phrases; these extra needles catch slip cases like 'أتعال'/'بجي لك'.",
|
||
"english": [
|
||
"coming over", "coming to you", "approaching",
|
||
"coming to find you", "coming your way",
|
||
"i'm coming", "on my way to you", "heading to you"
|
||
],
|
||
"arabic": [
|
||
"آتي إليك", "أتي إليك", "أتي", "آتي", "أتعال",
|
||
"أنا قادم", "قادم إليك", "قادم لك", "أقترب منك",
|
||
"أقترب", "أتقرّب", "بجي", "بجي لك", "جاي", "جاي لك",
|
||
"بقرّب", "أقرّب منك", "رايح لك", "أتجه إليك"
|
||
]
|
||
}
|
||
},
|
||
|
||
"follow_me": {
|
||
"canonical": "follow me",
|
||
"user_phrases": {
|
||
"english": ["follow me", "come with me", "walk with me"],
|
||
"arabic": [
|
||
"اتبعني", "تعال معي", "امش معي",
|
||
"تعال ورايا", "تعال ورائي", "تعا ورايي",
|
||
"تعال ويايا", "تعال وياي",
|
||
"خش ورايا", "خليك ورايا",
|
||
"يلا معي", "يلا معاي", "يا الله معي",
|
||
"روح ويايا", "امشي معاي", "امشي معي",
|
||
"خليك معي", "ضل معي", "ضل ورايا",
|
||
"تعال خلفي", "خش خلفي", "اتبعني يا سند"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["following you", "following", "coming with you"],
|
||
"arabic": [
|
||
"أتبعك", "آتي معك", "أمشي معك",
|
||
"بتبعك", "جاي ورايك", "بمشي معاك", "ماشي معاك"
|
||
]
|
||
}
|
||
},
|
||
|
||
"stay_here": {
|
||
"canonical": "stay here",
|
||
"user_phrases": {
|
||
"english": ["stay here", "stay", "wait here", "hold position", "don't follow me"],
|
||
"arabic": [
|
||
"ابق هنا", "اثبت هنا", "انتظر هنا", "لا تتبعني",
|
||
"خليك هنا", "خليك هون", "خلك هنا", "خل هنا",
|
||
"فضل هنا", "ضل هنا", "ضل هون", "ابقى هنا",
|
||
"اصبر هنا", "استنى هنا", "تو هنا",
|
||
"ثبات هنا", "اثبت بمكانك", "ابق بمكانك",
|
||
"ما تتبعني", "ما تجي ورايا", "ما تمشي معي",
|
||
"خليك بمحلك", "ضل بمحلك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["staying here", "staying", "waiting here"],
|
||
"arabic": [
|
||
"أبقى هنا", "أنتظر هنا", "أثبت هنا",
|
||
"باقي هنا", "بضل هنا", "بستنى هنا", "بقعد هنا"
|
||
]
|
||
}
|
||
},
|
||
|
||
"go_home": {
|
||
"canonical": "go home",
|
||
"user_phrases": {
|
||
"english": ["go home", "return home", "head home", "go back home"],
|
||
"arabic": [
|
||
"اذهب للبيت", "اذهب إلى البيت", "ارجع للبيت", "عُد للبيت",
|
||
"روح البيت", "روح للبيت", "روح ع البيت", "روح عالبيت", "روح بيت",
|
||
"ارجع البيت", "ارجاع البيت", "ارجع عالبيت", "ارجع ع البيت",
|
||
"خش البيت", "اطلع البيت",
|
||
"ارجع للقاعدة", "روح للقاعدة", "اتجه للبيت", "اتجه للقاعدة",
|
||
"عد للبيت", "عود للبيت"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["going home", "heading home", "returning home"],
|
||
"arabic": [
|
||
"أعود للبيت", "أذهب للبيت", "أتجه للبيت",
|
||
"براح البيت", "راجع البيت", "بروح للبيت", "أرجع للبيت"
|
||
]
|
||
}
|
||
},
|
||
|
||
"patrol": {
|
||
"canonical": "patrol",
|
||
"user_phrases": {
|
||
"english": ["patrol", "start patrol", "begin patrol", "patrol the area", "walk the route"],
|
||
"arabic": [
|
||
"طوف", "ابدأ الدورية", "ابدأ التطواف",
|
||
"دور بالمكان", "دور حواليك", "دور حوالينا", "لف بالمكان", "لف في المكان",
|
||
"تجول", "ابدأ التجوال", "تجول بالمكان",
|
||
"حراسة", "ابدأ الحراسة", "احرس المكان",
|
||
"طوف بالمكان", "تطوّف", "روح طوف"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["patrolling", "starting patrol", "beginning patrol"],
|
||
"arabic": [
|
||
"أطوف", "أبدأ الدورية", "أبدأ التطواف",
|
||
"بطوف", "بدور بالمكان", "ببدأ الدورية", "أتجول"
|
||
]
|
||
}
|
||
},
|
||
|
||
"look_around": {
|
||
"canonical": "look around",
|
||
"user_phrases": {
|
||
"english": ["look around", "scan the room", "scan around", "survey the area", "have a look around"],
|
||
"arabic": [
|
||
"انظر حولك", "تفحص المكان", "افحص المكان", "تطلع حولك",
|
||
"شوف حولك", "شوف حواليك", "شوف الغرفة", "شوف اللي حواليك",
|
||
"بص حواليك", "بص حولك", "بص في الغرفة",
|
||
"طلّ حواليك", "طلّ حولك", "تطلّع حواليك", "تطلّع حولك",
|
||
"افحص الغرفة", "افحص الموقع", "افحص اللي حولك",
|
||
"اسكان المكان", "امسح المكان", "امسح بنظرك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": ["looking around", "scanning around", "surveying the area"],
|
||
"arabic": [
|
||
"أنظر حولي", "أتفحص المكان", "أتطلع حولي",
|
||
"بشوف حواليّ", "بطلّ حواليّ", "بفحص المكان", "بمسح المكان"
|
||
]
|
||
}
|
||
},
|
||
|
||
"what_do_you_see": {
|
||
"canonical": "what do you see",
|
||
"user_phrases": {
|
||
"english": ["what do you see", "what can you see", "describe this", "describe what you see", "tell me what you see"],
|
||
"arabic": [
|
||
"ماذا ترى", "ماذا تشاهد", "صف ما تراه", "أخبرني ماذا ترى",
|
||
"شو شايف", "شو بتشوف", "شو عم تشوف", "شو تشوف",
|
||
"شنو تشوف", "شنو شايف", "شنو هذا",
|
||
"إيش تشوف", "ايش تشوف", "ايش شايف", "إيش شايف",
|
||
"وش تشوف", "وش شايف", "وش هذا",
|
||
"شايف إيه", "بتشوف إيه", "إيه اللي قدامك", "إيه اللي شايفه", "إيه ده",
|
||
"اشنو كاتشوف", "اشنو كاتشوف قدامك",
|
||
"صف لي اللي قدامك", "قول لي شو شايف", "وصف لي اللي قدامك", "وصفلي اللي قدامك",
|
||
"احكي لي اللي شايفه", "احكيلي شو شايف", "قولي شو شايف"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [],
|
||
"arabic": []
|
||
}
|
||
},
|
||
|
||
"repeat_last": {
|
||
"_": "Memory action: re-fire the most recent dispatched command. Marcus VoiceModule keeps a deque of recent commands and intercepts this canonical — it is NEVER passed to the brain, the resolved (real) command is dispatched instead. bot_phrases use distinctive multi-word forms ('repeating that', 'doing that again') to avoid colliding with the bare 'again' / 'تاني' that users might say in a different context.",
|
||
"canonical": "repeat last",
|
||
"user_phrases": {
|
||
"english": [
|
||
"do that again", "do it again", "again", "repeat", "redo",
|
||
"one more time", "once more", "do the same again",
|
||
"say that again", "do it once more", "repeat that",
|
||
"another time", "another one"
|
||
],
|
||
"arabic": [
|
||
"كرر", "كرّر", "كررها", "أعد", "أعدها", "أعد العملية",
|
||
"تاني", "مرة ثانية", "مرة تانية", "مرة كمان", "مرة أخرى",
|
||
"كرر اللي سويته", "كرر الحركة", "أعد الحركة", "مرة ثانية لو سمحت",
|
||
"أعد الكرة", "كمان مرة"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"repeating that", "doing that again", "doing it again",
|
||
"one more time", "doing the same again", "repeating the last action"
|
||
],
|
||
"arabic": [
|
||
"أعيد الحركة", "أكرر الحركة", "مرة ثانية", "أعيدها",
|
||
"أكررها", "أعيد آخر حركة", "أكرر آخر حركة"
|
||
]
|
||
}
|
||
},
|
||
|
||
"pause_motion": {
|
||
"_": "Soft hold: brain motion loops freeze in place (zero velocity) and wait. Resume continues the SAME motion from where it paused — different from stop, which terminates the chain. Marcus VoiceModule intercepts this canonical and sets motion_pause directly; brain never sees it. Persona Rule 10 instructs Gemini to confirm with 'Pausing.' / 'أتوقف مؤقتاً.'.",
|
||
"canonical": "pause motion",
|
||
"user_phrases": {
|
||
"english": [
|
||
"pause", "pause motion", "hold on", "hold position", "hold up",
|
||
"wait a moment", "wait a sec", "freeze for a moment", "one second",
|
||
"give me a sec", "pause for a moment", "stay there"
|
||
],
|
||
"arabic": [
|
||
"توقف لحظة", "انتظر لحظة", "ثبت", "ثبت مكانك",
|
||
"استنى شوي", "استنى ثانية", "ثانية واحدة", "لحظة", "هدّي شوي",
|
||
"ايقاف مؤقت", "وقفة قصيرة", "انتظرني", "خليك مكانك"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"pausing", "holding position", "holding for a moment",
|
||
"freezing in place", "pausing for a moment"
|
||
],
|
||
"arabic": [
|
||
"أتوقف مؤقتاً", "أتوقف لحظة", "أنتظر", "أثبت مكاني",
|
||
"إيقاف مؤقت", "انتظار قصير", "أبقى مكاني"
|
||
]
|
||
}
|
||
},
|
||
|
||
"resume_motion": {
|
||
"_": "Clears motion_pause so the previously-running brain loop continues. If nothing was actually paused, this is a quiet no-op. Persona Rule 10 instructs Gemini to confirm with 'Resuming.' / 'أكمل.'.",
|
||
"canonical": "resume motion",
|
||
"user_phrases": {
|
||
"english": [
|
||
"resume", "continue", "go on", "carry on", "keep going",
|
||
"proceed", "resume motion", "continue what you were doing",
|
||
"you can continue", "go ahead now"
|
||
],
|
||
"arabic": [
|
||
"أكمل", "استكمل", "كمّل", "كمل", "تابع", "استمر",
|
||
"كمّل الحركة", "كمّل اللي كنت فيه", "تابع اللي كنت تسوي",
|
||
"روح تابع", "استمر بالحركة"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"resuming", "continuing", "carrying on", "resuming motion",
|
||
"picking up where I left off"
|
||
],
|
||
"arabic": [
|
||
"أكمل", "أستمر", "أتابع", "أكمل الحركة",
|
||
"أكمل من حيث توقفت", "أتابع اللي كنت أسويه"
|
||
]
|
||
}
|
||
},
|
||
|
||
"start_recording": {
|
||
"_": "Begin capturing subsequent dispatched commands into a named sequence buffer. Marcus VoiceModule intercepts this canonical and starts recording. Optionally pre-name the sequence here ('start recording as my-greet') — otherwise the user must name it on save. The recording is in-memory until save_sequence is called.",
|
||
"canonical": "start recording",
|
||
"user_phrases": {
|
||
"english": [
|
||
"start recording", "begin recording", "record this",
|
||
"remember this sequence", "record what i do",
|
||
"record sequence", "start saving moves", "save what i do"
|
||
],
|
||
"arabic": [
|
||
"ابدأ التسجيل", "ابدأ تسجيل", "ابدا التسجيل",
|
||
"سجل اللي بسويه", "سجل الحركات",
|
||
"سجل ما أفعله", "ابدأ الحفظ"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"starting to record", "recording your sequence",
|
||
"i'm recording", "recording started"
|
||
],
|
||
"arabic": [
|
||
"بدأت التسجيل", "أسجل الحركات", "بدأت تسجيل التسلسل",
|
||
"بدأت أسجل"
|
||
]
|
||
}
|
||
},
|
||
|
||
"save_sequence": {
|
||
"_": "Stop recording and persist the buffered commands. The user typically appends a name in the SAME utterance ('save sequence as my-greet') — Gemini extracts the name and includes it in the confirmation. Marcus parses the bot_phrase, extracts the trailing name, calls Sequences.save_recording(name).",
|
||
"canonical": "save sequence",
|
||
"user_phrases": {
|
||
"english": [
|
||
"save sequence", "save this sequence", "save it as",
|
||
"save recording", "stop recording and save",
|
||
"stop recording save as", "save recording as",
|
||
"name this sequence", "call this sequence"
|
||
],
|
||
"arabic": [
|
||
"احفظ التسلسل", "احفظ التسجيل", "احفظ باسم",
|
||
"أوقف التسجيل واحفظ", "احفظ هذا التسلسل",
|
||
"سمي هذا التسلسل", "احفظ التسجيل باسم", "خلصت سجل"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"saved sequence", "saved as", "saving sequence as",
|
||
"recording saved", "saved your sequence as"
|
||
],
|
||
"arabic": [
|
||
"حفظت التسلسل", "حفظت باسم", "أحفظ التسلسل باسم",
|
||
"تم الحفظ"
|
||
]
|
||
}
|
||
},
|
||
|
||
"play_sequence": {
|
||
"_": "Replay a saved sequence by name. The bot_phrase carries the name ('Playing my-greet.'); Marcus extracts it and calls Sequences.play(name) → enqueues each command on the motion worker queue. Sequence commands execute serially with normal interrupt support — say 'stop' to abort the playback.",
|
||
"canonical": "play sequence",
|
||
"user_phrases": {
|
||
"english": [
|
||
"play sequence", "play my", "run my", "do my",
|
||
"play recording", "execute sequence", "run sequence",
|
||
"perform sequence"
|
||
],
|
||
"arabic": [
|
||
"شغل التسلسل", "نفذ التسلسل", "سوي اللي سجلته",
|
||
"ابدأ تسلسل", "نفذ تسجيل", "شغل التسجيل",
|
||
"اعمل التسلسل"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"playing", "running", "performing sequence",
|
||
"playing sequence", "starting sequence"
|
||
],
|
||
"arabic": [
|
||
"أشغل التسلسل", "أنفذ التسلسل", "أبدأ التسلسل",
|
||
"بدأت التشغيل"
|
||
]
|
||
}
|
||
},
|
||
|
||
"cancel_recording": {
|
||
"_": "Abandon the in-progress recording without saving. Marcus calls Sequences.cancel_recording().",
|
||
"canonical": "cancel recording",
|
||
"user_phrases": {
|
||
"english": [
|
||
"cancel recording", "discard recording", "throw away recording",
|
||
"stop recording without saving", "forget the recording"
|
||
],
|
||
"arabic": [
|
||
"ألغ التسجيل", "احذف التسجيل", "اوقف التسجيل بدون حفظ",
|
||
"تجاهل التسجيل"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"discarded recording", "cancelled recording",
|
||
"recording cancelled"
|
||
],
|
||
"arabic": [
|
||
"ألغيت التسجيل", "حذفت التسجيل", "تم إلغاء التسجيل"
|
||
]
|
||
}
|
||
},
|
||
|
||
"reverse_last": {
|
||
"_": "Memory action: fire the INVERSE of the last dispatched command (turn right→turn left, walk forward→walk backward, sit down→stand up, raise arm→lower arm; parametric forms flip direction and keep the number). Marcus intercepts the 'reverse last' canonical and computes the inverse from history. NOTE: the brain has its own 'undo' regex that returns to the start position via odometry — that's a different feature; reverse_last only flips the LAST motion. Distinctive bot_phrases avoid colliding with move_backward needles like 'going back' / 'reversing'.",
|
||
"canonical": "reverse last",
|
||
"user_phrases": {
|
||
"english": [
|
||
"undo", "undo that", "reverse", "reverse that",
|
||
"go back", "take that back", "cancel that",
|
||
"undo the last", "reverse the last", "do the opposite"
|
||
],
|
||
"arabic": [
|
||
"تراجع", "تراجع عن ذلك", "ارجع ما سويت", "ارجع",
|
||
"اعكس", "اعكسها", "ألغي", "ألغي ذلك", "ألغي الحركة",
|
||
"رد ما سويت", "تراجع عن آخر حركة", "اعكس آخر حركة",
|
||
"اعمل عكس", "اعمل العكس"
|
||
]
|
||
},
|
||
"bot_phrases": {
|
||
"english": [
|
||
"reversing that", "undoing that", "reversing the last action",
|
||
"undoing the last action", "going back to before"
|
||
],
|
||
"arabic": [
|
||
"أتراجع عن ذلك", "أعكس آخر حركة", "ألغي آخر حركة",
|
||
"أتراجع عن آخر حركة", "أرجع للحالة السابقة", "أعكسها"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
|
||
"_parametric_description": "Motion confirmations from Gemini that carry a NUMBER (turn 90 degrees, walk 5 steps, walk 2 meters). Each entry is regex-matched against Gemini's spoken reply; the captured groups are substituted into command_template via $1, $2 placeholders, and the resulting command_template string is dispatched to the brain — Brain/command_parser.py already parses 'turn left 90 degrees' / 'walk forward 5 steps' / 'walk 2 meters' natively. Order matters: more-specific patterns (with direction) MUST come before less-specific (no direction) so they claim spans first.",
|
||
"parametric_actions": [
|
||
{
|
||
"_": "turn left/right N degrees — 'Turning right 90 degrees.'",
|
||
"regex": "(?:turn(?:ing)?|spin(?:ning)?|rotat(?:e|ing))\\s+(left|right)\\s+(\\d+)\\s*deg(?:ree(?:s)?)?",
|
||
"command_template": "turn $1 $2 degrees"
|
||
},
|
||
{
|
||
"_": "turn left/right N steps (English) — 'Turning left 1 steps.' Maps to brain's _RE_TURN_STEP single-motion canonical 'turn left N steps' (NOT compound). User says 'turn left one step' — meaning one step's worth of left rotation.",
|
||
"regex": "(?:turn(?:ing)?|spin(?:ning)?|rotat(?:e|ing))\\s+(left|right)\\s+(\\d+(?:\\.\\d+)?)\\s*steps?",
|
||
"command_template": "turn $1 $2 steps"
|
||
},
|
||
{
|
||
"_": "Arabic أستدير يميناً/يساراً N خطوات — 'أستدير يساراً 1 خطوات' for 'لف يسار خطوة وحدة' single-motion intent. Parses as 'turn left N steps' brain canonical (not compound 'turn + walk').",
|
||
"regex": "(?:أستدير|استدر|لف+|ألف+|بلف|دور+|أدور+|بدور)\\s+(?:(?:على|ع|إلى)\\s+)?(?:يمين|يميناً|يمينا|اليمين|لليمين)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)",
|
||
"command_template": "turn right $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic أستدير يساراً N خطوات — same as above, left side.",
|
||
"regex": "(?:أستدير|استدر|لف+|ألف+|بلف|دور+|أدور+|بدور)\\s+(?:(?:على|ع|إلى)\\s+)?(?:يسار|يساراً|يسارا|اليسار|لليسار|شمال|الشمال|للشمال)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)",
|
||
"command_template": "turn left $1 steps"
|
||
},
|
||
{
|
||
"_": "turn N degrees — 'Turning 360 degrees.'",
|
||
"regex": "(?:turn(?:ing)?|spin(?:ning)?|rotat(?:e|ing))\\s+(\\d+)\\s*deg(?:ree(?:s)?)?",
|
||
"command_template": "turn $1 degrees"
|
||
},
|
||
{
|
||
"_": "walk forward/back N steps — 'Walking forward 5 steps.'",
|
||
"regex": "(?:walk(?:ing)?|step(?:ping)?|mov(?:e|ing))\\s+(forward|back(?:ward)?)\\s+(\\d+(?:\\.\\d+)?)\\s+steps?",
|
||
"command_template": "walk $1 $2 steps"
|
||
},
|
||
{
|
||
"_": "walk N steps forward/back — 'Walking 5 steps forward.'",
|
||
"regex": "(?:walk(?:ing)?|step(?:ping)?|tak(?:e|ing))\\s+(\\d+(?:\\.\\d+)?)\\s+steps?\\s+(forward|back(?:ward)?)",
|
||
"command_template": "walk $2 $1 steps"
|
||
},
|
||
{
|
||
"_": "walk N steps (default forward) — 'Taking 5 steps.'",
|
||
"regex": "(?:walk(?:ing)?|step(?:ping)?|tak(?:e|ing))\\s+(\\d+(?:\\.\\d+)?)\\s+steps?",
|
||
"command_template": "walk $1 steps"
|
||
},
|
||
{
|
||
"_": "walk forward/back N meters — 'Walking forward 2 meters.'",
|
||
"regex": "(?:walk(?:ing)?|mov(?:e|ing))\\s+(forward|back(?:ward)?)\\s+(\\d+(?:\\.\\d+)?)\\s*m(?:eter(?:s)?)?\\b",
|
||
"command_template": "walk $1 $2 meters"
|
||
},
|
||
{
|
||
"_": "walk N meters forward/back — 'Walking 2 meters forward.'",
|
||
"regex": "(?:walk(?:ing)?|mov(?:e|ing))\\s+(\\d+(?:\\.\\d+)?)\\s*m(?:eter(?:s)?)?\\s+(forward|back(?:ward)?)",
|
||
"command_template": "walk $2 $1 meters"
|
||
},
|
||
{
|
||
"_": "walk N meters (default forward) — 'Walking 2 meters.'",
|
||
"regex": "(?:walk(?:ing)?|mov(?:e|ing))\\s+(\\d+(?:\\.\\d+)?)\\s*m(?:eter(?:s)?)?\\b",
|
||
"command_template": "walk $1 meters"
|
||
},
|
||
{
|
||
"_": "Arabic turn right N degrees — covers MSA + Levantine/Syrian (لف يمين), Gulf/Iraqi (دور يمين), Egyptian (خش يمين). Verb roots: أستدير | استدر | لف | دور | خش. Direction tokens: يمين | يميناً | يمينا | اليمين (with optional على/ع prefix).",
|
||
"regex": "(?:أستدير|استدر|لف+|ألف+|دور+|أدور+|بدور|خش|أخش|بخش)\\s+(?:(?:على|ع)\\s+)?(?:يمين|يميناً|يمينا|اليمين|لليمين)\\s+(\\d+)\\s*درجة",
|
||
"command_template": "turn right $1 degrees"
|
||
},
|
||
{
|
||
"_": "Arabic turn left N degrees — also accepts شمال/الشمال (Lev/Egy 'left').",
|
||
"regex": "(?:أستدير|استدر|لف+|ألف+|دور+|أدور+|بدور|خش|أخش|بخش)\\s+(?:(?:على|ع)\\s+)?(?:يسار|يساراً|يسارا|اليسار|لليسار|شمال|الشمال|للشمال)\\s+(\\d+)\\s*درجة",
|
||
"command_template": "turn left $1 degrees"
|
||
},
|
||
{
|
||
"_": "Arabic turn N degrees (no direction) — 'أستدير 360 درجة' / 'لف 180 درجة' / 'دور 90 درجة'.",
|
||
"regex": "(?:أستدير|استدر|لف+|دور+)\\s+(\\d+)\\s*درجة",
|
||
"command_template": "turn $1 degrees"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps forward — verbs: أمشي | امشي | أتحرك | تحرك | روح | اروح. Forward: للأمام | لقدام | قدام (Egy/Lev).",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(?:للأمام|لقدام|قدام)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)",
|
||
"command_template": "walk forward $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps back — Back: للخلف | لورا | ورا (Egy/Lev/Gulf).",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(?:للخلف|لورا|ورا)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)",
|
||
"command_template": "walk backward $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps forward — number BEFORE direction (also common in Egy/Lev).",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)\\s+(?:للأمام|لقدام|قدام)",
|
||
"command_template": "walk forward $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps back — number BEFORE direction.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)\\s+(?:للخلف|لورا|ورا)",
|
||
"command_template": "walk backward $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps (default forward) — 'أمشي 5 خطوات' / 'امشي خمس خطوات' (digits only — Gemini is told to use digits).",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:خطوة|خطوات|خطوتين)",
|
||
"command_template": "walk $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic walk N steps — REVERSED word order: verb + unit + number ('أمشي خطوة واحدة' → after normalise_numbers → 'أمشي خطوة 1'). Common natural-Arabic phrasing where the number-adjective follows the noun. Without this entry, this very natural phrasing fails to dispatch.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(?:خطوة|خطوات|خطوتين)\\s+(\\d+)",
|
||
"command_template": "walk $1 steps"
|
||
},
|
||
{
|
||
"_": "Arabic DUAL form 'خطوتين' (two steps) — single word, no separate digit. Without this entry the dispatcher would miss 'أمشي خطوتين' since the parametric regex needs \\d+. Maps directly to walk 2 steps.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+خطوتين",
|
||
"command_template": "walk 2 steps"
|
||
},
|
||
{
|
||
"_": "Arabic DUAL form 'مترين' (two meters) — same dual-suffix pattern as above. 'أمشي مترين' / 'أتحرك مترين' → walk 2 meters.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+مترين",
|
||
"command_template": "walk 2 meters"
|
||
},
|
||
{
|
||
"_": "Arabic DUAL form 'درجتين' (two degrees) — for completeness, though 2-degree turns are rare.",
|
||
"regex": "(?:أستدير|استدر|لف+|ألف+|دور+|أدور+|بدور)\\s+(?:يميناً|يمينا|اليمين|لليمين|يساراً|يسارا|اليسار|لليسار|شمال|الشمال|للشمال)?\\s*درجتين",
|
||
"command_template": "turn 2 degrees"
|
||
},
|
||
{
|
||
"_": "Arabic walk N meters forward — direction first.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(?:للأمام|لقدام|قدام)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:متر|مترين|أمتار)",
|
||
"command_template": "walk forward $1 meters"
|
||
},
|
||
{
|
||
"_": "Arabic walk N meters back — direction first.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(?:للخلف|لورا|ورا)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:متر|مترين|أمتار)",
|
||
"command_template": "walk backward $1 meters"
|
||
},
|
||
{
|
||
"_": "Arabic walk N meters forward — number first.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:متر|مترين|أمتار)\\s+(?:للأمام|لقدام|قدام)",
|
||
"command_template": "walk forward $1 meters"
|
||
},
|
||
{
|
||
"_": "Arabic walk N meters back — number first.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:متر|مترين|أمتار)\\s+(?:للخلف|لورا|ورا)",
|
||
"command_template": "walk backward $1 meters"
|
||
},
|
||
{
|
||
"_": "Arabic walk N meters (default forward).",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|اروح|روح|اروحي|روحي)\\s+(\\d+(?:\\.\\d+)?)\\s*(?:متر|مترين|أمتار)",
|
||
"command_template": "walk $1 meters"
|
||
},
|
||
|
||
{
|
||
"_": "Generic dialect Arabic 'turn right' WITHOUT number. Catches forms NOT in turn_right.bot_phrases.arabic, e.g. 'ألف على اليمين', 'دور لليمين', 'أستدير إلى اليمين', 'لف ع اليمين'. Verbs: لف/ألف/بلف/دور/أدور/بدور/خش/أخش/بخش/حوّد/أحوّد/أستدير/استدير. Optional prep على/ع/إلى/لـ in front of direction.",
|
||
"regex": "(?:أستدير|استدير|استدر|لف+|ألف+|بلف|دور+|أدور+|بدور|خش|أخش|بخش|حوّد|أحوّد)\\s+(?:(?:على|ع|إلى)\\s+)?(?:ال)?(?:يمين|يميناً|يمينا|لليمين)",
|
||
"command_template": "turn right"
|
||
},
|
||
{
|
||
"_": "Generic dialect Arabic 'turn left' WITHOUT number — also catches شمال/الشمال.",
|
||
"regex": "(?:أستدير|استدير|استدر|لف+|ألف+|بلف|دور+|أدور+|بدور|خش|أخش|بخش|حوّد|أحوّد)\\s+(?:(?:على|ع|إلى)\\s+)?(?:ال)?(?:يسار|يساراً|يسارا|لليسار|شمال|الشمال|للشمال)",
|
||
"command_template": "turn left"
|
||
},
|
||
{
|
||
"_": "Generic dialect Arabic 'turn around' WITHOUT number — back/wara variants.",
|
||
"regex": "(?:أستدير|استدير|استدر|لف+|ألف+|بلف|دور+|أدور+|بدور)\\s+(?:(?:إلى|لـ)\\s*)?(?:للخلف|الخلف|للوراء|الوراء|للورا|ورا|لورا)",
|
||
"command_template": "turn around"
|
||
},
|
||
{
|
||
"_": "Generic dialect Arabic 'move forward' WITHOUT meters/steps — أمشي/أتحرك/أتقدم/أروح/بمشي/بتقدم + قدام/للأمام/الأمام variants.",
|
||
"regex": "(?:أمشي|امشي|امش|أتحرك|تحرك|أتقدم|بتقدم|أتقدّم|أروح|اروح|روح|براح|بمشي|بفوت|أفوت)\\s+(?:(?:إلى|لـ)\\s*)?(?:للأمام|الأمام|لقدام|قدام|للقدام)",
|
||
"command_template": "move forward"
|
||
},
|
||
{
|
||
"_": "Generic dialect Arabic 'move backward' WITHOUT meters/steps — أرجع/أتراجع/برجع + للخلف/ورا/الوراء variants.",
|
||
"regex": "(?:أرجع|ارجع|برجع|أتراجع|بتراجع|أتحرك|تحرك|أمشي|امشي|امش)\\s+(?:(?:إلى|لـ)\\s*)?(?:للخلف|الخلف|لورا|ورا|للوراء|الوراء)",
|
||
"command_template": "move backward"
|
||
},
|
||
|
||
{
|
||
"_": "STEP-CLOSER (English). Note: normalise_numbers runs BEFORE this regex matches and converts 'one'→'1'. The regex must accept both forms ('one step closer' OR '1 step closer'). Maps to a deterministic 1-step walk; distinct from 'walking to X' (planner) and 'come here' (YOLO-tracked).",
|
||
"regex": "(?:stepping|moving|coming|edging)\\s+closer|(?:one|1)\\s+step\\s+closer|step(?:ping)?\\s+(?:a\\s+(?:bit|little)\\s+)?forward",
|
||
"command_template": "walk forward 1 steps"
|
||
},
|
||
{
|
||
"_": "STEP-CLOSER (Arabic). Note: normalise_numbers converts 'واحدة'→'1' before this regex runs, so the optional 'one' part must match either واحدة or 1. Same single-step semantics as English.",
|
||
"regex": "أتقدم\\s+خطوة|أقترب\\s+خطوة|خطوة\\s+(?:(?:واحدة|1)\\s+)?(?:للأمام|قدام)|أقرب\\s+خطوة|أتقرّب\\s+خطوة|أقدّم\\s+خطوة|أخطو\\s+للأمام",
|
||
"command_template": "walk forward 1 steps"
|
||
},
|
||
|
||
{
|
||
"_": "WALK-TO-TARGET (English) — captures the named object after 'walking/heading/going to/towards'. Example bot phrases the dispatcher catches: 'Walking to the door.' / 'Heading to the chair.' / 'Walking towards the table.' / 'Going up to the wall.'. The captured target ($1) is plugged into the brain command 'walk to <target>', which Brain/command_parser._RE_WALK_TO routes into the LLaVA-grounded spatial planner. Constraints: (a) stops at sentence punctuation so 'walking to the door, then sitting' picks up just 'door', (b) the determiner-strip group includes 'that\\s+|this\\s+' so anaphora 'walking to that chair' captures 'chair' not 'that chair', (c) negative-lookahead before the target rejects pronouns (us|me|him|her|them|you|it|myself|yourself) so a Rule-4-violating description like 'I see a person walking towards us' does NOT fire 'walk to us'. Persona Rule 12 instructs Gemini to use these literal shapes. NOTE: target capture allows Arabic chars (U+0600–U+06FF) too — handles the field case where canonical_normalizer translated an Arabic verb+connective to English ('أتجه نحو X' → 'walking to X' with X still Arabic) and we want the planner to receive the Arabic target name. Qwen2.5-VL is multilingual; passing Arabic target to LLaVA prompt works.",
|
||
"regex": "(?:approaching|(?:walking|heading|going|moving)\\s+(?:over\\s+)?(?:to|towards?|up\\s+to)\\b)\\s+(?:the\\s+|a\\s+|an\\s+|that\\s+|this\\s+|ال)?(?!(?:us|me|him|her|them|you|it|myself|yourself|themselves|himself|herself|itself|هو|هي|هم|هما|هن|نحن|أنت|أنا)\\b)([A-Za-z\\u0600-\\u06FF][A-Za-z0-9\\u0600-\\u06FF ._-]{0,40}?)\\s*(?=[.!?،,]|$)",
|
||
"command_template": "walk to $1"
|
||
},
|
||
{
|
||
"_": "WALK-TO-TARGET (Arabic) — أمشي / أتجه / أتحرك + (إلى | نحو | تجاه | باتجاه) + <target>. Character class is the WHOLE Arabic block U+0600–U+06FF so vowel diacritics (fatha/damma/kasra/sukun, U+064B–U+065F) inside the target name don't truncate the capture (e.g. 'البَاب' with fatha was previously stopping at the fatha and capturing None). Determiner-strip includes هذا/هذه/ذلك/تلك (anaphora) plus the optional ال prefix. Pronoun negative-lookahead rejects هو/هي/هم/أنت/نحن/نا/ي etc as targets — handled by lookbehind avoiding common pronoun stems.",
|
||
"regex": "(?:أمشي|امشي|أتحرك|تحرك|أتجه|متجه|أروح|اروح|روح)\\s+(?:إلى|نحو|تجاه|باتجاه|لـ?ال?)\\s+(?:هذا|هذه|ذلك|تلك)?\\s*(?:ال)?(?!(?:هو|هي|هم|هما|هن|نحن|أنت|أنتم|أنا)\\b)([\\u0600-\\u06FF][\\u0600-\\u06FF 0-9_-]{0,40}?)\\s*(?=[.!?،,]|$)",
|
||
"command_template": "walk to $1"
|
||
}
|
||
]
|
||
}
|