"""Bridge 8: "modeli X yap" is handled by the bridge; a per-chat route survives until the user picks another model.""" import tempfile import unittest import model_gecis as g MODELS = [("gpt-6-sol", "GPT-6-Sol"), ("gpt-6-astra", "GPT-6-Astra"), ("gpt-6.1-sol", "GPT-6.1-Sol"), ("ide/9router-ag-gemini-3.8-flash-low", "agy/gemini-3.8-flash-low"), ("ide/9router-ag-gemini-3.8-flash-high", "agy/gemini-3.8-flash-high"), ("ide/9router-cc-claude-opus-5-5", "cc/opus-5-5"), ("ide/9router-cc-claude-opus-5-5-nt", "cc/opus-5-5 (no-think)"), ("ide/9router-nano-z-ai-glm-5.3-flash-uncensored", "nano/glm-5.3-flash-uncensored"), ("ide/agnes-agnes-2.0-flash", "agnes/agnes-2.0-flash"), ("ide/agnes-agnes-2.5-flash", "agnes/agnes-2.5-flash")] def user(text): return {"type": "message", "role": "user", "content": [{"type": "input_text", "text": text}]} def voice(text): return user(f"\n {text}\n user: x\n") def pick(text): command = g.komut_coz(text) return g.eslestir(command["ad"], MODELS) if command and command["tur"] == "gec" else command class Komut(unittest.TestCase): def test_spoken_names_resolve_to_one_model(self): for text, slug in [("modeli gemini flash low yap", "ide/9router-ag-gemini-3.8-flash-low"), ("Modeli Gemini 3.8 Flash High'a geçir", "ide/9router-ag-gemini-3.8-flash-high"), ("modeli klod opus yap", "ide/9router-cc-claude-opus-5-5"), ("modeli opusa geç", "ide/9router-cc-claude-opus-5-5"), ("modeli gpt 6 astra yap", "gpt-6-astra"), ("model geç gpt 6.1 sol", "gpt-6.1-sol"), ("modeli glm flaş sansürsüz yap", "ide/9router-nano-z-ai-glm-5.3-flash-uncensored")]: self.assertEqual((pick(text) or {}).get("slug"), slug, text) def test_ambiguous_name_lists_candidates_and_changes_nothing(self): self.assertEqual(pick("modeli agnes yap"), {"adaylar": ["agnes/agnes-2.0-flash", "agnes/agnes-2.5-flash"]}) def test_ordinary_sentences_are_not_commands(self): for text in ("Masaüstünde kaç klasör var", "bu modeli kullanarak bir site yap", "yapay zeka modeli nedir", "modeli değiştir", "hangi modeli önerirsin bu iş için bana söyle bakalım lütfen", "model " + "çok uzun bir cümle " * 5 + "yap"): self.assertFalse(pick(text) and "slug" in pick(text), text) self.assertEqual(g.komut_coz("seçili model hangisi"), {"tur": "sor"}) self.assertEqual(g.komut_coz("bu chatte ana model kim"), {"tur": "sor"}) def test_voice_delegation_yields_only_the_spoken_input(self): text, index, spoken = g.son_kullanici_metni({"input": [user("a"), voice("modeli opus yap")]}) self.assertEqual((text, index, spoken), ("modeli opus yap", 1, True)) self.assertEqual(g.son_kullanici_metni({"input": [user("x")]})[0], None) self.assertEqual(g.son_kullanici_metni({"input": [{"type": "function_call_output", "output": "x"}]})[0], None) class TurOrtasi(unittest.TestCase): def test_message_after_tool_items_is_mid_turn_and_after_final_answer_is_not(self): final = {"type": "message", "role": "assistant", "phase": "final_answer", "content": "ok"} call = {"type": "function_call", "call_id": "c", "name": "shell", "arguments": "{}"} out = {"type": "function_call_output", "call_id": "c", "output": "x"} self.assertFalse(g.tur_ortasi({"input": [user("a"), final, user(".")]}, 2)) self.assertTrue(g.tur_ortasi({"input": [user("a"), call, out, user(".")]}, 3)) self.assertTrue(g.tur_ortasi({"input": [user("a"), call, out, voice("bekliyorum"), user(".")]}, 4)) self.assertTrue(g.tur_ortasi({"input": [user("a"), {"type": "message", "role": "assistant", "phase": "commentary", "content": "bakıyorum"}, user(".")]}, 2)) self.assertFalse(g.tur_ortasi({"input": [user(".")]}, 0)) def test_handover_note_replaces_only_the_spoken_input(self): req = {"input": [voice("modeli opus yap")]} g.metni_degistir(req, 0, g.devir_notu("cc/opus-5-5", "GPT-6-Sol")) text = req["input"][0]["content"][0]["text"] self.assertIn("", text) self.assertIn("cc/opus-5-5 olarak devam ediyorum", text) self.assertNotIn("modeli opus yap", text) class Gecmis(unittest.TestCase): def test_handled_commands_in_history_become_notes_but_the_last_message_is_left_alone(self): req = {"input": [user("modeli gemini flash low yap"), user("Masaüstünde kaç dosya var"), voice("modeli opus yap"), user("modeli gpt 6 astra yap")]} self.assertEqual(g.gecmisi_temizle(req, MODELS), 2) self.assertIn("agy/gemini-3.8-flash-low olarak değiştirdi", req["input"][0]["content"][0]["text"]) self.assertEqual(req["input"][1]["content"][0]["text"], "Masaüstünde kaç dosya var") self.assertIn("", req["input"][2]["content"][0]["text"]) self.assertEqual(req["input"][3]["content"][0]["text"], "modeli gpt 6 astra yap") self.assertEqual(g.gecmisi_temizle(req, MODELS), 0) class Yon(unittest.TestCase): def test_route_lasts_until_the_user_picks_another_model_in_the_list(self): with tempfile.TemporaryDirectory() as home: y = g.Yonlendirme(home) y.koy("chat", "gpt-6-sol", "ide/x", simdi=1000) self.assertEqual(g.Yonlendirme(home).al("chat", "gpt-6-sol", simdi=1001), "ide/x") # survives a restart self.assertIsNone(y.al("other", "gpt-6-sol", simdi=1001)) self.assertIsNone(y.al("chat", "gpt-6-astra", simdi=1002)) # user picked another self.assertIsNone(y.al("chat", "gpt-6-sol", simdi=1003)) # and it stays cleared y.koy("chat", "gpt-6-sol", "ide/x", simdi=1000) y.koy("chat", "gpt-6-sol", "gpt-6-sol", simdi=1001) # back to the picked one self.assertIsNone(y.al("chat", "gpt-6-sol", simdi=1002)) y.koy("old", "a", "b", simdi=1000) self.assertIsNone(y.al("old", "a", simdi=1000 + g.OMUR_SN + 1)) if __name__ == "__main__": unittest.main()