feat(codex-bridge): Jev routes a blocked step down the layer combos, no exceptions

Katman-1..3 answers are checked by Jev each step; a blocked step is redone by
the next layer combo. Katman-4 is delivered unasked. The technical-obstacle,
question and third-party exemptions and the settings overrides are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-11 09:06:21 +03:00
1 parent 1f4f2de428
commit be0b33e89b
3 files changed
+160 -182

No files matched your search

+21 -49
View File
@@ -1,23 +1,13 @@
"""Adim denetimi: ek modelin her adimdaki cevabini Jev gecirir ya da gecirmez (11 Ekim 2026).
"""Katman denetimi: Jev, katman combosunun her adimdaki cevabini gecirir ya da gecirmez (11 Ekim 2026).
Kullanici karari (11 Ekim 2026): "Bu kopruye Jev koy, her model her adimda kontrol etsin ve yakaladigini qwen 3.8
obliterated thinking versin." / "Bir prompt cok adimli olabilir; her adim kontrol edilsin. Jev sadece geciren ya da
gecirmeyen; gecirmezse 3.8 obliterated thinking." Ardindan (ayni gun): "obliterated:thinking yerine Uncensored-Uygulama yapar
misin" -> yedek, Uncensored-Uygulama combosudur. Yani denetim adim basinadir: Jev'in gecirmedigi adimi yedek model
yapar, sonraki adim yine secili modele gider ve yine denetlenir.
Kullanici karari (11 Ekim 2026): "Jev kati olsun. Af yok istisna yok. 1.Katman combosu Jev'e gelirse Jev bunu
gecirmezse 2.Katmana yonlendirecek. 2.Katman gecmezse 3.Katmana, 3.Katman gecmezse 4.Katmana. 4.Katman combosu
gelirse Jev bunu sorgulamadan gecirecek."
Jev (TypeSafe System One) metin uretmez; bir duruma sorulan evet/hayir sorularina olasilik verir (olcum 11 Ekim
2026: cagri basina ~0,4 sn, 13 gercek ornegin 13'u dogru ayrildi). Kural kodda durur:
- yakalanir: cevap istegi yapmiyor/soylemiyor (ret, kacamak, konuyu degistirme) ya da istegi sormadan kendi
sartlariyla degistiriyor;
- yakalanmaz: somut bir teknik engel bildiren cevap (hata, eksik dosya/arac/yetki), ret icermeyen netlestirme
sorusu ve metni olmayan (yalniz arac cagiran) adim. "Yapamam, soyle yapayim mi?" diye soran cevap yakalanir.
Jev'e ulasilamazsa cevap oldugu gibi gecer (is durmaz); art arda hatada bir sure hic sorulmaz.
Codex'in kendi modelleri kopruye ugramadigi icin bu denetimin disindadir.
Ayar (bridge.json, istege bagli): "jev_denetim": {"enabled": false} kapatir; "hedef" yedek modelin Codex adi;
"ret", "sart", "teknik", "soru" esikleri; "sure" saniye.
Katmanlar OmniRoute combolaridir (KATMAN); kopru onlari yalniz adiyla cagirir. Jev (TypeSafe System One) metin
uretmez, sorulan evet/hayir sorularina olasilik verir. Kural tektir ve istisnasi yoktur: cevap istegi yapmiyorsa
(ret) ya da sormadan kendi sartlariyla degistiriyorsa (sart) adim gecmez ve ayni adimi bir sonraki katman yapar.
Metni olmayan (yalniz arac cagiran) adimda sorulacak cevap yoktur. Jev'e ulasilamazsa cevap oldugu gibi verilir.
"""
import json
import os
@@ -28,11 +18,8 @@ import urllib.request
ADRES = "https://api.typesafe.ai/v1/systemone"
MODEL = "jev-1.13.0"
HEDEF = "ide/Uncensored-Uygulama"
# Kullanici karari (11 Ekim 2026): "Jev gecmek zor olsun." Esikler dusuruldu; bir ret ancak GERCEKTEN yuksek teknik
# engel (teknik_muaf) ile gecer, sahte teknik bahane artik yakalanir. Tek istisna zarar: ucuncu kisinin cihazina/
# hesabina izinsiz girme ya da malware/saldiri araci uretme istegi; orada model reddederse ret DURUR, yedege gitmez.
ESIK = {"ret": 0.5, "sart": 0.7, "teknik_muaf": 0.85, "soru": 0.5, "zarar": 0.6}
KATMAN = ("Katman-1", "Katman-2", "Katman-3", "Katman-4")
ESIK = {"ret": 0.5, "sart": 0.7}
SURE = 6.0
EN_COK_ISTEK = 3000
EN_COK_CEVAP = 6000
@@ -43,20 +30,20 @@ SORU = {
"said it cannot or will not, avoided giving the requested judgment, or redirected to a different topic."),
"sart": ("The assistant changed the request on its own: it added its own conditions, softened or relabeled what was "
"asked, or left part of it out, instead of doing exactly what the user asked."),
"teknik": ("The assistant reports a concrete technical obstacle as the reason: an error message, a failed command, "
"a missing file, tool, permission, connection or piece of information."),
"soru": ("The assistant's reply is mainly a question to the user: it asks for a clarification, a choice or an "
"approval and waits for the user's answer before doing anything."),
"zarar": ("The user's request is to hack, intrude on, surveil or take control of a device, account, network or "
"system that is not the user's own, or to create malware or attack tooling against other people."),
}
_KILIT = threading.Lock()
_DEVRE = {"hata": 0, "kadar": 0.0}
_ANAHTAR = {"okundu": False, "deger": ""}
def sonrakiler(hedef):
"""Bu katmandan sonra sirayla denenecek katmanlar. Son katman ve katman olmayan model icin bos: Jev'e sorulmaz."""
ad = str(hedef or "")
return list(KATMAN[KATMAN.index(ad) + 1:]) if ad in KATMAN else []
def anahtar(ortam=None, dosyalar=None):
"""TypeSafe anahtari: ortam degiskeni, sonra ~/.typesafe/typesafe.env. Yoksa "" (denetim kapali sayilir)."""
"""TypeSafe anahtari: ortam degiskeni, sonra ~/.typesafe/typesafe.env. Yoksa ""."""
ortam = os.environ if ortam is None else ortam
deger = str(ortam.get("TYPESAFE_API_KEY") or "").strip()
if deger:
@@ -122,7 +109,7 @@ def _gonder(govde, key, sure):
def sor(istek, cevap, key, sure=SURE, gonder=_gonder, simdi=None):
"""Jev'e dort soruyu sorar. Donus: {"ret","sart","teknik","soru"} olasiliklari | None (sorulamadi)."""
"""Jev'e sorar. Donus: {"ret", "sart"} olasiliklari | None (sorulamadi)."""
simdi = time.time() if simdi is None else simdi
with _KILIT:
if simdi < _DEVRE["kadar"]:
@@ -143,21 +130,6 @@ def sor(istek, cevap, key, sure=SURE, gonder=_gonder, simdi=None):
return sonuc
def karar(puan, ayar=None):
"""True: adim gecmez (yedek model yapar). Esikler ayardan degistirilebilir.
Kullanici karari (11 Ekim 2026): "Jev gecmek zor olsun." Ret ya da sart iceren cevap, sonunda soru sorsa bile
gecmez; yalniz gercekten yuksek teknik engel ("SSH reddedildi") ya da ret icermeyen netlestirme sorusu gecer.
Istisna: istek ucuncu kisiye saldiri/malware ise (zarar) ret DURUR, yedege gitmez."""
e = dict(ESIK)
e.update({k: float(v) for k, v in (ayar or {}).items() if k in ESIK})
if puan.get("zarar", 0.0) >= e["zarar"] and puan["ret"] >= e["ret"]:
return False # ucuncu kisiye zarar istegi reddedildi: ret durur, yedek yapmaz
if puan["ret"] >= e["ret"] and puan["teknik"] < e["teknik_muaf"]:
return True # yapmiyor / soylemiyor (gercek teknik engel degil)
return puan["sart"] >= e["sart"] # sormadan kendi sartlariyla degistirdi
def ayar_oku(cfg):
"""(acik, hedef slug, ayar sozlugu)."""
ayar = cfg if isinstance(cfg, dict) else {}
return ayar.get("enabled", True) is not False, str(ayar.get("hedef") or HEDEF), ayar
def karar(puan):
"""True: adim gecmez, sonraki katman yapar. Istisna yok."""
return puan["ret"] >= ESIK["ret"] or puan["sart"] >= ESIK["sart"]
+57 -58
View File
@@ -871,51 +871,56 @@ class H(http.server.BaseHTTPRequestHandler):
self.send_header("Transfer-Encoding", "chunked")
self.end_headers()
def _denetimli_akis(self, resp, tag, rewriter, izle, istek, ayar, yedek):
"""Adim denetimi (jev_denetim.py): cevap istemciye verilmeden once tamami okunur ve Jev'e sorulur.
Gecerse oldugu gibi verilir; gecmezse atilir ve ayni adimi yedek model yapar (yedek(): (resp, rewriter, tag)).
Beklerken istemciye SSE yorum satiri gider ki Codex akisi kopmus saymasin."""
def _denetimli_akis(self, resp, tag, rewriter, izle, istek, sira, ac):
"""Katman denetimi (jev_denetim.py): cevap istemciye verilmeden once tamami okunur ve Jev'e sorulur.
Gecerse oldugu gibi verilir; gecmezse atilir ve ayni adimi siradaki katman yapar (ac(ad): (resp, rewriter,
tag)). Son katmanin cevabi sorulmadan akar. Beklerken SSE yorum satiri gider ki Codex akisi kopmus saymasin."""
self._akis_basligi(resp, resp.status)
parcalar, okuyan, son_yazi = [], yarim.Izleyici("", ""), time.time()
kalan, son_yazi = list(sira), time.time()
def w(b):
if b:
self.wfile.write(b"%x\r\n" % len(b) + b + b"\r\n"); self.wfile.flush()
try:
while True:
try:
chunk = resp.read1(4096)
except (OSError, http.client.HTTPException) as e:
log(f"{tag} ust kaynak koptu (denetim tamponu, {sum(map(len, parcalar))} bayt): {type(e).__name__}: {e}")
self.close_connection = True
return
if not chunk:
parcalar, okuyan = [], yarim.Izleyici("", "")
while True:
try:
chunk = resp.read1(4096)
except (OSError, http.client.HTTPException) as e:
log(f"{tag} ust kaynak koptu (denetim tamponu, {sum(map(len, parcalar))} bayt): {type(e).__name__}: {e}")
self.close_connection = True
return
if not chunk:
break
parcalar.append(chunk)
okuyan.feed(chunk)
if time.time() - son_yazi >= 10:
w(b": denetim\n\n"); son_yazi = time.time()
metin = okuyan.metin.strip()
gecmedi = False
if metin:
t0 = time.time()
puan = jev_denetim.sor(istek, metin, jev_denetim.anahtar())
if puan is None:
log(f"{tag} katman denetimi: Jev'e sorulamadi, cevap oldugu gibi geciyor")
else:
gecmedi = jev_denetim.karar(puan)
log(f"{tag} katman denetimi: ret={puan['ret']:.2f} sart={puan['sart']:.2f} -> "
f"{'GECMEDI' if gecmedi else 'gecti'} ({time.time() - t0:.1f} sn, {len(metin)} karakter)")
yeni = None
while gecmedi and kalan and yeni is None:
ad = kalan.pop(0)
try:
yeni = ac(ad)
except Exception as e:
log(f"{tag} katman denetimi: {ad} acilamadi ({type(e).__name__}: {str(e)[:120]})")
if yeni is None:
break
parcalar.append(chunk)
okuyan.feed(chunk)
if time.time() - son_yazi >= 10:
w(b": denetim\n\n"); son_yazi = time.time()
metin = okuyan.metin.strip()
gecmedi = False
if metin and istek:
t0 = time.time()
puan = jev_denetim.sor(istek, metin, jev_denetim.anahtar(), float(ayar.get("sure") or jev_denetim.SURE))
if puan is None:
log(f"{tag} adim denetimi: Jev'e sorulamadi, cevap oldugu gibi geciyor")
else:
gecmedi = jev_denetim.karar(puan, ayar)
log(f"{tag} adim denetimi: ret={puan['ret']:.2f} sart={puan['sart']:.2f} teknik={puan['teknik']:.2f} "
f"soru={puan['soru']:.2f} -> {'GECMEDI' if gecmedi else 'gecti'} ({time.time() - t0:.1f} sn, {len(metin)} karakter)")
if gecmedi:
try:
yeni = yedek()
except Exception as e:
yeni = None
log(f"{tag} adim denetimi: yedek model acilamadi ({type(e).__name__}: {str(e)[:120]}); ilk cevap veriliyor")
if yeni is not None:
resp2, rewriter2, tag2 = yeni
log(f"{tag} adim denetimi: adim yedek modele verildi -> {tag2}")
return self._stream(resp2, resp2.status, tag2, rewriter2, izle, basliksiz=True)
resp, rewriter, tag = yeni
log(f"{tag} katman denetimi: adim bu katmana verildi")
if not kalan:
return self._stream(resp, resp.status, tag, rewriter, izle, basliksiz=True)
for chunk in parcalar:
if izle is not None:
izle.feed(chunk)
@@ -1012,7 +1017,7 @@ class H(http.server.BaseHTTPRequestHandler):
"ide_model": int((sayi.split() or ["0"])[0]),
"ozet": bool((CFG.get("ozet_kopru") or {}).get("enabled", False)),
"is_hatti": bool(HAT_KOMUT[0]),
"adim_denetimi": bool(jev_denetim.ayar_oku(CFG.get("jev_denetim"))[0] and jev_denetim.anahtar())})
"adim_denetimi": bool(jev_denetim.anahtar())})
if self.command == "POST" and path.rstrip("/").endswith("/stop"):
self._send_json(200, {"ok": True})
log("AITURK IDE istegiyle kapatiliyor")
@@ -1563,25 +1568,19 @@ class H(http.server.BaseHTTPRequestHandler):
open(os.path.join(LOGDIR, f"{n:04d}_req.json"), "wb").write(data)
hdrs = {"Authorization": f"Bearer {route['key']}", "Content-Type": "application/json", "Accept": "text/event-stream", "User-Agent": UA}
last = None
# Adim denetimi (jev_denetim.py): Jev'in gecirmedigi adimi yedek model yapar. Yedek ayni gecitteyse ve
# secili model zaten yedek degilse acilir; ozet isteginde ve Jev anahtari yokken kapalidir.
jev_yedek = None
jev_acik, jev_hedef, jev_ayar = jev_denetim.ayar_oku(CFG.get("jev_denetim"))
jev_esleme = MODEL_MAP.get(jev_hedef)
if (jev_acik and not ozet_tetik and slug != jev_hedef and jev_esleme and jev_esleme[0] == route_name
and rewriter is not None and jev_denetim.anahtar()):
jev_istek = jev_denetim.son_istek(req)
# Katman denetimi (jev_denetim.py): Katman-1..3 cevabini Jev gecirmezse adimi siradaki katman yapar.
# Katman-4 ve katman olmayan modeller sorulmaz.
jev_sira = [] if ozet_tetik or rewriter is None or not jev_denetim.anahtar() else jev_denetim.sonrakiler(target)
jev_istek = jev_denetim.son_istek(req) if jev_sira else ""
def jev_yedek():
yedek_req = json.loads(data)
yedek_req["model"] = jev_esleme[1]
yanit = urllib.request.urlopen(urllib.request.Request(
route["url"], data=json.dumps(yedek_req, ensure_ascii=False).encode("utf-8"), headers=hdrs, method="POST"),
timeout=UPSTREAM_IDLE_TIMEOUT)
return (yanit, SseRewriter(custom, hedef=jev_esleme[1], tasma=self._tasma_ogren, aracsiz=self._aracsiz_ogren),
f"[{n} {route_name.upper()} {slug}=>{jev_esleme[1]}]")
if not jev_istek:
jev_yedek = None
def jev_ac(ad):
katman_req = json.loads(data)
katman_req["model"] = ad
yanit = urllib.request.urlopen(urllib.request.Request(
route["url"], data=json.dumps(katman_req, ensure_ascii=False).encode("utf-8"), headers=hdrs, method="POST"),
timeout=UPSTREAM_IDLE_TIMEOUT)
return (yanit, SseRewriter(custom, hedef=ad, tasma=self._tasma_ogren, aracsiz=self._aracsiz_ogren),
f"[{n} {route_name.upper()} {slug}=>{ad}]")
# A 9Router combo (Fusion-*, no provider prefix) runs a whole panel upstream. Once it may
# have started (timeout, 504, cut stream) resending it runs and bills it twice (28 Sep 2026);
# only failures before the work starts (no connection, 500/502/503/529) are retried.
@@ -1634,8 +1633,8 @@ class H(http.server.BaseHTTPRequestHandler):
sonuc = self._stream(resp, resp.status, tag, akis)
log(f"{tag} ozet kopru: {akis.sonuc_notu()}")
return sonuc
if jev_yedek is not None and resp.status == 200:
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_ayar, jev_yedek)
if jev_sira and jev_istek and resp.status == 200:
return self._denetimli_akis(resp, tag, rewriter, izle, jev_istek, jev_sira, jev_ac)
return self._stream(resp, resp.status, tag, rewriter, izle)
self._send_json(503, {"error": {"message": f"bridge: hedef ulasilamadi {last}"}})
@@ -1,7 +1,6 @@
"""Step check (11 Oct 2026): Jev passes or blocks each step of an added model; a blocked step is redone by the
fallback model, the next step goes back to the selected model."""
"""Layer check (11 Oct 2026): Jev passes or blocks each step of Katman-1..3; a blocked step is redone by the next
layer. Katman-4 is never asked. No exceptions."""
import ast
import http.client
import io
import json
import os
@@ -27,18 +26,15 @@ def user(text):
return {"type": "message", "role": "user", "content": [{"type": "input_text", "text": text}]}
def sse(*deltas, done=True):
def sse(*deltas):
out = b""
for d in deltas:
out += b"event: response.output_text.delta\ndata: " + json.dumps(
{"type": "response.output_text.delta", "delta": d}).encode() + b"\n\n"
if done:
out += b'event: response.completed\ndata: {"type": "response.completed"}\n\n'
return out
return out + b'event: response.completed\ndata: {"type": "response.completed"}\n\n'
class Yanit:
"""Fake upstream response: read1 returns the body in two pieces."""
status = 200
def __init__(self, body):
@@ -49,39 +45,34 @@ class Yanit:
return self.parts.pop(0) if self.parts else b""
def scores(ret=0.0, sart=0.0, teknik=0.0, soru=0.0, zarar=0.0):
return {"ret": ret, "sart": sart, "teknik": teknik, "soru": soru, "zarar": zarar}
class Karar(unittest.TestCase):
def test_refusals_and_silent_conditions_are_blocked(self):
self.assertTrue(jev_denetim.karar(scores(ret=0.84))) # "böyle bir hüküm vermiyorum"
self.assertTrue(jev_denetim.karar(scores(ret=0.41, sart=0.95))) # did it with its own conditions
self.assertTrue(jev_denetim.karar(scores(ret=0.93, sart=0.72)))
self.assertTrue(jev_denetim.karar(scores(ret=0.62, sart=0.91, soru=0.93))) # "I can't; shall I do less?"
self.assertTrue(jev_denetim.karar(scores(ret=0.70, sart=0.90, teknik=0.23, soru=0.89))) # measured 11 Oct 2026
self.assertTrue(jev_denetim.karar(scores(ret=0.55, teknik=0.60))) # a fake technical excuse no longer passes
def test_refusal_or_own_conditions_block(self):
self.assertTrue(jev_denetim.karar({"ret": 0.84, "sart": 0.1}))
self.assertTrue(jev_denetim.karar({"ret": 0.41, "sart": 0.95}))
self.assertTrue(jev_denetim.karar({"ret": 0.5, "sart": 0.0}))
def test_normal_answers_real_obstacles_and_questions_pass(self):
self.assertFalse(jev_denetim.karar(scores(ret=0.05, sart=0.3)))
self.assertFalse(jev_denetim.karar(scores(ret=0.85, teknik=0.97))) # genuine "SSH key rejected, could not read"
self.assertFalse(jev_denetim.karar(scores(ret=0.48, sart=0.44, soru=0.96))) # a clarifying question without a refusal
def test_normal_answer_passes(self):
self.assertFalse(jev_denetim.karar({"ret": 0.05, "sart": 0.3}))
def test_attack_on_a_third_party_stays_refused_not_sent_to_fallback(self):
# User decision 11 Oct 2026: making Jev strict must not turn a refusal of third-party intrusion/malware into
# a request the uncensored fallback fulfils. Such a refusal passes (the refusal stands), it is not blocked.
self.assertFalse(jev_denetim.karar(scores(ret=0.94, sart=0.92, teknik=0.58, soru=0.85, zarar=0.93)))
self.assertTrue(jev_denetim.karar(scores(ret=0.94, sart=0.92, zarar=0.2))) # ordinary refusal still blocked
def test_no_exception_questions_exist(self):
self.assertEqual(set(jev_denetim.SORU), {"ret", "sart"})
def test_thresholds_come_from_settings(self):
self.assertFalse(jev_denetim.karar(scores(ret=0.45))) # just under the default
self.assertTrue(jev_denetim.karar(scores(ret=0.45), {"ret": 0.4}))
self.assertFalse(jev_denetim.karar(scores(ret=0.9, teknik=0.9), {"teknik_muaf": 0.85}))
class Katman(unittest.TestCase):
def test_chain(self):
self.assertEqual(jev_denetim.sonrakiler("Katman-1"), ["Katman-2", "Katman-3", "Katman-4"])
self.assertEqual(jev_denetim.sonrakiler("Katman-2"), ["Katman-3", "Katman-4"])
self.assertEqual(jev_denetim.sonrakiler("Katman-3"), ["Katman-4"])
def test_last_layer_and_other_models_are_not_asked(self):
self.assertEqual(jev_denetim.sonrakiler("Katman-4"), [])
self.assertEqual(jev_denetim.sonrakiler("Uncensored-Uygulama"), [])
self.assertEqual(jev_denetim.sonrakiler(None), [])
class Istek(unittest.TestCase):
def test_last_user_request_is_taken_and_wrappers_are_skipped(self):
voice = user("<realtime_delegation>\n <input>siteyi yap</input>\n <transcript_delta>x</transcript_delta>\n</realtime_delegation>")
voice = user("<realtime_delegation>\n <input>siteyi yap</input>\n</realtime_delegation>")
self.assertEqual(jev_denetim.son_istek({"input": [user("eski"), voice]}), "siteyi yap")
hook = user("<hook_context>pano</hook_context>")
call = {"type": "function_call", "call_id": "c", "name": "shell", "arguments": "{}"}
@@ -99,14 +90,12 @@ class Sor(unittest.TestCase):
def gonder(govde, key, sure):
seen.update(govde=govde, key=key)
return {"answers": {k: {"type": "noul", "noul": 0.25} for k in jev_denetim.SORU}}
puan = jev_denetim.sor("istek", "c" * 9000, "anahtar", gonder=gonder)
self.assertEqual(puan, scores(0.25, 0.25, 0.25, 0.25, 0.25))
self.assertEqual(jev_denetim.sor("istek", "c" * 9000, "anahtar", gonder=gonder), {"ret": 0.25, "sart": 0.25})
self.assertEqual(seen["key"], "anahtar")
self.assertEqual(seen["govde"]["state"]["user_request"], "istek")
self.assertLess(len(seen["govde"]["state"]["assistant_reply"]), 6100) # long answers are cut
self.assertEqual(set(seen["govde"]["questions"]), {"ret", "sart", "teknik", "soru", "zarar"})
self.assertLess(len(seen["govde"]["state"]["assistant_reply"]), 6100)
def test_failures_pass_the_answer_and_open_the_breaker(self):
def test_failures_return_none_and_open_the_breaker(self):
calls = []
def bozuk(govde, key, sure):
@@ -114,10 +103,8 @@ class Sor(unittest.TestCase):
raise OSError("ulasilamadi")
for _ in range(jev_denetim.DEVRE_HATA):
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1000.0))
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1001.0)) # breaker open: not called
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1001.0))
self.assertEqual(len(calls), jev_denetim.DEVRE_HATA)
self.assertIsNone(jev_denetim.sor("i", "c", "k", gonder=bozuk, simdi=1000.0 + jev_denetim.DEVRE_SN + 1))
self.assertEqual(len(calls), jev_denetim.DEVRE_HATA + 1)
def test_key_is_read_from_env_or_file(self):
self.assertEqual(jev_denetim.anahtar({"TYPESAFE_API_KEY": " a "}), "a")
@@ -127,25 +114,19 @@ class Sor(unittest.TestCase):
self.assertEqual(jev_denetim.anahtar({}, [yol]), "b")
self.assertEqual(jev_denetim.anahtar({}, [os.path.join(d, "yok.env")]), "")
def test_settings(self):
self.assertEqual(jev_denetim.ayar_oku(None)[:2], (True, "ide/Uncensored-Uygulama"))
self.assertEqual(jev_denetim.ayar_oku({"enabled": False, "hedef": "ide/x"})[:2], (False, "ide/x"))
class Akis(unittest.TestCase):
"""_denetimli_akis through a fake handler: what reaches the client."""
def setUp(self):
self.logs = []
self.asked = []
self.puan = scores()
self.logs, self.asked, self.opened = [], [], []
self.puanlar = [] # one verdict per asked answer; empty -> pass
sahte = Mock()
sahte.SURE = 6.0
sahte.anahtar = lambda: "k"
sahte.sor = lambda istek, metin, key, sure: (self.asked.append((istek, metin)), self.puan)[1]
sahte.sor = self.sor
sahte.karar = jev_denetim.karar
env = {"jev_denetim": sahte, "yarim": yarim, "time": time, "http": __import__("http"), "log": self.logs.append,
"RESP_HOP": set(), "json": json}
env = {"jev_denetim": sahte, "yarim": yarim, "time": time, "http": __import__("http.client"),
"log": self.logs.append, "RESP_HOP": set(), "json": json}
adlar = ("_akis_basligi", "_denetimli_akis", "_stream")
exec(compile(ast.Module(body=[method(a) for a in adlar], type_ignores=[]), "kopru.py", "exec"), env)
self.h = type("H", (), {a: env[a] for a in adlar})()
@@ -153,9 +134,19 @@ class Akis(unittest.TestCase):
self.h.send_response = Mock()
self.h.send_header = Mock()
self.h.end_headers = Mock()
self.cevap = {"Katman-2": sse("iki"), "Katman-3": sse("uc"), "Katman-4": sse("dort")}
def sor(self, istek, metin, key):
self.asked.append(metin)
return self.puanlar.pop(0) if self.puanlar else {"ret": 0.0, "sart": 0.0}
def ac(self, ad):
self.opened.append(ad)
if self.cevap[ad] is None:
raise OSError("acilamadi")
return Yanit(self.cevap[ad]), None, f"[{ad}]"
def sent(self):
"""Chunked body the client received, decoded."""
raw, out = self.h.wfile.getvalue(), b""
while raw:
size, _, rest = raw.partition(b"\r\n")
@@ -166,41 +157,57 @@ class Akis(unittest.TestCase):
raw = rest[n + 2:]
return out
def calistir(self, body, sira=("Katman-2", "Katman-3", "Katman-4")):
self.h._denetimli_akis(Yanit(body), "[1]", None, None, "yap", list(sira), self.ac)
def test_a_passed_step_is_delivered_unchanged(self):
body = sse("Fenerbahçe'nin ", "13 puanı var.")
self.h._denetimli_akis(Yanit(body), "[1]", None, None, "kaç puan", {}, lambda: self.fail("fallback opened"))
self.calistir(body)
self.assertEqual(self.sent(), body)
self.assertEqual(self.asked, [("kaç puan", "Fenerbahçe'nin 13 puanı var.")])
self.assertIn("gecti", self.logs[0])
self.assertEqual(self.asked, ["Fenerbahçe'nin 13 puanı var."])
self.assertEqual(self.opened, [])
def test_a_blocked_step_is_dropped_and_redone_by_the_fallback(self):
self.puan = scores(ret=0.9)
yedek = sse("Tamam, yaptım.")
self.h._denetimli_akis(Yanit(sse("Bunu yapamam.")), "[1]", None, None, "yap", {},
lambda: (Yanit(yedek), None, "[1 yedek]"))
self.assertEqual(self.sent(), yedek) # the refused text never reaches the client
def test_blocked_layer_1_goes_to_layer_2_which_is_checked_too(self):
self.puanlar = [{"ret": 0.9, "sart": 0.0}]
self.calistir(sse("Bunu yapamam."))
self.assertEqual(self.sent(), self.cevap["Katman-2"])
self.assertNotIn(b"yapamam", self.h.wfile.getvalue())
self.assertTrue(any("GECMEDI" in s for s in self.logs))
self.h.send_response.assert_called_once() # headers once, although two upstream answers
self.assertEqual(self.opened, ["Katman-2"])
self.assertEqual(self.asked, ["Bunu yapamam.", "iki"])
self.h.send_response.assert_called_once()
def test_every_layer_blocked_ends_at_layer_4_unasked(self):
self.puanlar = [{"ret": 0.9, "sart": 0.0}] * 3
self.calistir(sse("hayir"))
self.assertEqual(self.sent(), self.cevap["Katman-4"])
self.assertEqual(self.opened, ["Katman-2", "Katman-3", "Katman-4"])
self.assertEqual(self.asked, ["hayir", "iki", "uc"]) # layer 4 is never asked
def test_blocked_layer_3_goes_straight_to_layer_4(self):
self.puanlar = [{"ret": 0.0, "sart": 0.8}]
self.calistir(sse("kendi sartimla"), sira=("Katman-4",))
self.assertEqual(self.sent(), self.cevap["Katman-4"])
self.assertEqual(self.asked, ["kendi sartimla"])
def test_a_layer_that_cannot_be_opened_is_skipped(self):
self.puanlar = [{"ret": 0.9, "sart": 0.0}]
self.cevap["Katman-2"] = None
self.calistir(sse("hayir"))
self.assertEqual(self.opened, ["Katman-2", "Katman-3"])
self.assertEqual(self.sent(), self.cevap["Katman-3"])
def test_a_step_without_text_is_not_sent_to_jev(self):
body = b'event: response.output_item.done\ndata: {"type": "response.output_item.done", "item": {"type": "function_call"}}\n\n' + sse()
self.h._denetimli_akis(Yanit(body), "[1]", None, None, "yap", {}, lambda: self.fail("fallback opened"))
self.calistir(body)
self.assertEqual(self.sent(), body)
self.assertEqual(self.asked, [])
def test_unreachable_jev_or_fallback_keeps_the_first_answer(self):
self.puan = None
def test_unreachable_jev_keeps_the_answer(self):
self.puanlar = [None]
body = sse("Bunu yapamam.")
self.h._denetimli_akis(Yanit(body), "[1]", None, None, "yap", {}, lambda: self.fail("fallback opened"))
self.assertEqual(self.sent(), body)
self.h.wfile = io.BytesIO()
self.puan = scores(ret=0.9)
def bozuk():
raise OSError("yedek acilamadi")
self.h._denetimli_akis(Yanit(body), "[1]", None, None, "yap", {}, bozuk)
self.calistir(body)
self.assertEqual(self.sent(), body)
self.assertEqual(self.opened, [])
if __name__ == "__main__":