5858# )
5959from call_processing .constants .language_config import (
6060 LANGUAGE_INSTRUCTIONS ,
61+ LANGUAGE_DISPLAY_NAMES ,
6162)
6263from call_processing .constants .filler_phrases import FILLER_PHRASES
6364
@@ -83,7 +84,9 @@ def __init__(
8384 for lang_code in supported_languages :
8485 filter_func = self ._create_language_filter (lang_code )
8586 stt_service = stt_services [lang_code ]
86- routes .append ([FunctionFilter (filter_func ), stt_service ])
87+ routes .append (
88+ [FunctionFilter (filter_func , filter_system_frames = True ), stt_service ]
89+ )
8790
8891 super ().__init__ (* routes )
8992
@@ -130,7 +133,9 @@ def __init__(
130133 for lang_code in supported_languages :
131134 filter_func = self ._create_language_filter (lang_code )
132135 tts_service = tts_services [lang_code ]
133- routes .append ([FunctionFilter (filter_func ), tts_service ])
136+ routes .append (
137+ [FunctionFilter (filter_func , filter_system_frames = True ), tts_service ]
138+ )
134139
135140 super ().__init__ (* routes )
136141
@@ -313,13 +318,45 @@ async def run_conversation(
313318 initial_language_instruction = LANGUAGE_INSTRUCTIONS .get (
314319 default_language , LANGUAGE_INSTRUCTIONS .get ('en' , 'Respond in English.' )
315320 )
321+ supported_language_names = [
322+ LANGUAGE_DISPLAY_NAMES .get (code , code ) for code in supported_languages
323+ ]
316324 language_switching_rules = (
317- f'\n \n LANGUAGE SWITCHING RULES:\n '
318- f'- You support these languages only: { ", " .join (supported_languages )} .\n '
319- f'- Call detect_and_switch_language only when the user clearly intends to choose or change language. '
320- f'A single word is a valid choice if it directly answers a language preference question.\n '
321- f'- Do NOT switch based on a greeting (e.g. "Namaste") or incidental use of another language.\n '
322- f'- If the user requests a language not in the supported list, apologise and tell them which languages are available. Do not call the switch tool.'
325+ f'\n \n LANGUAGE SWITCHING RULES (follow exactly, no exceptions):\n '
326+ f'Supported languages: { ", " .join (supported_language_names )} .\n '
327+ f'Current language: { LANGUAGE_DISPLAY_NAMES .get (default_language , default_language )} .\n \n '
328+ f'CASE 1 — USER WANTS THE ASSISTANT TO USE A DIFFERENT LANGUAGE:\n '
329+ f'The user is asking or implying that they want the conversation to happen in a specific supported language. Triggers include:\n '
330+ f' - Saying a supported language name alone (e.g. "Hindi", "English", "Tamil")\n '
331+ f' - Asking if you can speak/use a language (e.g. "Can you speak in English?", "क्या आप हिंदी में बात कर सकते हैं?")\n '
332+ f' - Requesting a switch (e.g. "switch to Hindi", "speak in Tamil", "Hindi mein baat karo", "change language")\n '
333+ f' - Saying "speaking [language]" implying they want the assistant to speak it (e.g. "Speaking Hindi")\n '
334+ f' - Responding with a language name after being asked which language they want\n '
335+ f' - A word that phonetically resembles a supported language name — STT often mishears language names '
336+ f'(e.g. "Hindi" → "Indy" or "Indie", "Kannada" → "Canada", "Telugu" → "Tell you"). '
337+ f'Use phonetic judgment: if the word sounds like a supported language name in context, treat it as CASE 1.\n '
338+ f'BIAS RULE: When in doubt between CASE 1 and CASE 2, if a supported language name (or phonetic match) '
339+ f'appears in the message, default to CASE 1.\n '
340+ f'ACTION: Call detect_and_switch_language immediately. Do NOT ask for confirmation. Do NOT say anything before calling the tool.\n \n '
341+ f'CASE 2 — USER SPEAKS IN A DIFFERENT LANGUAGE (no language name mentioned, no switch request):\n '
342+ f'The user sends a full message in a language different from the current language, '
343+ f'with NO mention of a language name and NO request to switch. They are just talking.\n '
344+ f'NOTE: STT may transcribe foreign speech phonetically in the current language script — '
345+ f'e.g. if current language is English and the user speaks Hindi, STT may output romanized Hindi '
346+ f'like "Ha muje naye loan ke baare mai batao". Recognize this as Hindi input, not English.\n '
347+ f'ACTION: Do NOT call detect_and_switch_language. Do NOT answer their query. '
348+ f'Respond in the CURRENT language (the language you are currently configured to speak) with this meaning: '
349+ f'"Are you trying to switch the language? If yes, please say one of: { ", " .join (supported_language_names )} "\n \n '
350+ f'CASE 3 — UNSUPPORTED LANGUAGE REQUESTED:\n '
351+ f'The user requests a language not in the supported list.\n '
352+ f'ACTION: Do NOT call detect_and_switch_language. Inform the user that only these languages are supported: '
353+ f'{ ", " .join (supported_language_names )} .\n \n '
354+ f'CRITICAL RULES:\n '
355+ f'- Never call detect_and_switch_language for Case 2 or Case 3.\n '
356+ f'- Never answer a query in the wrong language before switching.\n '
357+ f'- Never ask for confirmation before switching in Case 1.\n '
358+ f'- Never respond with your own words before or instead of calling the tool in Case 1.\n '
359+ f'- Never invent responses outside these three cases.'
323360 )
324361 system_content = f'{ initial_language_instruction } \n \n { base_system_prompt } { language_switching_rules } '
325362 # Store base prompt without language instruction for switching (rules persist across switches)
@@ -426,13 +463,16 @@ async def run_conversation(
426463 language_detection_schema = FunctionSchema (
427464 name = 'detect_and_switch_language' ,
428465 description = (
429- f"Switch the conversation language when the user clearly intends to choose or change language. "
430- f"Use conversational context to judge intent — a single word like 'Hindi' or 'Tamil' counts as an "
431- f"explicit choice when it directly answers a question about language preference. "
432- f"Also trigger on explicit requests like 'switch to Hindi', 'speak in Tamil', 'Hindi mein baat karo'. "
433- f"Do NOT trigger on greetings in another language (e.g. 'Namaste') without a clear intent to switch. "
434- f"Only switch to languages in the supported list: { ', ' .join (supported_languages )} . "
435- f"If the user asks for an unsupported language, do NOT call this tool — inform them directly in the current language. "
466+ f"Switch the conversation language. "
467+ f"Call this when the user wants the assistant to use a specific language — "
468+ f"this includes: saying a language name directly ('Hindi', 'Tamil'), "
469+ f"asking 'can you speak in X?', saying 'speaking [language]', "
470+ f"or phrases like 'switch to Hindi', 'speak in Tamil', 'Hindi mein baat karo'. "
471+ f"STT may mishear language names (e.g. 'Hindi' → 'Indy', 'Kannada' → 'Canada') — use phonetic judgment. "
472+ f"When in doubt and a language name is present, call this tool. "
473+ f"Do NOT call this tool when the user simply starts speaking in another language with no language name and no switch request — "
474+ f"in that case respond in the current language asking if they want to switch. "
475+ f"Only switch to supported languages: { ', ' .join (supported_language_names )} . "
436476 f"Current language: { language_state ['current_language' ]} ."
437477 ),
438478 properties = {
0 commit comments