User decision (10 Oct 2026): combos keep their own name; single models read as short provider/model with the version kept (cc/opus-5-5, agy/gemini-3.8-flash-high, bekci/kurnaz). No-think copies show their real provider with a "(no-think)" suffix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
108 lines
6.2 KiB
Python
108 lines
6.2 KiB
Python
import json, os, tempfile, unittest
|
|
import ide_catalog as c
|
|
|
|
|
|
def girdi(mid, ad, yetenek=("chat",), sira=0, kaynak="omniroute", kind="model"):
|
|
return {"id": mid, "turkservis": {"display_name": ad, "capabilities": list(yetenek), "order": sira, "source": kaynak, "kind": kind}}
|
|
|
|
|
|
KATALOG = [
|
|
girdi("Ajan-Arac", "OmniRoute · Ajan-Arac", sira=5),
|
|
girdi("9router-cc-opus", "OmniRoute · cc/claude-opus-5-5", sira=2),
|
|
girdi("9router-nano-x", "OmniRoute · nano/x", sira=1),
|
|
girdi("gorsel", "OmniRoute · gpt-image-1", ("image",)),
|
|
girdi("9router-Takim-Agir", "OmniRoute · Takim-Agir", sira=9, kind="combo"),
|
|
girdi("9router-Takim-Agir-6e65dba5", "OmniRoute · Takim-Agir", sira=8, kind="combo"),
|
|
girdi("Ajan-Arac", "OmniRoute · Ajan-Arac (tekrar)"),
|
|
]
|
|
|
|
|
|
class Ayar(unittest.TestCase):
|
|
def test_dosya_yoksa_varsayilan_acik(self):
|
|
self.assertEqual(c.ayar_oku(os.path.join(tempfile.gettempdir(), "yok-boyle-dosya.json")), {"enabled": True, "kapsam": "ide"})
|
|
|
|
def test_kapatma_ve_bozuk_dosya(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
yol = os.path.join(d, "a.json")
|
|
for icerik, beklenen in [('{"enabled": false}', {"enabled": False, "kapsam": "ide"}),
|
|
('{"enabled": true, "kapsam": "hepsi"}', {"enabled": True, "kapsam": "hepsi"}),
|
|
('{"enabled": "hayir", "kapsam": "x"}', {"enabled": True, "kapsam": "ide"}),
|
|
('bozuk', {"enabled": True, "kapsam": "ide"})]:
|
|
open(yol, "w", encoding="utf-8").write(icerik)
|
|
self.assertEqual(c.ayar_oku(yol), beklenen, icerik)
|
|
|
|
|
|
class Yapilandirma(unittest.TestCase):
|
|
def test_config_yaml_okuma(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
open(os.path.join(d, "config.yaml"), "w", encoding="utf-8").write(
|
|
"model:\n default: Ajan-Arac\n provider: turkservis\nproviders:\n baska:\n models:\n Yabanci: {}\n"
|
|
" turkservis:\n base_url: https://ornek.test/v1/\n # yorum\n models:\n Hermes-Master: {}\n"
|
|
" 'cc/claude-opus-5-5': {}\n timeout: 3\nmcp_servers:\n x:\n models:\n Degil: {}\n")
|
|
open(os.path.join(d, ".env"), "w", encoding="utf-8").write("A=1\nHERMES_CUSTOM_TURKSERVIS_API_KEY='sahte-anahtar'\n")
|
|
self.assertEqual(c.ide_yapilandirma(d), ("https://ornek.test/v1", "Ajan-Arac", ["Hermes-Master", "cc/claude-opus-5-5"]))
|
|
self.assertEqual(c.anahtar_oku(d), "sahte-anahtar")
|
|
|
|
def test_dosyalar_yoksa(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
self.assertEqual(c.ide_yapilandirma(d), (c.DEFAULT_BASE, "", []))
|
|
self.assertEqual(c.anahtar_oku(d), "")
|
|
|
|
|
|
class Secim(unittest.TestCase):
|
|
def test_ide_kapsami(self):
|
|
s = c.sec(KATALOG, ["cc/claude-opus-5-5"], "ide")
|
|
# Uye katalogu yerel config'teki adlarla sinirlanmaz.
|
|
self.assertEqual([x["id"] for x in s], ["9router-nano-x", "9router-cc-opus", "Ajan-Arac"])
|
|
|
|
def test_9router_combolari_gosterilmez(self):
|
|
katalog = [girdi("9router-Takim-Agir-6e65dba5", "Takim-Agir", kaynak="9router", sira=1),
|
|
girdi("9router-Takim-Agir", "Takim-Agir (2)", sira=2, kind="combo"),
|
|
girdi("Takim-Agir", "Takim-Agir (3)", sira=3),
|
|
girdi("Ajan-Arac", "Ajan-Arac", sira=4),
|
|
girdi("9router-nano-x", "nano/x", kaynak="9router", sira=5)]
|
|
s = c.sec(katalog, ["nano/x"], "ide")
|
|
# 9Router combosu ve gecidin 9router saglayicisindaki kopyasi yok; OmniRoute'un kendi combosu
|
|
# sayacsiz adiyla kalir. Dogrudan 9Router tekilleri de eklenmez.
|
|
self.assertEqual([(x["id"], x["ad"]) for x in s],
|
|
[("Takim-Agir", "Takim-Agir"), ("Ajan-Arac", "Ajan-Arac")])
|
|
|
|
def test_9router_modelleri_yalniz_omniroute_uzerinden_eklenir(self):
|
|
katalog = [girdi("9router-nano-x-aaaa1111", "nano/x", kaynak="9router", sira=1),
|
|
girdi("9router-nano-x", "nano/x (2)", sira=2),
|
|
girdi("9router-ocg-y-bbbb2222", "ocg/y", kaynak="9router", sira=3),
|
|
girdi("vag-z", "vag/z", sira=4),
|
|
girdi("9router-ses", "nano/ses", ("tts",), kaynak="9router", sira=5),
|
|
girdi("9router-Takim-Agir-6e65dba5", "Takim-Agir", kaynak="9router", sira=6)]
|
|
s = c.sec(katalog, [], "ide")
|
|
# Yerel model tanimi gerekmez; iki kaynak yerine yalniz OmniRoute yolu gelir.
|
|
self.assertEqual([(x["id"], x["ad"]) for x in s],
|
|
[("9router-nano-x", "nano/x"), ("vag-z", "vag/z")])
|
|
|
|
def test_gorunen_ad_yalniz_saglayici_ve_model(self):
|
|
for tam, beklenen in [("OmniRoute · ag/gemini-3.8-flash", "ag/gemini-3.8-flash"),
|
|
("nano/qwen/qwen3.8-27b-obliterated:thinking", "nano/qwen3.8-27b-obliterated:thinking"),
|
|
("9Router · Nous-Research/inclusionai/ling-3.1-flash", "Nous-Research/ling-3.1-flash"),
|
|
("cf/@cf/qwen/qwq-32b", "cf/qwq-32b"),
|
|
("9R · nano/qwen/qwen3.8-27b", "nano/qwen3.8-27b"), ("9R · ag/gemini", "ag/gemini"),
|
|
("OmniRoute · Ajan-Arac", "Ajan-Arac"), ("cc/claude-opus-5-5", "cc/claude-opus-5-5")]:
|
|
self.assertEqual(c.kisa_ad(tam), beklenen, tam)
|
|
|
|
def test_cakisan_adlar_ayirt_edilir(self):
|
|
adlar = c.adlandir([("a", "nano/z-ai/glm-5.3"), ("b", "nano/baska/glm-5.3"), ("d", "cc/opus"), ("e-12345678", "OmniRoute · Takim-Agir")],
|
|
dolu={"takim-agir"})
|
|
self.assertEqual(adlar["a"], "nano/z-ai/glm-5.3") # kisa adi cakisan: aradaki halka geri gelir
|
|
self.assertEqual(adlar["b"], "nano/baska/glm-5.3")
|
|
self.assertEqual(adlar["d"], "cc/opus")
|
|
self.assertEqual(adlar["e-12345678"], "Takim-Agir [12345678]")
|
|
self.assertEqual(len(set(adlar.values())), 4)
|
|
|
|
def test_hepsi_kapsami_yalniz_sohbet(self):
|
|
s = c.sec(KATALOG, [], "hepsi")
|
|
self.assertEqual(len(s), 3) # iki 9Router combosu hicbir kapsamda gosterilmez
|
|
self.assertNotIn("gorsel", [x["id"] for x in s])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|