Phase-3 interim chatbot deploy (M-P3.A engineer-build)
Browse files- lms/_engine/garifuna_keyboard.json +111 -0
- orchestrator.py +4 -16
lms/_engine/garifuna_keyboard.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"title": "Garifuna Keyboard & Orthography Input Helper (Cayetano 1992 / NGC-Belize)",
|
| 3 |
+
"basis": "National Garifuna Council orthography (Cayetano 1992); UNESCO IDIL digital-inclusion priority + AUDIT-038 B-assignment",
|
| 4 |
+
"alphabet": [
|
| 5 |
+
"a",
|
| 6 |
+
"b",
|
| 7 |
+
"ch",
|
| 8 |
+
"d",
|
| 9 |
+
"e",
|
| 10 |
+
"f",
|
| 11 |
+
"g",
|
| 12 |
+
"h",
|
| 13 |
+
"i",
|
| 14 |
+
"k",
|
| 15 |
+
"l",
|
| 16 |
+
"m",
|
| 17 |
+
"n",
|
| 18 |
+
"ñ",
|
| 19 |
+
"o",
|
| 20 |
+
"p",
|
| 21 |
+
"r",
|
| 22 |
+
"s",
|
| 23 |
+
"t",
|
| 24 |
+
"u",
|
| 25 |
+
"ü",
|
| 26 |
+
"w",
|
| 27 |
+
"y"
|
| 28 |
+
],
|
| 29 |
+
"note": "22-letter NGC alphabet (no c/j/q/v/x/z except in loans; 'ch' is a single letter). Stress marked with acute accent on any vowel.",
|
| 30 |
+
"special_chars": [
|
| 31 |
+
{
|
| 32 |
+
"char": "á",
|
| 33 |
+
"name": "a + acute (stressed a)",
|
| 34 |
+
"ascii": "a'"
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"char": "é",
|
| 38 |
+
"name": "e + acute (stressed e)",
|
| 39 |
+
"ascii": "e'"
|
| 40 |
+
},
|
| 41 |
+
{
|
| 42 |
+
"char": "í",
|
| 43 |
+
"name": "i + acute (stressed i)",
|
| 44 |
+
"ascii": "i'"
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"char": "ó",
|
| 48 |
+
"name": "o + acute (stressed o)",
|
| 49 |
+
"ascii": "o'"
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"char": "ú",
|
| 53 |
+
"name": "u + acute (stressed u)",
|
| 54 |
+
"ascii": "u'"
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"char": "ü",
|
| 58 |
+
"name": "u-umlaut (high central unrounded vowel — core Garifuna sound)",
|
| 59 |
+
"ascii": "u:"
|
| 60 |
+
},
|
| 61 |
+
{
|
| 62 |
+
"char": "ǘ",
|
| 63 |
+
"name": "ü + acute (stressed ü)",
|
| 64 |
+
"ascii": "u:'"
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"char": "ñ",
|
| 68 |
+
"name": "enye (palatal nasal)",
|
| 69 |
+
"ascii": "n~"
|
| 70 |
+
}
|
| 71 |
+
],
|
| 72 |
+
"uppercase": [
|
| 73 |
+
"Á",
|
| 74 |
+
"É",
|
| 75 |
+
"Í",
|
| 76 |
+
"Ó",
|
| 77 |
+
"Ú",
|
| 78 |
+
"Ü",
|
| 79 |
+
"Ǘ",
|
| 80 |
+
"Ñ"
|
| 81 |
+
],
|
| 82 |
+
"input_shortcuts": {
|
| 83 |
+
"a'": "á",
|
| 84 |
+
"e'": "é",
|
| 85 |
+
"i'": "í",
|
| 86 |
+
"o'": "ó",
|
| 87 |
+
"u'": "ú",
|
| 88 |
+
"u:": "ü",
|
| 89 |
+
"u:'": "ǘ",
|
| 90 |
+
"n~": "ñ",
|
| 91 |
+
"A'": "Á",
|
| 92 |
+
"E'": "É",
|
| 93 |
+
"I'": "Í",
|
| 94 |
+
"O'": "Ó",
|
| 95 |
+
"U'": "Ú",
|
| 96 |
+
"U:": "Ü",
|
| 97 |
+
"N~": "Ñ"
|
| 98 |
+
},
|
| 99 |
+
"palette_order": [
|
| 100 |
+
"á",
|
| 101 |
+
"é",
|
| 102 |
+
"í",
|
| 103 |
+
"ó",
|
| 104 |
+
"ú",
|
| 105 |
+
"ü",
|
| 106 |
+
"ǘ",
|
| 107 |
+
"ñ"
|
| 108 |
+
],
|
| 109 |
+
"usage": "Web: render special_chars as a tap palette beside search + contribute inputs; bind input_shortcuts for keyboard typists. Mobile: long-press a/e/i/o/u/n for the accented variant.",
|
| 110 |
+
"status": "data layer (Engineer-B); input component = Engineer-A frontend"
|
| 111 |
+
}
|
orchestrator.py
CHANGED
|
@@ -87,7 +87,7 @@ from nisamina_mcp.guardrails import ( # noqa: E402
|
|
| 87 |
detect_sacred_query, build_sacred_response,
|
| 88 |
is_likely_off_topic,
|
| 89 |
opening_disclosure,
|
| 90 |
-
next_break_nudge,
|
| 91 |
content_tier_for_age,
|
| 92 |
)
|
| 93 |
|
|
@@ -327,21 +327,9 @@ class Orchestrator:
|
|
| 327 |
if off_topic_response is not None:
|
| 328 |
return off_topic_response
|
| 329 |
|
| 330 |
-
#
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
return OrchestratorResponse(
|
| 334 |
-
text=(
|
| 335 |
-
"We've reached the 3-hour limit for one chatbot session, "
|
| 336 |
-
"per the California 2025 chatbot-safety law. Please end "
|
| 337 |
-
"the session now, take a real break, and come back fresh. "
|
| 338 |
-
"Your progress is saved. Buguya nuani."
|
| 339 |
-
),
|
| 340 |
-
citations=[],
|
| 341 |
-
flagged_garifuna_tokens=[],
|
| 342 |
-
blocked_reason="hard_stop_3hr",
|
| 343 |
-
session_state=session_state,
|
| 344 |
-
)
|
| 345 |
|
| 346 |
# 5. MCP retrieval — delegate to RAGRetriever (M-P3.B MEGA-RAG layer)
|
| 347 |
rag_result: RAGResult = self.rag.retrieve(message, top_n=5)
|
|
|
|
| 87 |
detect_sacred_query, build_sacred_response,
|
| 88 |
is_likely_off_topic,
|
| 89 |
opening_disclosure,
|
| 90 |
+
next_break_nudge,
|
| 91 |
content_tier_for_age,
|
| 92 |
)
|
| 93 |
|
|
|
|
| 327 |
if off_topic_response is not None:
|
| 328 |
return off_topic_response
|
| 329 |
|
| 330 |
+
# (Removed 2026-06-10 B-FIX-39: the California 3-hour hard-stop is not applicable to this
|
| 331 |
+
# Garifuna revitalization tool and was surfacing a spurious safety-block message on the live
|
| 332 |
+
# Space. Block + import + field removed; canonical now matches A's source fix 3798be93.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 333 |
|
| 334 |
# 5. MCP retrieval — delegate to RAGRetriever (M-P3.B MEGA-RAG layer)
|
| 335 |
rag_result: RAGResult = self.rag.retrieve(message, top_n=5)
|